应用管理与运维平台 ServiceStage应用管理与运维平台 ServiceStage

更新时间:2021/08/05 GMT+08:00
分享

基于动态配置的流量特征治理开发

微服务引擎提供了简单易用的基于流量标记治理的能力。您可以通过微服务引擎的服务治理功能定义业务特征和治理规则,也可以通过动态配置管理配置项的方式下发治理规则,详情请参考治理微服务

本章节重点介绍和代码开发有关的内容,包括如何配置依赖、涉及的配置项,以及不同微服务开发框架对于流量特征治理支持的差异的内容。

Java Chassis

Java Chassis通过Handler实现了基于流量标记治理能力。其中Provider实现了限流、熔断和隔离仓,Consumer实现了重试。

  1. 使用流量标记治理能力,首先需要在代码中引入依赖:
    <dependency>
      <groupId>org.apache.servicecomb</groupId>
      <artifactId>handler-governance</artifactId>
    </dependency>
  2. 然后配置Handler链:
    servicecomb:
      handler:
        chain:
          Consumer:
            default: governance-consumer,loadbalance
          Provider:
            default: governance-provider

Java Chassis是基于Open API的REST/RPC框架,在模型上和单纯的REST框架存在差异。Java Chassis提供两种模式匹配规则,第一种是基于REST的,第二种是基于RPC的。可以通过配置项:servicecomb.governance.{operation}.matchType 指定匹配规则,默认使用REST。如果使用Java Chassis中的highway协议调用,需要指定matchType类型为rpc。比如:

servicecomb:
  governance:
    matchType: rest # 设置全局默认是rest匹配模式,highway协议设置为rpc
    GovernanceEndpoint.helloRpc:
      matchType: rpc # 设置服务端的接口helloRpc采用RPC匹配模式

在REST匹配模式下, apiPath使用url, 比如:

servicecomb:
  matchGroup:
    userLoginAction: |
      matches:
        - apiPath:
            exact: "/user/login"

在RPC匹配模式下, apiPath使用operation, 比如:

servicecomb:
  matchGroup:
    userLoginAction: |
      matches:
        - apiPath:
            exact: "UserSchema.login"

对于服务端治理,比如限流,REST模式下从HTTP取header;对于客户端治理,比如重试,REST模式下从InvocationContext取header。

Spring Cloud

Spring Cloud通过Aspect拦截RequestMappingHandlerAdater实现了限流、熔断和隔离仓,通过拦截RestTemplate和FeignClient实现了重试。

使用流量标记治理能力,首先需要在代码中引入依赖:

<dependency>
  <groupId>com.huaweicloud</groupId>
  <artifactId>spring-cloud-starter-huawei-governance</artifactId>
</dependency>

Spring Cloud是基于REST的框架,能比较好的符合流量特征治理的匹配语义,apiPath和headers分别对应HTTP协议的概念:

servicecomb:
  matchGroup:
    userLoginAction: |
      matches:
        - apiPath:
            exact: "/user/login"
          method:
            - POST
        - headers:
          Authentication: 
            prefix: Basic

Dubbo

Dubbo的Provider通过Filter拦截请求实现了限流、熔断和隔离仓,通过拦截ClusterInvoker实现了重试。

使用流量标记治理能力,首先需要在代码中引入依赖:

<dependency>
  <groupId>com.huaweicloud.dubbo-servicecomb</groupId>
  <artifactId>dubbo-servicecomb-governance-center</artifactId>
  <version>${project.version}</version>
</dependency>

如果要使用重试,需要修改Dubbo的Spring配置文件,将Dubbo默认的ClusterInvoker修改为dubbo-servicecomb:

 <dubbo:consumer cluster="dubbo-servicecomb"></dubbo:consumer>

Dubbo是一个RPC框架,需要定义operation和apiPath的映射关系,比如,服务端限流、熔断、隔离仓场景:com.huaweicloud.it.order.OrderGovernanceService.hello;客户端重试场景:com.huaweicloud.it.order.OrderGovernanceService.retry。headers使用Attachments,需要包含在Attachments里面的头才会参与匹配。

servicecomb:
  matchGroup:
    userLoginAction: |
      matches:
        - apiPath:
            exact: "com.huaweicloud.it.order.OrderGovernanceService.hello"
          method:
            - POST
        - headers:
            Authentication: 
              prefix: Basic

自定义

服务治理的默认实现并不一定能够解决业务的所有问题。自定义治理功能可以方便的在不同的场景下使用基于流量的治理能力,比如在网关场景下进行流控,在Java Chassis场景下支持URL匹配等。SDK基于Spring,使用Spring的框架都能够灵活的使用这些API,方法类似。

下面以流控为例,说明如何使用API。使用API开发的自定义代码,也可以通过微服务引擎的管理控制台下发业务和治理规则。

代码的基本过程包括声明RateLimitingHandler的引用,创建GovernanceRequest,拦截(包装)业务逻辑,处理治理异常。

 @Autowired
private RateLimitingHandler rateLimitingHandler;

GovernanceRequest governanceRequest = convert(request);

CheckedFunction0<Object> next = pjp::proceed;
DecorateCheckedSupplier<Object> dcs = Decorators.ofCheckedSupplier(next);

try {
  SpringCloudInvocationContext.setInvocationContext();

  RateLimiter rateLimiter = rateLimitingHandler.getActuator(request);
  if (rateLimiter != null) {
	dcs.withRateLimiter(rateLimiter);
  }

  return dcs.get();
} catch (Throwable th) {
  if (th instanceof RequestNotPermitted) {
	response.setStatus(429);
	response.getWriter().print("rate limited.");
	LOGGER.warn("the request is rate limit by policy : {}",
		th.getMessage());
  } else {
	if (serverRecoverPolicy != null) {
	  return serverRecoverPolicy.apply(th);
	}
	throw th;
  }
} finally {
  SpringCloudInvocationContext.removeInvocationContext();
}

上面简单的介绍了自定义开发。对于更加深入的使用方式,也可以直接参考Java Chassis、Spring Cloud、Dubbo项目中的默认实现代码。

分享:

    相关文档

    相关产品