熔断降级

熔断整个服务

配置熔断规则

配置服务熔断规则,针对default命名空间下所有的服务,对于时延大于500毫秒,或者返回码为500的请求,标识为错误请求,一旦一分钟内错误率30%及以上或连续错误数在5个以上,则对服务进行熔断。

熔断降级 - 图1

使用SDK进行熔断判断

方法说明

北极星Java SDK提供以下熔断相关的方法,所有的方法都在com.tencent.polaris.circuitbreak.api.CircuitBreakAPI接口中提供。

  • check:检查资源是否可被调用,并对资源获取调用申请。对于半开的资源,如果半开的调用配额申请成功,返回true,否则返回false。
  • report:该方法供用户在资源调用完成后,上报调用的结果,包括返回码、时延等信息,供熔断逻辑判断。
  • makeFunctionalDecorator:创建一个函数调用装饰器FunctionalDecorator,装饰器可以对Java的函数接口进行装饰。装饰后的逻辑,会在函数逻辑调用前,先通过check方法检查资源是否可被调用,如果不能被调用,会抛出资源熔断异常(CallAbortedException)。调用完成后,会通过report接口上报本次调用结果。FunctionalDecorator包含以下方法:
    • decorateSupplier:对函数接口Supplier进行封装。
    • decorateConsumer:对函数接口Consumer进行封装。
    • decorateFunction:对函数Function进行封装。
    • decoratePredicate:对函数接口Predicate进行封装。

使用示例

  1. // 创建CircuitBreakAPI实例
  2. CircuitBreakAPI circuitBreakAPI = CircuitBreakAPIFactory.createCircuitBreakAPI();
  3. // 通过传入服务名(testService1)和命名空间(default),创建FunctionalDecorator
  4. FunctionalDecoratorRequest makeDecoratorRequest = new FunctionalDecoratorRequest();
  5. makeDecoratorRequest.setService(new ServiceKey("default", "testService1"));
  6. FunctionalDecorator decorator = circuitBreakAPI.makeFunctionalDecorator(makeDecoratorRequest);
  7. // 封装函数接口
  8. Consumer<Integer> integerConsumer = decorator.decorateConsumer(new Consumer<Integer>() {
  9. @Override
  10. public void accept(Integer object) {
  11. // 执行服务调用...
  12. }
  13. });
  14. // 通过执行函数接口,进行服务调用
  15. // 在调用过程中,如果出现熔断,会抛出CallAbortedException异常
  16. for (int i = 0; i < 500; i++) {
  17. try {
  18. integerConsumer.accept(i);
  19. } catch(CallAbortedException e) {
  20. e.printStackTrace();
  21. }
  22. }

样例地址

Github地址

熔断单个接口

配置熔断规则

配置接口熔断规则,针对default命名空间所有服务的foo接口,对于时延大于500毫秒,或者返回码为500的请求,标识为错误请求,一旦一分钟内错误率30%及以上或连续错误数在5个以上,则对接口进行熔断。

熔断降级 - 图2

使用SDK进行熔断判断

熔断所使用的SDK接口及方法与服务级熔断相同,这里不再重复介绍。

使用示例

  1. // 创建CircuitBreakAPI实例
  2. CircuitBreakAPI circuitBreakAPI = CircuitBreakAPIFactory.createCircuitBreakAPI();
  3. // 通过传入服务名(testService1)、命名空间(default)和方法名(foo),创建FunctionalDecorator
  4. FunctionalDecoratorRequest makeDecoratorRequest = new FunctionalDecoratorRequest();
  5. makeDecoratorRequest.setService(new ServiceKey("default", "testService1"));
  6. makeDecoratorRequest.setMethod("foo");
  7. FunctionalDecorator decorator = circuitBreakAPI.makeFunctionalDecorator(makeDecoratorRequest);
  8. // 封装函数接口
  9. Consumer<Integer> integerConsumer = decorator.decorateConsumer(new Consumer<Integer>() {
  10. @Override
  11. public void accept(Integer object) {
  12. // 执行服务接口调用...
  13. }
  14. });
  15. // 通过执行函数接口,进行服务调用
  16. // 在调用过程中,如果出现熔断,会抛出CallAbortedException异常
  17. for (int i = 0; i < 500; i++) {
  18. try {
  19. integerConsumer.accept(i);
  20. } catch(CallAbortedException e) {
  21. e.printStackTrace();
  22. }
  23. }

