最终一致性,从其名字看,已经放弃了强一致性,如果出现异常情况,很有可能会产生主业务已提交,边缘业务最终也没能一致的情况。如网络持续不通,一段时间重试后,任务不得不放弃

因此最终一致性还有一层隐含信息->做好最终不一致的备案,否则可能造成不可预期的问题。

目前做法

和事务型数据库一同提交
想要做到原子性,强一致性,需要将边缘业务的信息和主业务一同提交到事务型数据库中,通过已有的事务特性来保证一致性。
具体的做法是在数据库,如mysql中,建一个边缘任务表,和主业务流程的更改一同入库。
将边缘的任务方法,通过aop增强的方式,改造成往数据库中存入一条记录,和主业务一同提交到mysql,然后再通过异步、重试、告警等方式履行边缘任务的代码。
如果边缘任务重试次数超过阈值仍没有成功,就需要告警或者监听器的方式,告知备案程序,如单独记录一个失败任务信息,通过人工来处理这些失败的任务。

边缘任务获取

京东有一款分布式事务中间件,通过一致性hash算法来获取任务,让每个应用节点获取到不同的任务,避免多个任务同时被多台机器请求到,这样做需要引入一个额外的分布式系统,来监控各个应用节点的心跳,如果某个机器离线了,其他机器就可以接手它的任务。

幂等性

幂等是最重要的问题,在分布式系统中可能出现各种意料之外的问题,比如一个任务开始之后,向数据提交任务完成事件前挂掉了,其他节点会把当前任务进行重试,避免任务漏做。还有很多这种情况,解决的办法都是幂等,多次执行结果和执行一次的效果相同,如发送邮件,如果要做到幂等,需要根据边缘任务做了一个锁或者信号,其他任务发现这个锁或者信号,就知道任务正在被执行或已完成,这样就可以避免发送两次邮件

封装

代码的微入侵,可以通过aspectj在编译时增强代码,也可以通过javaagent在启动时增强,还可以在运行时利用spring aop增强,方法很多,各有优劣,其中spring aop存在“自调用”问题:原始类内部方法调用无法触及增强代码。

关于远程边缘任务数据中心

如果边缘业务表在本地数据库,则需要每个应用都在自己的库中建表,这种体验不太好,因此,又有了中心化存储边缘任务的模式,这种模式效率相较于本地库会低一些,且存在风险

posted on 2018-12-06 16:33  j.liu windliu  阅读(1323)  评论(0编辑  收藏  举报