关键是你的操作是不是幂等的。
一个幂等的操作典型如:
把编号为5的记录的A字段设置为0
这种操作不管执行多少次都是幂等的。
一个非幂等的操作典型如:
把编号为5的记录的A字段增加1
这种操作显然就不是幂等的。
要做到幂等性,从接口设计上来说不设计任何非幂等的操作即可。
譬如说需求是:
当用户点击赞同时,将答案的赞同数量+1。
改为:
当用户点击赞同时,确保答案赞同表中存在一条记录,用户、答案。
赞同数量由答案赞同表统计出来。
要考虑你的幂等的全局性:空间全局性和时间全局性。
空间全局性:比如是交易流水幂等还是用户ID幂等。是某种类型交易流水幂等,还是某个人|机构|渠道的交易流水幂等
时间全局性:是幂等几秒,还是几分钟,还是永远。
不同的要求,可以有不一样的解决方案、难度和成本。
对时间全局性要求高的,可能就必须选择DB这种持久化方案比较可靠,但是性能不够好啊(然后就要考虑loadmemory,以及数据同步的问题,就一步还要考虑实时性要求了)
在空间的要求中,根据不同的幂等范围,可以考虑分布式数据库(分布式集群全局流水号幂等)。还是某种少量数据幂等(可能只需要单台,做好主备)。
重复消息是SOA服务实现中非常常见的问题,你永远不要指望调用方每次请求消息不一样,对于读操作,重复消息可能无害,可对于写操作很可能就是灾难。
可以通过幂等(Idempotent)模式处理重复的消息,基本处理思路是:
1、调用者给消息一个唯一请求ID标识。ID标识一个工作单元,这个工作单元只应执行一次,工作单元ID可以是Schema的一部分,也可以是一个定制的SOAP Header,服务的Contract 可以说明这个唯一请求ID标识是必须的;
2、接收者在执行一个工作单元必须先检验该工作单元是否已经执行过。检查是否执行的逻辑通常是根据唯一请求ID ,在服务端查询请求是否有记录,是否有对应的响应信息,如果有,直接把响应信息查询后返回;如果没有,那么就当做新请求去处理。
幂等性我看到要分两种来讨论,一种是同步执行,就是两个同样的task允许同时执行。一种是顺序执行,就是俩同样的task不允许同时执行,但是一个执行完了再执行另一个是可以的。
不过不管哪种,这种事情最好是让产生副作用的那货自己处理。。。比如你的task是删东西,个么重复删几次应该么事。如果是生产东西,看看生产的那玩意能不能自己判重之类的。
实在不行的话就得找个啥玩意给你做同步了。
对于不要求同时执行的,现在有那种zookeeper之类的分布式锁,但是得有ttl,以及随之而来的一大滩麻烦。。数据库是个不错的地方,不过要看你的scale……scale没问题的话就用数据库吧。
对于要求可以同时执行的,可以选择在合适的地方把重复的task清理掉。。。就相当于重复执行了,反正是幂等的
接口幂等性,只要保证接口内的逻辑不涉及接口外的对象状态累积或变迁即可。