1.6 使用微服务引擎功能
1.6.3 使用服务治理
1.6.3.2 基于动态配置的流量特征治理介绍
基于动态配置的流量特征治理旨在提供一种通用的,适合不同语言、不同微服务开发 框架的治理规则。治理规则规定了微服务治理的过程、治理的策略,可以使用不同的 开发框架、技术实现治理规则约定的治理能力。
您可以在Java Chassis、Spring Cloud、Dubbo中使用该功能。
Java Chassis提供了实现SDK,可以将其用于其他开发框架。SDK默认采用Resilience4j 实现治理过程。规范没有约束治理过程的实现框架,可以很方便的使用其他的治理框 架实现治理过程。
治理过程
治理过程可以从如下两个不同的角度进行描述:
● 从管理流程上,可以分为流量标记和设置治理规则两个步骤。系统架构师将请求 流量根据特征打上标记,用于区分一个或者一组代表具体业务含义的流量,然后 对这些流量设置治理规则。
● 从处理过程上,可以分为下发配置和应用治理规则两个步骤。 可以通过配置文 件、配置中心、环境变量等常见的配置管理手段下发配置。微服务SDK负责读取 配置,解析治理规则,实现治理效果。
治理策略
治理策略分两部分进行描述,一部分描述流量标记, 一部分描述治理规则。
可以根据请求的特征进行流量标记,示例如下:
servicecomb:
matchGroup:
userLoginAction: | matches:
- apiPath:
exact: "/login"
method:
- POST - headers:
Authentication:
prefix: Basic
示例定义了一个流量特征userLoginAction,如果流量的apiPath=/
login&method=POST, 或者请求头Authentication=Basic*,那么认为这个流量是一个 登录操作。
定义好流量特征后,就可以设置治理规则,示例如下:
servicecomb:
rateLimiting:
userLoginAction: | rate: 100
示例设置流量特征userLoginAction的限流策略是100TPS。
规范参考
● 流量标记 示例如下:
servicecomb:
matchGroup:
userLoginAction: | matches:
- name: loginMethod apiPath:
exact: "/login"
method:
- POST
- name: authHeader headers:
Authentication:
prefix: Basic
一个流量对应一个Key,userLoginAction为Key的名称。 一个流量可以定义多个 标记规则,每个标记规则里面可以定义apiPath,method,headers匹配规则。
不同标记规则是或的关系,匹配规则是与的关系。
在match中提供了一系列的算子来对apiPath或者headers进行匹配:
– exact : 精确匹配。
– prefix: 前缀匹配。
– suffix: 后缀匹配。
– contains: 包含, 目标字符串是否包含模式字符串。
– compare: 比较,支持>、<、>=、<=、=、!=符号匹配。处理时会把模式字符 串和目标字符串转化为Double类型进行比较,支持的数据范围为Double的数 据范围。在进行=和!=判断时,如果二者的差值小于1e-6就视为相等。例如模 式串为>-10,会对大于-10以上的目标串匹配成功。
流量标记可以在不同的应用层实现,比如:在提供REST接口的服务端,可以通过 HttpServletRequest获取流量信息;在RestTemplate调用的客户端,可以从 RestTemplate获取流量信息。
不同的框架和应用层,提取信息的方式不一样。实现层通过将特征映射到 GovernanceRequest来屏蔽差异。使得在不同的框架、不同的应用层都可以使用 治理。
public class GovernanceRequest { private Map<String, String> headers;
private String uri;
private String method;
}
● 限流 示例如下:
servicecomb:
rateLimiting:
userLoginAction: |
retryOnResponseStatus: [502,503,5xx] # 响应码,通过响应码列表指定重试场景,默 认是502,5xx表示匹配500-599的响应码
retryOnResponseStatus: [502,503,5xx] # 响应码,通过响应码列表指定重试场景,默认是 502,5xx表示匹配500-599的响应码
retryStrateg: RandomBackoff # 重试策略,默认为FixedInterval固定时间间隔策略 initialInterval:1000 # 基准时间间隔,最小值为10,单位默认毫秒,支持Duration类型时 间 multiplier: 2.0f # 乘积因子,单位为float,取值范围大于1.0
重试条件是框架相关的,通过扩展RetryExtension, 不同框架实现机制可能不 同:
public interface RetryExtension {
boolean isRetry(List<Integer> statusList, Object result);
Class<? extends Throwable>[] retryExceptions();
}
● 熔断 示例如下:
servicecomb:
circuitBreaker:
userLoginAction: |
failureRateThreshold:50 # 失败率(请求)百分比阈值,取值范围(0,100.0]
slowCallRateThreshold: 100 # 慢调用率阀值,取值范围取值范围(0,100.0]
slowCallDurationThreshold: 60000 # 慢调用请求阈值定义,响应时间超过该阈值的请求 都是慢调用,单位默认毫秒,支持Duration类型时间
minimumNumberOfCalls: 100 # 达到熔断条件的请求数量下限 slidingWindowType: count # 滑动窗口计数类型,默认为time类型
slidingWindowSize: 100 # 滑动窗口大小,当为滑动窗口类型为time类型时,窗口大小表 示时间,单位为秒
熔断规则借鉴了Resilience4j的思想,作用在服务端,其原理为:
达到指定failureRateThreshold错误率或者slowCallRateThreshold慢请求率时进行 熔断,返回响应码429,慢请求通过SlowCallDurationThreshold定义。
minimumNumberOfCalls是达到熔断要求的最低请求数量门槛,例如,若
minimumNumberOfCalls是10,为计算失败率,则最小要记录10个调用。若只记 录了9个调用,即使9个都失败,CircuitBreaker也不会打开。slidingWindowType 指定滑动窗口类型,默认可选count/time, 分别是基于请求数量窗口和基于时间 窗口。若滑动窗口为count,则最近slidingWindowSize次的调用会被记录和统 计。若滑动窗口为time,则最近slidingWindowSize秒中的调用会被记录和统计。
slidingWindowSize指定窗口大小,根据滑动窗口类型,单位可能是请求数量或者 秒。
● 隔离仓 示例如下:
servicecomb:
bulkhead:
userLoginAction: |
maxConcurrentCalls: 1000 # 最大信号量
maxWaitDuration: 0 # 最大等待时间间隔,单位默认毫秒,支持Duration类型时间 隔离仓规则借鉴了Resilience4j的思想,作用在服务端,其原理为:
隔离仓使用了信号量机制,当大量并发请求进入时,如果信号量存在剩余,进入 系统的请求会直接获取信号量并开始业务处理。当信号量全被占用时,请求将会 进入阻塞状态,如果maxWaitDuration时间内无法获取到信号量则系统会拒绝这 些请求。若请求在阻塞计时maxWaitDuration内获取到了信号量,那么将直接获 取信号量并执行相应的业务处理。开启隔离仓时,返回错误码429。在异步框架,
建议maxWaitDuration设置为0,防止阻塞事件派发线程。