样例地址

Github地址

熔断单个实例

配置熔断规则

配置实例熔断规则,针对default命名空间下所有的服务实例,对于时延大于500毫秒,或者返回码为500的请求,标识为错误请求,每个实例的错误率是单独统计的,一旦一分钟内错误率30%及以上或连续错误数在5个以上,则对被调实例(IP:PORT)进行熔断。

熔断降级 - 图3

使用SDK进行熔断判断

当实例被熔断时,该实例会暂时不接收请求,原本路由到该实例的请求会路由到其他实例。这个过程在服务路由过程中自动完成,用户无需进行额外的熔断状态判断等操作。

引入依赖

修改应用根目录下的pom.xml,为 polaris-java 添加 dependencyManagement:

  1. <dependencyManagement>
  2. <dependencies>
  3. <dependency>
  4. <groupId>com.tencent.polaris</groupId>
  5. <artifactId>polaris-dependencies</artifactId>
  6. <version>${version}</version>
  7. <type>pom</type>
  8. <scope>import</scope>
  9. </dependency>
  10. </dependencies>
  11. </dependencyManagement>

然后只需要在 标签中在添加 polaris-all 即可

  1. <dependencies>
  2. <dependency>
  3. <groupId>com.tencent.polaris</groupId>
  4. <artifactId>polaris-all</artifactId>
  5. </dependency>
  6. </dependencies>

配置北极星服务端地址

用户需要在项目的 main/resources 下创建一个 polaris.yaml 文件用于初始化 polaris-java SDK。

  1. global:
  2. serverConnector:
  3. # 北极星服务端地址,端口为8091
  4. addresses:
  5. - 127.0.0.1:8091

执行服务路由

  1. import com.tencent.polaris.factory.api.DiscoveryAPIFactory;
  2. public static void main(String[] args) throws Exception {
  3. ConsumerAPI consumerAPI = DiscoveryAPIFactory.createConsumerAPI();
  4. // 执行服务路由,筛选出单个实例,在这个过程中,会自动剔除熔断的实例
  5. GetOneInstanceRequest getOneInstanceRequest = new GetOneInstanceRequest();
  6. getOneInstanceRequest.setNamespace("default");
  7. getOneInstanceRequest.setService("testService1");
  8. InstancesResponse oneInstance = consumerAPI.getOneInstance(getOneInstanceRequest);
  9. Instance targetInstance = oneInstance.getInstances()[0];
  10. // 执行服务调用
  11. // invoke rpc call with targetInstance
  12. // 上报调用结果,调用结果用于进行熔断判断
  13. ServiceCallResult result = new ServiceCallResult();
  14. result.setNamespace(namespace);
  15. result.setService(service);
  16. result.setHost(targetInstance.getHost());
  17. result.setPort(targetInstance.getPort());
  18. // 设置返回码
  19. result.setRetCode(code);
  20. // 设置调用时延
  21. result.setDelay(delay);
  22. // 使用updateServiceCallResult上报调用结果
  23. consumerAPI.updateServiceCallResult(result);
  24. }

样例地址

Github地址

启用主动探测

业务往往会存在高峰期和低峰期,低峰期流量比较少,不足以触发熔断,会出现当部分实例出现数据不可达的问题时,没法及时发现,导致高峰期到来时出现故障。

主动探测可以解决这个问题,启用主动探测后,主调方会定时根据探测规则,对被调实例进行探测,探测结果可作为熔断的判断依据,可实现对故障资源的快速熔断。

配置主动探测规则

配置一个主动探测规则,对服务(名为testService1,命名空间为default)进行探测。探测使用的协议是HTTP协议,由于服务开启了鉴权,因此探测时需要传入鉴权头。

熔断降级 - 图4

注意:主动探测的规则,服务名可以选择全部服务,则规则针对全部服务生效。如果需要针对只接口进行探测,则可以在接口字段中填入对应的接口名。

在熔断规则中开启主动探测

需要在熔断规则中开启探测,这样才可以把探测结果用于熔断。

熔断降级 - 图5