sentinel+dubbo
如何实现dubbo远程调用异常时全局的降级或熔断,尝试过 sentinel-demo-dubbo 无法实现全局 fallback
,测试代码如下
测试环境
- springcloud:Hoxton.SR12
- springcloudalibaba:2.2.7.RELEASE
- dubbo:2.7.13
- Sentinel:1.8.4
消费者pom.xml
<dependencies>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-dubbo</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-apache-dubbo-adapter</artifactId>
</dependency>
<!--Snetinel 依赖-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-spring-cloud-gateway-adapter</artifactId>
</dependency>
</dependencies>
消费者ConsumerImpl
@Service
public class ConsumerServiceImpl implements IConsumerService {
@DubboReference
private IProductService productService;
@Override
@SentinelResource(value = "testHello")
public String hello(Long id) {
Random random = new Random();
productService.hello(id.toString());
String serialNum = String.valueOf(random.nextInt(1000));
return Thread.currentThread().getName() + "\t" + "调用成功,流水号为:" + serialNum;
}
}
消费者DubboAdapterConfig
全局fallback配置参考Sentinel+dubbo配置,文档中说明 用户只需要实现自定义的 DubboFallback 接口,并通过 DubboFallbackRegistry 注册即可
,我按如下代码注册结果不生效,注册方式有误还请大佬指正🙈
@Configuration
public class DubboAdapterConfig {
private static final Logger logger = LoggerFactory.getLogger(DubboAdapterConfig.class);
@Bean
private static void registerFallback() {
DubboFallbackRegistry.setProviderFallback(new DubboFallback() {
@Override
public Result handle(Invoker<?> invoker, Invocation invocation, BlockException ex) {
return new AppResponse("错误: " + ex.getClass().getTypeName());
}
});
}
}
服务者pom.xml
<dependencies>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-dubbo</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-apache-dubbo-adapter</artifactId>
</dependency>
<!--Snetinel 依赖-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
</dependencies>
服务者ProductServiceImpl
@DubboService
public class ProductServiceImpl implements IProductService {
@Override
public String hello(String str) {
return "结果:" + str;
}
}
分别启动消费者服务和服务者服务时,可以正常远程调用。当停掉服务者时,再次请求消费者时,控制台抛异常如下:
org.apache.dubbo.rpc.RpcException: No provider available from registry 127.0.0.1:8858 for service com.ran.member.api.service.IProductService on consumer 172.17.192.1 use dubbo version 2.7.13, please check status of providers(disabled, not registered or in blacklist).
at org.apache.dubbo.registry.integration.DynamicDirectory.doList(DynamicDirectory.java:168) ~[dubbo-2.7.13.jar:2.7.13]
Suppressed: reactor.core.publisher.FluxOnAssembly$OnAssemblyException:
Error has been observed at the following site(s):
|_ checkpoint ⇢ org.springframework.cloud.gateway.filter.WeightCalculatorWebFilter [DefaultWebFilterChain]
|_ checkpoint ⇢ org.springframework.boot.actuate.metrics.web.reactive.server.MetricsWebFilter [DefaultWebFilterChain]
|_ checkpoint ⇢ HTTP GET "/index?id=-1" [ExceptionHandlingWebHandler]
Stack trace:
请问要如何实现当服务者停机时,消费者再次请求 Sentinel
可以做全局降级/限流🤔
2条答案
按热度按时间rur96b6h1#
消费者
setProviderFallback
你不觉得奇怪么~~消费者调用失败 抛出
BlockException
的时候 会调用DubboAdapterGlobalConfig.getConsumerFallback().handle(invoker, invocation, e);
(所以在消费端调用需要注册的是consumerFallack
) rpc 异常的时候 没做处理所以你需要在 调用的时候 rpc 异常了也行调用回调 或者 返回结果中有异常时按需也可调用 可以参考框架的 filter自己实现 在
rpcexception
的时候也调用ConsumerFallback 。全局降级 这个可以配置内置的断路器配合使用 添加对应的
DegradeRule
即可yqyhoc1h2#
@liufeiyu1002 感谢大佬指点😊。实现方式:全局异常捕获
BlockException
,其中ConsumerFallack
中异常继承于RuntimeException
,发生限流时抛出异常为:RuntimeException:SentinelBlockException: FlowException
,所以还需对RuntimeException
做判断:消费者DubboAdapterConfig调整
消费者全局异常捕获 GlobalExceptionHandler