熔断降级
熔断整个服务
配置熔断规则
配置服务熔断规则,针对default命名空间下所有的服务,对于时延大于500毫秒,或者返回码为500的请求,标识为错误请求,一旦一分钟内错误率30%及以上或连续错误数在5个以上,则对服务进行熔断。
使用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进行封装。
使用示例
// 创建CircuitBreakAPI实例
CircuitBreakAPI circuitBreakAPI = CircuitBreakAPIFactory.createCircuitBreakAPI();
// 通过传入服务名(testService1)和命名空间(default),创建FunctionalDecorator
FunctionalDecoratorRequest makeDecoratorRequest = new FunctionalDecoratorRequest();
makeDecoratorRequest.setService(new ServiceKey("default", "testService1"));
FunctionalDecorator decorator = circuitBreakAPI.makeFunctionalDecorator(makeDecoratorRequest);
// 封装函数接口
Consumer<Integer> integerConsumer = decorator.decorateConsumer(new Consumer<Integer>() {
@Override
public void accept(Integer object) {
// 执行服务调用...
}
});
// 通过执行函数接口,进行服务调用
// 在调用过程中,如果出现熔断,会抛出CallAbortedException异常
for (int i = 0; i < 500; i++) {
try {
integerConsumer.accept(i);
} catch(CallAbortedException e) {
e.printStackTrace();
}
}
样例地址
熔断单个接口
配置熔断规则
配置接口熔断规则,针对default命名空间所有服务的foo接口,对于时延大于500毫秒,或者返回码为500的请求,标识为错误请求,一旦一分钟内错误率30%及以上或连续错误数在5个以上,则对接口进行熔断。
使用SDK进行熔断判断
熔断所使用的SDK接口及方法与服务级熔断相同,这里不再重复介绍。
使用示例
// 创建CircuitBreakAPI实例
CircuitBreakAPI circuitBreakAPI = CircuitBreakAPIFactory.createCircuitBreakAPI();
// 通过传入服务名(testService1)、命名空间(default)和方法名(foo),创建FunctionalDecorator
FunctionalDecoratorRequest makeDecoratorRequest = new FunctionalDecoratorRequest();
makeDecoratorRequest.setService(new ServiceKey("default", "testService1"));
makeDecoratorRequest.setMethod("foo");
FunctionalDecorator decorator = circuitBreakAPI.makeFunctionalDecorator(makeDecoratorRequest);
// 封装函数接口
Consumer<Integer> integerConsumer = decorator.decorateConsumer(new Consumer<Integer>() {
@Override
public void accept(Integer object) {
// 执行服务接口调用...
}
});
// 通过执行函数接口,进行服务调用
// 在调用过程中,如果出现熔断,会抛出CallAbortedException异常
for (int i = 0; i < 500; i++) {
try {
integerConsumer.accept(i);
} catch(CallAbortedException e) {
e.printStackTrace();
}
}
样例地址
熔断单个实例
配置熔断规则
配置实例熔断规则,针对default命名空间下所有的服务实例,对于时延大于500毫秒,或者返回码为500的请求,标识为错误请求,每个实例的错误率是单独统计的,一旦一分钟内错误率30%及以上或连续错误数在5个以上,则对被调实例(IP:PORT)进行熔断。
使用SDK进行熔断判断
当实例被熔断时,该实例会暂时不接收请求,原本路由到该实例的请求会路由到其他实例。这个过程在服务路由过程中自动完成,用户无需进行额外的熔断状态判断等操作。
引入依赖
修改应用根目录下的pom.xml,为 polaris-java 添加 dependencyManagement:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.tencent.polaris</groupId>
<artifactId>polaris-dependencies</artifactId>
<version>${version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
然后只需要在 标签中在添加 polaris-all 即可
<dependencies>
<dependency>
<groupId>com.tencent.polaris</groupId>
<artifactId>polaris-all</artifactId>
</dependency>
</dependencies>
配置北极星服务端地址
用户需要在项目的 main/resources 下创建一个 polaris.yaml 文件用于初始化 polaris-java SDK。
global:
serverConnector:
# 北极星服务端地址,端口为8091
addresses:
- 127.0.0.1:8091
执行服务路由
import com.tencent.polaris.factory.api.DiscoveryAPIFactory;
public static void main(String[] args) throws Exception {
ConsumerAPI consumerAPI = DiscoveryAPIFactory.createConsumerAPI();
// 执行服务路由,筛选出单个实例,在这个过程中,会自动剔除熔断的实例
GetOneInstanceRequest getOneInstanceRequest = new GetOneInstanceRequest();
getOneInstanceRequest.setNamespace("default");
getOneInstanceRequest.setService("testService1");
InstancesResponse oneInstance = consumerAPI.getOneInstance(getOneInstanceRequest);
Instance targetInstance = oneInstance.getInstances()[0];
// 执行服务调用
// invoke rpc call with targetInstance
// 上报调用结果,调用结果用于进行熔断判断
ServiceCallResult result = new ServiceCallResult();
result.setNamespace(namespace);
result.setService(service);
result.setHost(targetInstance.getHost());
result.setPort(targetInstance.getPort());
// 设置返回码
result.setRetCode(code);
// 设置调用时延
result.setDelay(delay);
// 使用updateServiceCallResult上报调用结果
consumerAPI.updateServiceCallResult(result);
}
样例地址
启用主动探测
业务往往会存在高峰期和低峰期,低峰期流量比较少,不足以触发熔断,会出现当部分实例出现数据不可达的问题时,没法及时发现,导致高峰期到来时出现故障。
主动探测可以解决这个问题,启用主动探测后,主调方会定时根据探测规则,对被调实例进行探测,探测结果可作为熔断的判断依据,可实现对故障资源的快速熔断。
配置主动探测规则
配置一个主动探测规则,对服务(名为testService1,命名空间为default)进行探测。探测使用的协议是HTTP协议,由于服务开启了鉴权,因此探测时需要传入鉴权头。
注意:主动探测的规则,服务名可以选择全部服务,则规则针对全部服务生效。如果需要针对只接口进行探测,则可以在接口字段中填入对应的接口名。
在熔断规则中开启主动探测
需要在熔断规则中开启探测,这样才可以把探测结果用于熔断。