servicecomb-pack
servicecomb-pack copied to clipboard
分布式事务优雅shut down服务问题
关闭服务之后,不能调用补偿,即使多实例的情况下,关闭其中一个实例,也不能调用补偿
你的问题场景能具体描述一下吗?如果是分布式事务参与者服务实例退出,Omega是需要在Alpha注销的。目前Alpha在调用Omega的补偿方法是通过CompositeOmegaCallback中的compensate方法, 现在的实现还是绑定了具体的实例, 针对你的问题是可以进行相关的扩展加载不同实例的选择。
服务A call 服务B
服务B代码 如下:
@Transactional
@Compensable(compensationMethod = "cancel",retries=5)
@Override
@DtIdempotent
public void updateUserCoinWallet(UpdateUserCoinWalletReq req) {
logger.error("钱包【uid={},coinId={}】,begin" +
"更新钱包,globalTxId={}", req.getUid(),req.getCoinId(),req.getGlobalTxId()) ;
List<String> keys = new ArrayList<>();
List<Object> argList = new ArrayList<>();
... ...
}
@Transactional
@DtIdempotent
public void cancel(UpdateUserCoinWalletReq req) {
logger.error("钱包【uid={},coinId={}】,撤销更新,globalTxId={}", req.getUid(),req.getCoinId(),req.getGlobalTxId()) ;
List<String> keys = new ArrayList<>();
List<String> argList = new ArrayList<>();
... ...
}
服务A中通过SagaStart注解 启动saga事务管理。
服务B 只配置一个实例,在进行重启的时候(启动时长约1分钟) ,重启完成后发现部分事务没有补偿成功。
这种情况是否在服务B端有什么处理机制需要做改进,避免这种情况发生。
@DtIdempotent
这个注解是在怎么使用的?您所指的优雅shutdown是说在服务B重启的时候,要保证所有的outstanding transaction都是已完成或者已补偿的状态?
@DtIdempotent
这个注解是在怎么使用的?您所指的优雅shutdown是说在服务B重启的时候,要保证所有的outstanding transaction都是已完成或者已补偿的状态?
这个是我自定义的注解,实现幂等的
OK, 那你想实现的Graceful shutdown是在服务重启的时候,要保证所有的outstanding transaction都是已完成或者已补偿的状态
?
OK, 那你想实现的Graceful shutdown是
在服务重启的时候,要保证所有的outstanding transaction都是已完成或者已补偿的状态
?
是的,目前重启之后会补偿之前的事务吗?我测试了之后是不行的
现在补偿采用的方式是grpc回调,目前应该是不支持对多omega实例。@WillemJiang,是这样的吗?
@Richhardbranson Alpha端有一个rest api的接口,你看看能不能通过接口查询到?
多个Omega的支持可以通过查询注册的客户端来实现,如果是多个Alpha的情况下处理比较复杂,这块我们还没有实现, @tnessn @Richhardbranson 有兴趣做一下吗?我会给出相关的指导的。 另外建议使用Saga 状态机模式 ,有关数据接口的实现我们不打算提供支持了。
状态机模式下, 查询事件的API
我们已经切换到状态机模式下,在状态机模式下可以方便的查看到事务的执行情况。在这种模式下,我们再次对omega所在服务进行重启操作。出现了5个suspended的事务。 都是TxAbortEvent 执行超时。这种情况下要保证事务的最终一致性,需要人为干预。UI是没有这个功能的,是否有API可以实现触发。
@WillemJiang good catch ! I think it is worth to raise an issue for changing these codes ?
@Richhardbranson feel free to raise an issue on SCB !
我们已经切换到状态机模式下,在状态机模式下可以方便的查看到事务的执行情况。在这种模式下,我们再次对omega所在服务进行重启操作。出现了5个suspended的事务。 都是TxAbortEvent 执行超时。这种情况下要保证事务的最终一致性,需要人为干预。UI是没有这个功能的,是否有API可以实现触发。
在界面实现失败事务的人为干预是一个不错的想法,我下一步正策划实现这个功能,目前还没有开始,有兴趣一起参与吗?
我创建了 JIRA https://issues.apache.org/jira/browse/SCB-1852 跟踪这个问题
另外还有一点建议。因为各种场景下,异常的情况是有很多的。哪些类别的异常可以自动进行补偿,建议可以进行可扩展的定义。这样对与整个系统的实用性会有很大增强。是否你们已经有考虑。
自动化补偿这块在Alpha端是调用compensate方法。如果能够恢复成功的,就自动恢复了,如果恢复不成功,还是需要人为参与的。 @Richhardbranson 不知道你提到的扩展定义是什么?能详细说明一下吗?
补偿方法的参数,是缓存在omega实例的内存里的,实例一旦停止,就无法补偿了。只能让omega先不接收新的请求(手动从注册中心或nginx下线),并等已有事务回调全部完毕,才能够优雅shutwown
了解了, @lastboy1228 这块主要shutdown实例的过程中,需要Omega做一些额外处理, 你有兴趣提供补丁吗?