一般的协调工作,让zookeeper来做那是最好的,问题是你得部署zookeeper。如果没有能否模拟一个协调者呢?这是本篇文章需要介绍的内容。
背景
有合同约定,如果总消费额达到一定的额度,需要启动折扣,达到另一个更高的额度后,会启动另一个折扣。用户的消费记录都是小额的,如1毛一笔,折扣需要详细到每一笔交易。现在已经有了很大批量的这种数据,需要计算总价。应用部署了3台机器,如何让3台机器都可以参与处理,并且一个合同的消费数据只能由一台机器处理,并且,如果这台机器处理了合同的部分数据死掉后,需要有其他的机器继续处理?
在这里,使用数据库作为协调器,协调各机器间的状态,详细介绍如下:
1、约定心跳时间为1分钟
2、创建调度任务表
字段 |
说明 |
任务类型 |
这里对应批价合同ID,唯一ID |
最近更新时间 |
|
版本号 |
或者时间戳,一个意思 |
3、每台机器启动一个心跳线程,线程找到一条最近1分钟(心跳时间单位)内没有更新过的任务记录(更新时间与当前时间差大于1分钟)
4、更新这条记录,执行sql:update 任务表 set 最近更新时间=系统时间,版本号=Step3查询出来的版本号+1 where 任务类型=查询出来的任务类型 and 版本号=Step3查询出来的版本号
5、判断执行结果,如果更新成功(sql影响行数=1)则意味着该机器可以开始执行该任务,否则就意味着该任务被其他的机器抢占了。
进一步优化:
Step4中只执行了一个心跳既认可任务处理权,可以多几个心跳时间,如3个,10个等成功更新后,再确认拥有处理权,再开始处理。
分析思路:
1、部署的3台机器之间没有联系,因此要实现相互协调,必须有一个中间协调器。
2、协调2钟,主动和被动,①三台服务器被动接受协调器的协调结果,目前没有;②三台服务器主动询问某共享资源,这里用的是数据库。
3、借鉴了数据库并发处理的特征,就是那个版本号,这个非常重要。