Open ranLee1 opened 2 years ago
消费者 setProviderFallback
你不觉得奇怪么~~
消费者调用失败 抛出 BlockException
的时候 会调用 DubboAdapterGlobalConfig.getConsumerFallback().handle(invoker, invocation, e);
(所以在消费端调用需要注册的是 consumerFallack
) rpc 异常的时候 没做处理
所以你需要在 调用的时候 rpc 异常了也行调用回调 或者 返回结果中有异常时按需也可调用 可以参考框架的 filter自己实现 在 rpcexception
的时候也调用ConsumerFallback 。
全局降级 这个可以配置内置的断路器配合使用 添加对应的DegradeRule
即可
@liufeiyu1002 感谢大佬指点😊。实现方式:全局异常捕获BlockException
,其中ConsumerFallack
中异常继承于RuntimeException
,发生限流时抛出异常为:RuntimeException:SentinelBlockException: FlowException
,所以还需对RuntimeException
做判断:
消费者DubboAdapterConfig调整
@Configuration
public class DubboAdapterConfig {
@Bean
private static void registerFallback() {
DubboFallbackRegistry.setConsumerFallback(new DubboFallback() {
@Override
public Result handle(Invoker<?> invoker, Invocation invocation, BlockException ex) {
//AsyncRpcResult
CompletableFuture<AppResponse> cf = new CompletableFuture<>();
AsyncRpcResult asyncRpcResult = new AsyncRpcResult(cf, invocation);
asyncRpcResult.setException(ex);
return asyncRpcResult;
}
});
}
}
消费者全局异常捕获 GlobalExceptionHandler
@RestControllerAdvice
public class GlobalExceptionHandler {
private static final Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);
/**
* 限流器异常捕获
*
* @param e BlockException
* @return
*/
@ExceptionHandler(value = {BlockException.class})
public JSONResult handler(BlockException e) {
return getBlockExceptionInfo(e);
}
/**
* dubbo远程调用
*
* @param e RpcException
* @return
*/
@ExceptionHandler(value = {RpcException.class})
public JSONResult handler(RpcException e) {
logger.error("远程调用失败,{}", e.getMessage());
return JSONResult.failure(e.getCode(), e.getMessage());
}
/**
* 运行时异常
*
* @param e RuntimeException
* @return
*/
@ExceptionHandler(value = RuntimeException.class)
public JSONResult handler(RuntimeException e) {
if (e.getCause() instanceof BlockException) {
BlockException bk = (BlockException) e.getCause();
return getBlockExceptionInfo(bk);
}
return JSONResult.failure(e.getMessage());
}
private JSONResult getBlockExceptionInfo(BlockException e) {
String msg = "";
if (e instanceof FlowException) {
msg = "请求限流";
} else if (e instanceof ParamFlowException) {
msg = "请求热点参数限流";
} else if (e instanceof DegradeException) {
msg = "请求降级";
} else if (e instanceof AuthorityException) {
msg = "无访问权限";
} else {
msg = "捕获异常失败";
}
logger.warn(e.getRuleLimitApp()+ "," + msg);
return JSONResult.failure(msg);
}
}
测试环境
消费者pom.xml
消费者ConsumerImpl
消费者DubboAdapterConfig 全局fallback配置参考Sentinel+dubbo配置,文档中说明
用户只需要实现自定义的 DubboFallback 接口,并通过 DubboFallbackRegistry 注册即可
,我按如下代码注册结果不生效,注册方式有误还请大佬指正🙈服务者pom.xml
服务者ProductServiceImpl
分别启动消费者服务和服务者服务时,可以正常远程调用。当停掉服务者时,再次请求消费者时,控制台抛异常如下:
请问要如何实现当服务者停机时,消费者再次请求
Sentinel
可以做全局降级/限流🤔