点击上方“码农沉思录”,选择“设为星标”优质文章,及时送达不断的学习新东西,不断的思考更多,不断的对原有自己造成更大的冲击。如果要给我迁移 FaaS 期间的感受下一个总结,那么一定是:“在撕裂中成长”。微服务架构下,稳定性和高可用性一个永恒的话题,在实际的治理过程中,我们有可能会遇到以下场景:
目前已经覆盖了市面上大部分微服务场景,后续我们将会持续支持开源最新的 Dubbo/Spring Cloud 版本。我们提供了 Dubbo 和 Spring Cloud 两种场景的离群摘除功能,本文将先介绍一下 Dubbo Microservice Outlier Ejection 的实践与效果。
我们将以 cartservice 服务即 Dubbo 服务端为例子,展示离群实例摘除功能。
点击下一步后,上传刚才打包的jar包,即 cartservice-provider/target/ cartservice-provider-1.0.0-SNAPSHOT.jar 然后下一步,记住登陆密码,直到创建应用成功。
然后启动应用,到目前为止,我们启动了一个 cartservice-provider。点击按此实例规格扩容,该服务我们部署在两个实例上。
我们在这个 provider 的com.alibabacloud.hipstershop.provider.CartServiceImpl 类中可以看到,这个 provider 是提供了viewCart 和 addItemToCart 的两个关于购物车的服务,我们在 viewCart 中加入一些模拟运行时异常的逻辑。
进入浏览器访问 :http://47.99.150.33:8080/
点击 View Cart 访问至 :http://47.99.150.33:8080/cart
可以看到,此时服务都是正常的。我们去 ACM 配置中心 配置 exception.ip 为 172.16.205.180(即cartservice的其中某个实例的IP)。
然后继续访问 :http://47.99.150.33:8080/cart ,发现 50 % 的概率错误页面。
此时,我们写一个脚本,定时大量访问 :http://47.99.150.33:8080/cart 模拟请求。
其实也可以理解到,下游的服务质量随着上游的某台机子的异常而急剧下降,甚至可能导致下游服务被上游某些机子的(系统、业务)异常给拖垮。开启离群摘除策略下面我将演示离群摘除的策略的开启及其效果的展示。
然后按照提示一步步创建离群摘除的策略。
如上图可以选择命名空间、填写策略名称、选择该策略支持的框架类型(Dubbo/Spring Cloud)。
按照目前的调用方式,我们只需要配置 frontend 应用,保护下游应用 consumer。
这些参数都提供了默认值,需要根据自己应用的具体情况调整最合适的值,由于需要保护的 RuntimeException 属于业务异常于是选上 网络异常+业务异常。(需要注意的是即使摘除实例比例上限配得特别低,向下取整数小于1,当集群中实例数目大于1,且某一实例异常,我们也会摘除一实例)。
可以看到策略的信息,创建完成。
看到了我们创建的离群摘除策略,且是针对 Dubbo 框架,并且针对的是 网络异常+业务异常 的异常类型。验证离群摘除效果这时,我们看到,再感知到异常后,离群摘除功能生效,请求调用一阵子后,均返回正确结果。
不断刷新浏览器访问:http://47.99.150.33:8080/cart 也均正常。
客户端感知到某台服务端机子异常后,主动摘除。仅仅调用业务正常的 Provider 实例,同时我们也可以通 ARMS(EDAS监控系统) 监控看到服务质量的上升,以及流量从异常 Provider 中摘除。Dubbo 框架可以从 /home/admin/.opt/ArmsAgent/logs 目录下的日志中,搜索日志中的 “OutlierRouter” 关键字可以看到一系列离群实例摘除的事件日志。
然后增加删除应用或者调整参数,确定后均立即生效
控制台的操作,对应用中的配置都是实时生效的,若删除策略后,默认关闭相关策略。若我们打开 ARMS 监控观察具体的调用情况。
我们可以从下图即 ARMS( EDAS 监控系统)应用监控页面直观地看到结果。
从以下拓扑图中我们看到,流量不断地访问到 cartservice 服务上。
可以看到,在开启了离群摘除的那个点只后,错误率从 50% 明显下降。
其中两个小的起伏毛刺是因为,离群摘除一段时间后会重新尝试访问被摘除的 endPoint ,若依旧错误率高于阈值,继续隔离,且间隔时间更长。
Dubbo Agent 方案技术架构对于用户来说,无需改动一行代码,一行配置,即可享受到稳定性增强的能力。
Dubbo-Router 控制逻辑每次请求过来仅仅 check 一下并标记状态,后台有专门两个线程将标记的流量进行判断是否进入隔离列表或从中剔除,修改拉黑信息等耗时操作,最大程度上保证请求的实时性。Spring Cloud 基于 扩展 LoadBalace 实现,原理相似。



