OpenSergo & CloudWeGo 共同保障微服务运行时流量稳定性
简介: 流控降级与容错是微服务流量治理中的重要的一环,同时 MSE 还提供更广范围、更多场景的微服务治理能力,包括全链路灰度、无损上下线、微服务数据库治理、日志治理等一系列的微服务治理能力。
作者:宿何
微服务运行时稳定性的问题
微服务的稳定性一直是开发者非常关注的话题。随着业务从单体架构向分布式架构演进以及部署方式的变化,服务之间的依赖关系变得越来越复杂,业务系统也面临着巨大的高可用挑战。大家可能都经历过以下的场景:
- 演唱会抢票瞬间洪峰流量导致系统超出最大负载,load 飙高,用户无法正常下单;
- 在线选课时同一时刻提交选课的请求过多,系统无法响应;
- 页面服务中某一块内容访问很慢,一直加载不出来,导致整个页面都卡住,无法正常操作
影响微服务可用性的因素有非常多,而这些不稳定的场景可能会导致严重后果。我们从微服务流量的视角来看,可以粗略分为两类常见的运行时场景:
- 服务自身流量超过承载能力导致不可用。比如激增流量、批量任务投递导致服务负载飙高,无法正常处理请求。
- 服务因依赖其他不可用服务,导致自身连环不可用。比如我们的服务可能依赖好几个第三方服务,假设某个支付服务出现异常,调用非常慢,而调用端又没有有效地进行预防与处理,则调用端的线程池会被占满,影响服务自身正常运转。在分布式系统中,调用关系是网状的、错综复杂的,某个服务出现故障可能会导致级联反应,导致整个链路不可用。
在遇到这些微服务运行时稳定性的问题时,我们应该如何解决呢?针对这些不稳定的场景,MSE 提供全方位的流量防护能力,基于开源流量治理组件 Sentinel 的稳定性防护能力,以流量为切入点,从流量控制、并发控制、熔断降级、热点防护、系统自适应保护等多个维度来帮助保障服务的稳定性,覆盖微服务框架、云原生网关、Service Mesh 等几大场景,支持 Java、Go、C++、Rust 等多种语言的异构微服务架构。
CloudWeGo 原生支持 Sentinel 及 OpenSergo
CloudWeGo 是一套由字节跳动开源的、可快速构建企业级云原生微服务架构的中间件集合。CloudWeGo 项目共同的特点是高性能、高扩展性、高可靠,专注于微服务通信与治理。其中 Kitex 是下一代高性能、强可扩展的 Golang RPC 框架,提供整套微服务的能力;Hertz 是高易用性、高性能、高扩展性的 Golang 微服务 HTTP 框架,旨在为开发人员简化构建微服务。
近期 CloudWeGo 社区与 Sentinel 社区合作共建,提供了 CloudWeGo Kitex 及 Hertz 对接 Sentinel Go 的适配模块,只需简单地引入适配模块并引入对应 Middleware,即可快速将 Kitex 及 Hertz 服务接入 Sentinel Go,享受全面的流量治理与防护能力。同时结合 Sentinel Go 与 OpenSergo 微服务治理标准的对接,CloudWeGo 也将支持 OpenSergo spec 中流控降级与容错的标准配置,未来可以通过统一的 CRD 方式进行流量治理管控。
适配模块文档可以参考:
- Kitex adapter:
https://pkg.go.dev/github.com/alibaba/sentinel-golang/pkg/adapters/kitex
- Hertz adapter:
https://pkg.go.dev/github.com/alibaba/sentinel-golang/pkg/adapters/hertz
同时,基于 Sentinel 的 Kitex 和 Hertz 适配模块,我们可以结合 MSE 服务治理 Go SDK 接入方式,来方便地将 Kitex 和 Hertz 服务接入到阿里云 MSE 微服务治理产品中,通过白屏化的观测与治理配置手段来保障微服务的运行时流量稳定性。
CloudWeGo + MSE 流量防护最佳实践
MSE 微服务治理提供全方位的流量治理、流量防护及微服务视角的数据库治理能力,其中对于 Go 微服务,开发者可以通过 Go SDK 方式接入 MSE 来享受流控降级与容错相关的治理、白屏化配置与观测能力,保障服务运行时的稳定性。MSE 流量治理支持 CloudWeGo, gRPC, Gin, dubbo-go, go-micro 等常用 Go 微服务框架的流控降级与容错能力。首先我们先来看一下流量防护的典型场景。
流量控制保障激增流量下服务的稳定性
流量是非常随机性的、不可预测的。前一秒可能还风平浪静,后一秒可能就出现流量洪峰了(例如双十一零点的场景)。然而我们系统的容量总是有限的,如果突然而来的流量超过了系统的承受能力,就可能会导致请求处理不过来,堆积的请求处理缓慢,CPU/Load 飙高,最后导致系统崩溃。因此,我们需要针对这种突发的流量来进行限制,在尽可能处理请求的同时来保障服务不被打垮,这就是流量控制。流量控制的场景是非常通用的,像脉冲流量类的场景都是适用的。
MSE Sentinel 基于毫秒级滑动窗口精确统计与令牌桶、 漏桶、WarmUp 等流量控制算法,提供包括秒级精准流控、集群总量流控、匀速排队等在内的多种维度的流量控制场景。通常在 Web 入口或 RPC 服务提供方(Service Provider)的场景下,我们需要保护服务提供方自身不被流量洪峰打垮。这时候通常根据服务提供方的服务能力进行流量控制,或针对特定的服务调用方进行限制。我们可以结合前期压测评估核心接口的承受能力,配置 QPS 模式的流控规则,当每秒的请求量超过设定的阈值时,会自动拒绝多余的请求。
熔断降级与隔离保障服务不被慢依赖调用拖垮
一个服务常常会调用别的模块,可能是另外的一个远程服务、数据库,或者第三方 API 等。例如,支付的时候,可能需要远程调用银联提供的 API;查询某个商品的价格,可能需要进行数据库查询。然而,这个被依赖服务的稳定性是不能保证的。如果依赖的服务出现了不稳定的情况,请求的响应时间变长,那么调用服务的方法的响应时间也会变长,线程会产生堆积,最终可能耗尽业务自身的线程池,服务本身也变得不可用。
现代微服务架构都是分布式的,由非常多的服务组成。不同服务之间相互调用,组成复杂的调用链路。以上的问题在链路调用中会产生放大的效果。复杂链路上的某一环不稳定,就可能会层层级联,最终导致整个链路都不可用。
MSE Sentinel 提供以下的能力避免慢调用等不稳定因素造成服务不可用:
- 并发控制(隔离规则):作为一种轻量级隔离的手段,控制某些调用的并发数(即正在进行的数目),防止过多的慢调用占满线程池造成整体不可用。并发控制规则可作为一种重要的保底手段,防止服务被大量慢调用拖垮。
- 不稳定调用熔断:对不稳定的弱依赖调用进行自动熔断降级,暂时切断不稳定调用,避免局部不稳定因素导致整体的雪崩。
- 提前降级:对于一些弱依赖的服务(非关键链路依赖),可以在活动前或资源紧张时进行动态降级,以优先保障重要服务的稳定性。被降级的服务将直接返回给定的 mock 值而不会触发实际调用。
熔断降级特性基于熔断器模式的思想,在服务出现不稳定因素(如响应时间变长,错误率上升)的时候暂时切断服务的调用,等待一段时间再进行渐进式恢复尝试。一方面防止给不稳定服务“雪上加霜”,另一方面保护服务的调用方不被拖垮。目前支持两种熔断策略:基于响应时间(慢调用比例)和基于错误(错误比例/错误数),可以有效地针对各种不稳定的场景进行防护。
注意熔断器模式一般适用于弱依赖调用,即熔断后不影响业务主流程,而并发控制对于弱依赖和强依赖调用均适用。开发者需要设计好降级后的 fallback 逻辑和返回值。另外需要注意的是,即使服务调用方引入了熔断降级机制,我们还是需要在 HTTP 或 RPC 客户端配置请求超时时间,来做一个兜底的防护。
CloudWeGo 接入 MSE 流量防护示例
接下来我们就以 CloudWeGo Kitex 服务为例,展示如何结合 MSE Sentinel 来保障 CloudWeGo 微服务的运行时稳定性。
首先,我们先在项目中引入 MSE Go SDK,并进行一些简单初始化配置;同时我们也引入 Kitex Sentinel 适配模块,以便将我们的 Kitex 服务接入到 MSE:
import (
sentinel "github.com/alibaba/sentinel-golang/api"
sentinelPlugin "github.com/alibaba/sentinel-golang/pkg/adapters/kitex"
api "github.com/cloudwego/kitex-examples/hello/kitex_gen/api/hello"
mse "github.com/aliyun/aliyun-mse-go-sdk"
) func main() {
// 初始化 MSE Sentinel;可以通过环境变量或 sentinel.yml 文件配置应用名
err := mse.InitMseDefault()
if err != nil {
log.Fatalf("Failed to init MSE: %+v", err)
} // 创建 Kitex server 时添加 Sentinel 适配模块中的 middleware
svr := api.NewServer(new(HelloImpl), server.WithMiddleware(sentinelPlugin.SentinelServerMiddleware())) err = svr.Run()
if err != nil {
log.Println(err.Error())
}
}
接下来我们启动服务 provider,即可在 MSE 控制台看到我们的 Kitex 服务。我们通过 consumer 触发流量访问,然后可以在 MSE 控制台的接口详情页面看到我们 Kitex 服务调用的详细监控信息。
接下来我们针对 Hello:Echo 这个接口方法配置一条单机 QPS 为 10 的流控规则:
配置完成后,规则会实时生效到服务中。稍等片刻我们就可以在接口详情页面看到 Hello:Echo 这个接口方法的单机处理量被限制到了 10 次每秒,同时 consumer 端也会接收到相应的流控 error。
结合 OpenSergo 实现标准化的流量治理
结合 OpenSergo 实现标准化的流量治理
业界微服务治理存在概念不统一、配置形式不统一、能力不统一、多框架统一管控较为复杂等问题。比如我们希望给某个接口配置熔断降级规则,在 Sentinel 中可能需要通过 Sentinel 动态规则的方式进行配置,在 Istio 中可能又是另一套配置方式,在其它组件上可能又是不同的配置。不同框架治理配置方式的不一致使得微服务统一治理管控的复杂度相当高。
基于以上背景,由阿里巴巴、bilibili、CloudWeGo 等企业与社区共同发起的 OpenSergo 项目应运而生。OpenSergo 旨在提供一套开放通用的、面向云原生服务、覆盖微服务及上下游关联组件的微服务治理标准,并根据标准提供一系列的 API 与 SDK 实现。OpenSergo 的最大特点就是以统一的一套配置/DSL/协议定义服务治理规则,面向多语言异构化架构,覆盖微服务框架及上下游关联组件。无论微服务的语言是 Java, Go, Node.js 还是其它语言,无论是标准微服务还是 Mesh 接入,从网关到微服务框架,从数据库到缓存访问,从服务注册发现到配置,开发者都可以通过同一套 OpenSergo CRD 标准配置进行统一的治理管控,而无需关注各框架、语言的差异点,降低异构化、全链路微服务治理管控的复杂度。
在 OpenSergo 中,我们结合 Sentinel 及 MSE 的场景实践对流控降级与容错抽出标准 CRD。一个容错治理规则 (FaultToleranceRule) 由以下三部分组成:
- Target: 针对什么样的请求
- Strategy: 容错或控制策略,如流控、熔断、并发控制、自适应过载保护、离群实例摘除等
- FallbackAction: 触发后的 fallback 行为,如返回某个错误或状态码
以下 YAML CR 示例定义的规则针对 Hello:Echo 这个服务方法(用资源名标识)配置了一条流控策略,全局不超过 10 QPS:
apiVersion: fault-tolerance.opensergo.io/v1alpha1
kind: RateLimitStrategy
metadata:
name: rate-limit-foo
spec:
metricType: RequestAmount
limitMode: Global
threshold: 10
statDuration: "1s"
---
apiVersion: fault-tolerance.opensergo.io/v1alpha1
kind: FaultToleranceRule
metadata:
name: my-fault-tolerance-rule
spec:
selector:
app: foo-app # 规则配置生效的服务名
targets:
- targetResourceName: 'Hello:Echo'
strategies:
- name: rate-limit-foo
# 这里还可以单独定义 fallbackAction,比如自定义返回值或错误;不指定则为默认行为
Sentinel 2.0 将原生支持 OpenSergo 流量治理相关 CRD 配置及能力,结合 Sentinel 提供的各框架的适配模块,让 Dubbo, Spring Cloud Alibaba, gRPC, CloudWeGo 等20+框架能够无缝接入到 OpenSergo 生态中,用统一的 CRD 来配置流量路由、流控降级、服务容错等治理规则。无论是 Java 还是 Go 还是 Mesh 服务,无论是 HTTP 请求还是 RPC 调用,还是数据库 SQL 访问,我们都可以用这统一的容错治理规则 CRD 来给微服务架构中的每一环配置治理,来保障我们服务链路的稳定性。MSE 作为 OpenSergo 微服务治理标准的企业级产品,也将原生支持 OpenSergo spec。
总结与展望
流控降级与容错是微服务流量治理中的重要的一环,同时 MSE 还提供更广范围、更多场景的微服务治理能力,包括全链路灰度、无损上下线、微服务数据库治理、日志治理等一系列的微服务治理能力。服务治理是微服务改造深入到一定阶段之后的必经之路,是将微服务做稳做好的关键。同时我们也在与 CloudWeGo、Kratos、Spring Cloud Alibaba、Dubbo、ShardingSphere 等社区共同建设 OpenSergo 微服务治理标准,将企业与社区中微服务治理的场景与最佳实践共同提取成标准规范,也欢迎更多社区与企业一起参与 OpenSergo 微服务治理标准的共建。欢迎大家加入 OpenSergo 社区交流群(钉钉群)进行讨论:34826335
参考链接:
MSE 微服务治理:
https://help.aliyun.com/document_detail/170447.html
Sentinel Go:
https://github.com/alibaba/sentinel-golang
OpenSergo:
CloudWeGo:
原文链接:https://click.aliyun.com/m/1000359080/
本文为阿里云原创内容,未经允许不得转载。
OpenSergo & CloudWeGo 共同保障微服务运行时流量稳定性的更多相关文章
- Re:从 0 开始的微服务架构--(四)如何保障微服务架构下的数据一致性--转
原文地址:http://mp.weixin.qq.com/s/eXvoJew3bjFKzLLJpS0Otg 随着微服务架构的推广,越来越多的公司采用微服务架构来构建自己的业务平台.就像前边的文章说的, ...
- spring_cloud多个微服务访问时偶发forward_error问题
1.问题: 最近在做SpringBoot项目的时候,有多个分开的微服务,偶发forward error 问题 2.猜想: 个人理解为服务跳转错误,可能本身没找到目标服务,或者目标服务损坏 3.解决: ...
- 微服务监控之一:Metrics让微服务运行更透明
摘要 让微服务运行状态清晰可见. 嘉宾演讲视频回顾及PPT:http://t.cn/R8b6i85 Metrics是什么 直译是“度量”,不同的领域定义有所区别,在微服务领域中的定义: “对微服务的某 ...
- 将微服务运行在docker上遇到的问题一
按照类似这样的流程: 但是去访问本机的 localhost:92 localhost:80 都没有任何的内容..... 这是什么原因? 重新再来一次 新写了一个微服务demo jar包: 相应的Doc ...
- springboot启动微服务项目时,启动后没有端口号信息,也访问不了
2018-06-05 13:43:42.282 [localhost-startStop-1] DEBUG org.apache.catalina.core.ContainerBase - Add c ...
- 我们都可以把它放 Sidecar 容器中,这样微服务具备了 Super power,一种超能力
云原生时代,微服务如何演进? 原创 李响 阿里技术 2020-08-28 https://mp.weixin.qq.com/s/KQG2U8_aotDL4YFB8ee6Zw 一 微服务架构与云原 ...
- Java微服务 vs Go微服务,究竟谁更强!?
前言 Java微服务能像Go微服务一样快吗? 这是我最近一直在思索地一个问题. 去年8月份的the Oracle Groundbreakers Tour 2020 LATAM大会上,Mark Nels ...
- 基于 Docker 的微服务架构实践
本文来自作者 未闻 在 GitChat 分享的{基于 Docker 的微服务架构实践} 前言 基于 Docker 的容器技术是在2015年的时候开始接触的,两年多的时间,作为一名 Docker 的 D ...
- 浅谈微服务架构、容器技术与K8S
关注嘉为科技,获取运维新知 企业应用系统:从单体应用走向微服务架构:从裸金属走向容器. 如果在诸多热门云计算技术诸如容器.微服务.DevOps.OpenStack等之中,找出一个最火的方向,那么可能非 ...
- 微服务介绍及Asp.net Core实战项目系列之微服务介绍
0.目录 整体架构目录:ASP.NET Core分布式项目实战-目录 一.微服务选型 在做微服务架构的技术选型的时候,我们以“无侵入”和“社区活跃”为主要的考量点,将来升级为原子服务架构.量子服务架构 ...
随机推荐
- Spring Boot获取配置参数最简单常用的两种方式
一.自定义属性及常量 在开发过程中,我们常常用到的多环境配置文件,常用的有:dev,test,prod,在不同环境下,我们用到的一样的配置参数,例如:redis,mq,回调接口的url配置.这个情况, ...
- Spring Boot学习日记
学习了springboot 的优点 为所有Spring开发者更快的入门 开箱即用,提供各种默认配置来简化项目配置 内嵌式容器简化Web项目 没有冗余代码生成和XML配置的要求 Spring开发-Hel ...
- 建民的Java小课堂
Java Java快问快答: 1.JAVA的基本运行单位是类还是方法? 很明显是类 2.类由什么组成? 由特性和行为的对象组成 3.变量的类型,相互之间可以转换吗,浮点数? 答案是可以 int i=9 ...
- 三维模型OBJ格式轻量化顶点压缩主要技术方法分析
三维模型OBJ格式轻量化顶点压缩主要技术方法分析 三维模型的OBJ格式轻量化中,顶点压缩是一项重要的技术方法,用于减小模型文件的大小.以下是关于三维模型OBJ格式轻量化顶点压缩的主要技术方法的分析: ...
- 记录--Vue开发历程---音乐播放器
这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 一.audio标签的使用 1.Audio 对象属性 2.对象方法 二.效果 效果如下: 三.代码 代码如下: MusicPlayer.vu ...
- PowerDesigner操作要点
一.PowerDesigner解决name和code同步问题 工具-常规选项-General Options-Dialog-Name to Code mirroring√去掉 二.PowerDesi ...
- KingbaseES V8R6 等待事件之LWLock Buffer_IO
等待事件含义 当进程同时尝试访问相同页面时,等待其他进程完成其输入/输出(I/O)操作时,会发生LWLock:BufferIO等待事件.其目的是将同一页读取到共享缓冲区中. 每个共享缓冲区都有一个与L ...
- KingbaseES 分区表与 Oracle 分区表对于空值的处理差异
一.对于null 值处理 1.Oracle 分区字段允许为空,只要存在maxvalue 分区,值就可以插入. SQL> create table t1(id number,data varcha ...
- Windows10系统重装教程
.
- echarts 中国地图tooltip实现提示框
point: 鼠标位置,如 [20, 40]. params: 同 formatter 的参数相同. dom: tooltip 的 dom 对象. rect: 只有鼠标在图形上时有效,是一个用x, y ...