配置推空保护
注册中心作为承担服务注册发现的核心组件,是微服务架构中必不可少的一环。本文介绍注册中心中的推空保护。
背景信息
客户端在请求注册中心订阅服务端地址列表时,在服务端注册异常的场景下,注册中心返回了空列表,此时客户端忽略该空返回的变更,从缓存中获取上一次正常的服务端地址进行服务访问。推空保护功能可以在注册中心在进行变更(变配、升降级)或遇到突发情况(例如,可用区断网断电)或其他不可预知情况下的列表订阅异常收到空的地址列表推送时,可以有效保护业务调用,增加业务可靠性。
本文演示的应用架构是由后端的微服务应用实例(Spring Cloud)构成。具体的后端调用链路有Spring Cloud Consumer调用Spring Cloud Provider,这些应用中的服务之间通过Nacos注册中心实现服务注册与发现。
该功能Agent正在灰度中,如果需要使用欢迎加入微服务引擎钉钉交流群:34754806,联系技术支持单独升级后再进行试用。
使用限制
限制项 | 限制值 | 说明 |
Spring Cloud版本 | Spring Cloud Edgware及以上版本。 | - |
Dubbo版本 | 2.5.3~2.7.8 | Dubbo 3.0+版本支持当前处于灰度中。 |
注册中心类型 |
| - |
准备工作
已创建Kubernetes集群,请参见创建Kubernetes托管版集群。
已开通MSE微服务治理专业版,请参见开通MSE微服务治理。
安装MSE微服务治理组件
在容器服务控制台左侧导航栏中,选择 ,在搜索框中输入ack-mse-pilot,单击该组件。
在详情页面单击一键部署,在创建页面选择开通该组件的集群,单击下一步,然后单击确定。
为应用开启微服务治理
登录MSE治理中心控制台。在左侧导航栏选择 ,然后单击目标集群操作列下方的管理。
在集群详情页面,单击目标命名空间操作列下方的开启微服务治理。然后单击确定开启微服务治理。
部署Demo应用程序
在容器服务控制台左侧导航栏,单击集群。在集群列表页面,单击目标集群名称。
在集群管理页左侧导航栏,选择 。
在无状态页面的顶部,选择命名空间,然后单击使用YAML创建资源。对模板进行相关配置,完成配置后单击创建。本文示例中部署sc-consumer、sc-consumer-empty和sc-provider,使用的是开源的Nacos。
# 开启推空保护的 sc-consumer apiVersion: apps/v1 kind: Deployment metadata: name: sc-consumer spec: replicas: 1 selector: matchLabels: app: sc-consumer template: metadata: annotations: msePilotCreateAppName: sc-consumer labels: app: sc-consumer spec: containers: - env: - name: JAVA_HOME value: /usr/lib/jvm/java-1.8-openjdk/jre - name: spring.cloud.nacos.discovery.server-addr value: nacos-server:8848 image: registry.cn-hangzhou.aliyuncs.com/mse-demo-hz/demo:sc-consumer-0.1 imagePullPolicy: Always name: sc-consumer ports: - containerPort: 18091 livenessProbe: tcpSocket: port: 18091 initialDelaySeconds: 10 periodSeconds: 30 --- apiVersion: v1 kind: Service metadata: annotations: service.beta.kubernetes.io/alibaba-cloud-loadbalancer-spec: slb.s1.small service.beta.kubernetes.io/alicloud-loadbalancer-address-type: internet name: sc-consumer-slb spec: ports: - port: 80 protocol: TCP targetPort: 18091 selector: app: sc-consumer type: LoadBalancer status: loadBalancer: {} # 无推空保护的sc-consumer-empty --- apiVersion: apps/v1 kind: Deployment metadata: name: sc-consumer-empty spec: replicas: 1 selector: matchLabels: app: sc-consumer-empty template: metadata: annotations: msePilotCreateAppName: sc-consumer-empty labels: app: sc-consumer-empty spec: containers: - env: - name: JAVA_HOME value: /usr/lib/jvm/java-1.8-openjdk/jre - name: spring.cloud.nacos.discovery.server-addr value: nacos-server:8848 image: registry.cn-hangzhou.aliyuncs.com/mse-demo-hz/demo:sc-consumer-0.1 imagePullPolicy: Always name: sc-consumer-empty ports: - containerPort: 18091 livenessProbe: tcpSocket: port: 18091 initialDelaySeconds: 10 periodSeconds: 30 --- apiVersion: v1 kind: Service metadata: annotations: service.beta.kubernetes.io/alibaba-cloud-loadbalancer-spec: slb.s1.small service.beta.kubernetes.io/alicloud-loadbalancer-address-type: internet name: sc-consumer-empty-slb spec: ports: - port: 80 protocol: TCP targetPort: 18091 selector: app: sc-consumer-empty type: LoadBalancer status: loadBalancer: {} # sc-provider --- apiVersion: apps/v1 kind: Deployment metadata: name: sc-provider spec: replicas: 1 selector: matchLabels: app: sc-provider strategy: template: metadata: annotations: msePilotCreateAppName: sc-provider labels: app: sc-provider spec: containers: - env: - name: JAVA_HOME value: /usr/lib/jvm/java-1.8-openjdk/jre - name: spring.cloud.nacos.discovery.server-addr value: nacos-server:8848 image: registry.cn-hangzhou.aliyuncs.com/mse-demo-hz/demo:sc-provider-0.3 imagePullPolicy: Always name: sc-provider ports: - containerPort: 18084 livenessProbe: tcpSocket: port: 18084 initialDelaySeconds: 10 periodSeconds: 30 # Nacos Server --- apiVersion: apps/v1 kind: Deployment metadata: name: nacos-server spec: replicas: 1 selector: matchLabels: app: nacos-server template: metadata: labels: app: nacos-server spec: containers: - env: - name: MODE value: standalone image: nacos/nacos-server:v2.2.0 imagePullPolicy: Always name: nacos-server dnsPolicy: ClusterFirst restartPolicy: Always # Nacos Server Service 配置 --- apiVersion: v1 kind: Service metadata: name: nacos-server spec: ports: - port: 8848 protocol: TCP targetPort: 8848 selector: app: nacos-server type: ClusterIP
开启推空保护功能
登录MSE治理中心控制台,并在顶部菜单栏选择地域。
在左侧导航栏,选择 ,然后单击目标应用的资源量卡片。
在目标应用详情页面的左侧导航栏,单击流量治理,然后选择推空保护页签。
打开推空保护开关按钮。
功能验证
编写测试脚本
vi curl.sh
。while : do result=`curl $1 -s` if [[ "$result" == *"500"* ]]; then echo `date +%F-%T` $result else echo `date +%F-%T` $result fi sleep 0.1 done
执行脚本,进行测试。
执行脚本
% sh curl.sh {sc-consumer-empty-slb}:18091/user/rest
,显示如下:2022-01-19-11:58:12 Hello from [18084]10.116.0.142! 2022-01-19-11:58:12 Hello from [18084]10.116.0.142! 2022-01-19-11:58:12 Hello from [18084]10.116.0.142! 2022-01-19-11:58:13 Hello from [18084]10.116.0.142! 2022-01-19-11:58:13 Hello from [18084]10.116.0.142! 2022-01-19-11:58:13 Hello from [18084]10.116.0.142!
保持脚本一直在调用,观察MSE控制台看到如下情况:
执行脚本
% sh curl.sh {sc-consumer-slb}:18091/user/rest
,显示如下:2022-01-19-11:58:13 Hello from [18084]10.116.0.142! 2022-01-19-11:58:13 Hello from [18084]10.116.0.142! 2022-01-19-11:58:13 Hello from [18084]10.116.0.142! 2022-01-19-11:58:14 Hello from [18084]10.116.0.142! 2022-01-19-11:58:14 Hello from [18084]10.116.0.142! 2022-01-19-11:58:14 Hello from [18084]10.116.0.142!
保持脚本一直在调用,观察MSE控制台看到如下情况:
将coredns组件缩容至数量0,模拟DNS网络解析异常场景。
发现实例与Nacos的连接断开且服务列表为空。
模拟DNS服务恢复,将其扩容回数量2。
结果验证
在以上保持持续的业务流量过程中,可以发现sc-consumer-empty服务出现大量且持续的报错。只有重启了Provider,sc-consumer-empty才恢复正常。
2022-01-19-12:02:37 {"timestamp":"2022-01-19T04:02:37.597+0000","status":500,"error":"Internal Server Error","message":"com.netflix.client.ClientException: Load balancer does not have available server for client: mse-service-provider","path":"/user/feign"}
2022-01-19-12:02:37 {"timestamp":"2022-01-19T04:02:37.799+0000","status":500,"error":"Internal Server Error","message":"com.netflix.client.ClientException: Load balancer does not have available server for client: mse-service-provider","path":"/user/feign"}
2022-01-19-12:02:37 {"timestamp":"2022-01-19T04:02:37.993+0000","status":500,"error":"Internal Server Error","message":"com.netflix.client.ClientException: Load balancer does not have available server for client: mse-service-provider","path":"/user/feign"}
相比sc-consumer-empty,sc-consumer应用全流程没有任何报错。
查看推空保护事件
登录MSE治理中心控制台,并在顶部菜单栏选择地域。
在左侧导航栏,选择 ,然后单击目标应用的资源量卡片。
在目标应用详情页面的左侧导航栏,单击流量治理,然后选择推空保护页签。
在页面的右上角,查看保护事件。