点个在看吧,证明你还爱我
- 某个应用灰度发布,先上了几台机器,由于代码逻辑写的有问题,造成线程池满,出现运行异常。
- 服务端集群中,某几台机器由于磁盘满,或者是宿主机资源争抢导致 load 过高,客户端出现调用超时。
- 服务端集群中,某几台机器由于线程池满,造成 Full Garbage Collection。
Microservice Outlier Ejection (微服务离群实例摘除)
- 什么是离群实例摘除
- 离群实例摘除的功能
- 与熔断的区别
- 离群实例摘除支持的版本
目前已经覆盖了市面上大部分微服务场景,后续我们将会持续支持开源最新的 Dubbo/Spring Cloud 版本。我们提供了 Dubbo 和 Spring Cloud 两种场景的离群摘除功能,本文将先介绍一下 Dubbo Microservice Outlier Ejection 的实践与效果。示例
下面将通过在 EDAS 上通过演示 Dubbo 离群摘除功能及效果。企业级分布式应用服务 EDAS(Enterprise Distributed Application Service)是一个应用托管和微服务管理的 PaaS 平台,提供应用开发、部署、监控、运维等全栈式解决方案,同时支持 Dubbo、Spring Cloud 等微服务运行环境。https://www.aliyun.com/product/edas
准备
接下来以微服务 Demo 为例子示范离群摘除功能,读者可以从 github 中下载验证https://github.com/aliyun/alibabacloud-microservice-demo/tree/master/src微服务 Demo 是一个简单的电商项目,下图为项目结构,cartservice 为 Dubbo 框架的购物车服务 provider,productservice 为 Spring Cloud 提供的商品详情服务 provider,frontend 为 web controller 即前端展示页面,可以理解为 consumer 。
我们将以 cartservice 服务即 Dubbo 服务端为例子,展示离群实例摘除功能。EDAS 上部署微服务 Demo
首先 cd cartservice 切换到 cartservice 目录下,再通过 mvn clean install 打包,通过 cd cartservice-provider/target 切换到 target 目录下,我们可以看到新生成的 cartservice-provider-1.0.0-SNAPSHOT.jar 包,然后在 EDAS上 创建一个 cartservice 应用。
点击下一步后,上传刚才打包的jar包,即 cartservice-provider/target/ cartservice-provider-1.0.0-SNAPSHOT.jar 然后下一步,记住登陆密码,直到创建应用成功。
然后启动应用,到目前为止,我们启动了一个 cartservice-provider。点击按此实例规格扩容,该服务我们部署在两个实例上。
我们在这个 provider 的com.alibabacloud.hipstershop.provider.CartServiceImpl 类中可以看到,这个 provider 是提供了viewCart 和 addItemToCart 的两个关于购物车的服务,我们在 viewCart 中加入一些模拟运行时异常的逻辑。 @Value("${exception.ip}") private String exceptionIp; @Override public List viewCart(String userID) { if (exceptionIp != null && exceptionIp.equals(getLocalIp())) { throw new RuntimeException("运行时异常"); } return cartStore.getOrDefault(userID, Collections.emptyList()); }其中 exceptionIp 为 ACM 配置中心的 exception.ip 的配置项,若该项配置为本机 Ip 时,该服务 throw RuntimeException ,用于模拟业务异常的场景。- 为什么将 cartservice 扩容到两个实例,想必大家也猜到了,运行时通过配置ACM配置中心指定其中一个实例的IP,模拟出一个实例异常的场景。

