@ExceptionHandler+seata+sentinel冲突问题

背景说明

@ExceptionHandlerspringboot中的通用异常处理,通过与配合@RestControllerAdvice,达到处理全局异常的目的。

seataspringcloud alibaba的分布式事务组件

sentinelspringcloud alibaba的服务降级、熔断组件

当这三个组件在一起出现时,会产生什么结果呢?

模拟情况

testService作为服务消费者,userService作为服务提供者,当userService出现异常时,大致分为以下几种情况:

模拟情况

情况1:ExceptionHandler+seata

服务提供者的ExceptionHandler将异常处理成了ResponseResultUtil.error这种返回值,而服务消费者的feign将其识别为了无异常的返回值,导致调用方不回滚事务。

情况1

情况2:sentinel+seata

服务提供者返回异常,服务消费者的sentinel将其降级处理,进入fallback后,服务消费者视作无异常,导致其不回滚事务。

情况2

情况3:ExceptionHandler+seata+sentinel

类似情况1,服务消费者无异常,也不会降级,导致其不回滚事务。

解决方案

1.sentinel作为服务降级组件、存在的意义就在于能够让业务正常走下去,所以在逻辑要求严格的业务中不应引入。

不应引入的模块,如转销售:先改单据状态、再占库、最后做账,这一系列流程的结果必须保证一致,需要同时完成,不可降级。(其他思考:功能痛点:逻辑严格的系统中,如果一个微小的系统异常,导致用户表单无法提交,很影响体验。这种严格流程是否应该?是否也可以增加状态来控制流程?比如订单状态改了,但占库失败,增加未占库状态,之后再手动、或者自动去占库、做账,提高系统的容错率及可用性。

可以考虑引入的模块,如新建用户:先创建用户,再关联角色,如果用户表单的项目很多,角色是其中一个select,而恰好关联角色时,又有问题,则可以考虑先保存用户信息,关联角色降级处理,这样的好处是可以让使用者先将要创建的大部分数据创建进去,回头再处理有问题的部分。当然前提必须是对业务影响较小的情况。

处理方式只需去掉fallback即可

而且,目前fallback只能针对对于整个interface,而不支持针对于interface中的某一个方法。所以如果有某一个方法需要特殊处理,还需要再额外增加接口。所以对于sentinel,应持保守态度。

2.@ExceptionHandler配合@RestControllerAdvice意味着绑定了所有的@RequestMapping,即所有的接口都会进行异常处理,结合目前只有记录错误日志、和处理返回体2种功能的这种情况,而影响到全局事务的功能只有处理通用返回体,所以应明确:

2.1.终端的所有请求,皆通过主服务,即服务消费者。所以在此独立jar包中,采用通用的异常处理,去处理返回体是没问题的。

2.2.而其他的服务提供者,如库存、账款、订单、基础服务提供者,一定不能将异常处理为正常返回体(日志保留),只有这样,才能不影响seata全局事务。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 本文章仅作为个人笔记 nacos 接入 gateway 参考 nacos 的服务安装(这里都仅处理单机模式)官网...
    草丛里的黄盖阅读 3,078评论 0 5
  • 十三、消息总线 SpringCloudBus配合SpringCloudConfig一起使用,可以实现配置的动态刷新...
    西谷haul阅读 1,091评论 0 0
  • 内存模型以及分区 JVM分为虚拟机栈、堆、方法区、本地方法区堆,用来存放实例化对象、非static成员变量,属于线...
    北京黄小胖阅读 1,257评论 0 0
  • 基于分布式微服务架构 SpringCloud=分布式微服务架构的一站式解决方案,是多种微服务架构落地技术的集合体,...
    任人渐疏_8786阅读 2,754评论 1 1
  • 久违的晴天,家长会。 家长大会开好到教室时,离放学已经没多少时间了。班主任说已经安排了三个家长分享经验。 放学铃声...
    飘雪儿5阅读 7,581评论 16 22