模拟业务异常
进入到 frontend 应用中,我们看到其实例的公网 Ip 为 47.99.150.33。
进入浏览器访问 :http://47.99.150.33:8080/
点击 View Cart 访问至 :http://47.99.150.33:8080/cart
可以看到,此时服务都是正常的。我们去 ACM 配置中心 配置 exception.ip 为 172.16.205.180(即cartservice的其中某个实例的IP)。
然后继续访问 :http://47.99.150.33:8080/cart ,发现 50 % 的概率错误页面。
此时,我们写一个脚本,定时大量访问 :http://47.99.150.33:8080/cart 模拟请求。while :do result=`curl $1 -s` if [[ "$result" == *"500"* ]]; then echo `date +%F-%T` $result else echo `date +%F-%T` "success" fi sleep 0.1done然后 sh curlservice.sh http://47.99.150.33:8080/cart。我们看到不断重复的每秒钟 10 次的 50% 的调用成功率。
其实也可以理解到,下游的服务质量随着上游的某台机子的异常而急剧下降,甚至可能导致下游服务被上游某些机子的(系统、业务)异常给拖垮。开启离群摘除策略下面我将演示离群摘除的策略的开启及其效果的展示。创建
我们进入到 EDAS 左侧列表的 [微服务管理] 下的 [离群实例摘除] 界面中,并选择创建离群实例摘除策略。
然后按照提示一步步创建离群摘除的策略。基本信息
如上图可以选择命名空间、填写策略名称、选择该策略支持的框架类型(Dubbo/Spring Cloud)。选择生效应用
按照目前的调用方式,我们只需要配置 frontend 应用,保护下游应用 consumer。配置策略
这些参数都提供了默认值,需要根据自己应用的具体情况调整最合适的值,由于需要保护的 RuntimeException 属于业务异常于是选上 网络异常+业务异常。(需要注意的是即使摘除实例比例上限配得特别低,向下取整数小于1,当集群中实例数目大于1,且某一实例异常,我们也会摘除一实例)。创建完成
可以看到策略的信息,创建完成。策略
看到了我们创建的离群摘除策略,且是针对 Dubbo 框架,并且针对的是 网络异常+业务异常 的异常类型。验证离群摘除效果这时,我们看到,再感知到异常后,离群摘除功能生效,请求调用一阵子后,均返回正确结果。
不断刷新浏览器访问:http://47.99.150.33:8080/cart 也均正常。
客户端感知到某台服务端机子异常后,主动摘除。仅仅调用业务正常的 Provider 实例,同时我们也可以通 ARMS(EDAS监控系统) 监控看到服务质量的上升,以及流量从异常 Provider 中摘除。Dubbo 框架可以从 /home/admin/.opt/ArmsAgent/logs 目录下的日志中,搜索日志中的 “OutlierRouter” 关键字可以看到一系列离群实例摘除的事件日志。修改/关闭离群摘除策略
对于 EDAS 的应用我们支持通过控制台动态修改和删除离群摘除策略。- 对应策略规则的修改
然后增加删除应用或者调整参数,确定后均立即生效删除对应策略
控制台的操作,对应用中的配置都是实时生效的,若删除策略后,默认关闭相关策略。若我们打开 ARMS 监控观察具体的调用情况。ARMS监控
若我们开启监控,将会直观看到流量与请求错误等信息。开启离群摘除前
如下图方式开启,然后跳转至 ARMS( EDAS 监控系统)应用监控页面,我们需要把三个应用都开启高级监控。
我们可以从下图即 ARMS( EDAS 监控系统)应用监控页面直观地看到结果。
从以下拓扑图中我们看到,流量不断地访问到 cartservice 服务上。
开启离群摘除后
离群摘除效果通过简单的例子就看到了,当然可以通过 ARMS ( EDAS 监控系统)的监控可以明显观察到服务质量的提升。
可以看到,在开启了离群摘除的那个点只后,错误率从 50% 明显下降。
其中两个小的起伏毛刺是因为,离群摘除一段时间后会重新尝试访问被摘除的 endPoint ,若依旧错误率高于阈值,继续隔离,且间隔时间更长。离群实例摘除具体控制逻辑
前面我们看到了,离群实力摘除对应用稳定性提高带来的帮助,下面我们将具体分析离群实例摘除的控制逻辑,有助于您更好地理解其各种参数的意义,以及可以根据自己的应用情况,通过调整参数,配置出最合适自己的离群摘除策略。对于 Dubbo/SpringCloud 框架:- 默认 QPS 下限为 1
- 默认错误率下限 50%
- 默认摘除实例比例上限 20%
- 异常类型
- 关于恢复检测单位时间(默认 30000ms 即 30s )与未恢复累计次数上限(默认 40 )的解释
- 兜底
- 通用最佳实践
离群实例摘除技术细节
无侵入技术
无侵入方案即通过 agent 技术来实现,一句话来说就是通过字节码增强技术,运行时插入我们的代码,改变应用的原有逻辑,可以理解为运行时 AOP ,通过在 Dubbo 的链路中插入 Filter/Router ,在 Spring Cloud 中增强 LoadBalance 逻辑,来实现我们期望的路由控制逻辑。同时因为是 agent 增强的,再加上 Dubbo 各个版本的链路整体基本没大的变化,Spring Cloud 模型的统一性,因此我们可以花少的代价将能力基本覆盖到所有版本。
Dubbo Agent 方案技术架构对于用户来说,无需改动一行代码,一行配置,即可享受到稳定性增强的能力。离群实例摘除技术
Outlier Detection 离群检测
均是基于时间窗口的数据统计。两种实现如下:1、Dubbo 2.7 版本通过向链路中嵌入一个 MetricsFilter ,对于链路的每个 request/response 做打点处理,统计rt、调用成功与否、异常类型,并且已 endpoint(ip+port) 为 key 存储。2、在 Agent 底座中统计经过的 http 请求,通过 url、rt、状态码、异常类型等数据结果,统计最近时间窗口的数据(目前写死 10 秒,暂时不透出)。实时统计前 N 秒的调用信息,作为离群实例摘除动作的依据。Outlier Ejection 离群摘除
Dubbo 基于 Dubbo Router 实现,对于调用的上游服务对应的所有 invokers 中,拉黑掉“不健康”的节点,同时记录拉黑的信息。
Dubbo-Router 控制逻辑每次请求过来仅仅 check 一下并标记状态,后台有专门两个线程将标记的流量进行判断是否进入隔离列表或从中剔除,修改拉黑信息等耗时操作,最大程度上保证请求的实时性。Spring Cloud 基于 扩展 LoadBalace 实现,原理相似。



点个在看吧,证明你还爱我
本文介绍了微服务治理中的离群实例摘除策略,通过EDAS平台部署微服务示例,模拟业务异常,探讨了离群检测与摘除的技术细节,包括无侵入技术,并提供了监控与最佳实践。

被折叠的 条评论
为什么被折叠?



