1. 背景介绍
本人参与过国内两家大银行的系统开发,其中参与最多的是批量任务,虽然两个行的批量架构有所不同,但有一点相同的是它们都依赖其它组件,比如依赖调度,依赖MQ等等。
这样做的好处明显,符合架构设计中的职责单一的原则,但是也引来一些问题,比如:
1.单点故障导致服务不可用;
2.执行节点故障转移后原节点状态未知导致最终处理结果有误;
根本原因是什么?
1.虽然是分布式架构,但架构属于中心化架构,中心区组件的不可用会导致整个系统不可用。
2.故障转移的根本原因除了代码问题还有就是参数设置不合理,设置了过多的线程数或者过多的pageSize导致CPU、内存负载过高,或者机器配置本身就不行。
如下图:
2.解决方案
如何解决这些问题呢?伴随着区块链的出现,参考区块链去中心化的设计思想,我们可以设计一个去中心化的调度系统。
ElasticJob等其它调度系统虽然号称是去中心化,但是仔细观察会发现,他的节点并不是像比特币矿机那样完全独立,依然依赖其它组件。
而我们设计的是一个完全去中心化的调度系统,命名为tiger,类似独行的老虎。
那么理想中的调度系统是什么样的呢?我的想法是:
1.应用依赖tiger的jar包,jar包中提供了完整的调度功能,包括通讯、共识、调度、监控、数据持久化等,
2.横向动态扩展只需要丢一个依赖tiger的应用jar包到新的服务器上,新服务器只需要有jdk环境即可自动实现动态扩展。
如下图:
3. Tiger模块组成
Tiger包含的模块如下:
下面琢一解释:
1. IOC,这里是自己实现的,模仿spring用极简的代码实现了一个轻量的IOC容器,启动速度超快。
2. 数据库,这里也是自己实现,本质就是操作执行节点机器上的文件做持久化,当然性能会差一点,这个后续可以去优化,因为场景单一,就是持久化tiger调度用的数据。
3. 日志,目前使用了logback,java自带的太难用,会有其它问题。
4. 定时任务,这块使用了quatz框架来做。
5. 通讯层,使用netty框架,tcp协议用来做各执行节点的通讯,http协议对外暴露接口,供控制台客户端调用,或者其它等三方系统调用。
6. 共识协调,这块是任务调度时执行节点接收到命令之后进行协调的模块,是否可以执行,或等一段时间再执行等等动作。以及聚合查询汇总等动作。
7. 任务调度,根据任务流图来发出指令顺序执行任务。
8. 智能调优,这一层的调优仅限于参数调优,代码调优还是得靠开发人员。对于线程数、分片数等根据机器资源以及前N次的使用情况做动态调整,既能充分利用资源,也能避免OOM或假死等。
9. 控制台,这里提供了一系列的接口来维护、查询,比如创建任务流,启动任务,实时监控等功能。因为在局域网,所以连任何一个执行节点都可以访问。
10. JAVA客户端,这种调度系统使用CS模式的客户端比较好,java开发的可以跨平台使用,不用考虑兼容各种浏览器,体验相对来说比较好。
4. 任务解决方案
tiger执行的任务是什么样的?任务流程图模型举例如下:
任务类型有两种分法
1. 定时执行任务、手工执行任务。
2. 单一任务,批量任务。
定时和手工的区别可以在控制台实现。单一任务简单,最难的是批量任务,所以下面重点讨论批量任务。
批量任务是什么?
不同于联机接口单条处理,而是通过批量的方式来处理一些数据。
数据输入源有:文件,网络,内存,数据库
数据输出源有:文件,网络,内存,数据库
整个处理过程就是输入输出的组合,比如:文件->数据库;文件->文件;文件->数据库->文件;数据库->网络 等等
tiger怎么去处理这些场景?思路是根据不同的场景设计不同的方案,不同的场景在真实项目中出现的概率不同,优先实现经常使用的场景。
以我的经验来看,按出现的概率从大到小是:
1. 数据库->数据库
2. 数据库->文件,文件->数据库
3. 数据库->网络
剩下的先不列了,这几个基本占了批量任务的80%了,根据二八定律,优先解决80%的问题。
首先场景最多的是: 数据库->数据库
对于这种场景,需要做数据分片,即每台执行节点处理一个分片的数据。
如图:
数据库->文件的这种场景,因为文件分散在各个执行节点上,所以需要做最后的合并。
文件->数据库这种场景,需要先做拆分,再操作数据库,如图
数据库->网络,这个场景一般是读数据库里的数据,然后调某个接口。处理方式如图,其中需要保证tiger有消息队列的功能。
5. 待解决的问题
当然,还有很多问题要解决,我知道的有如:
1. 故障转移
2. 重跑续跑
不知道的还有很多,任何一个新方案肯定会衍生出很多新问题来,后面一步一步去解决,反正大体方向是这样。
6. 设计原则
使用分片思想、MapReduce的思想。
使用去中心化去中间件化思想。
约定共识大于通讯共识,减少网络通讯,提高性能。
二八定律,功能的实现不做大而全,把主要的80%功能实现即可。
尽少依赖,尽量用纯JAVA实现,越轻量越好,少依赖其它的包。
7. 项目地址
项目地址如下,还在开发中,已跑通了一个小demo。
https://github.com/shaoyangdd/tigger
业余时间写的,这个难度确实有点大,写得我脑壳疼,如果你也对这个感兴趣,欢迎联系我一起开发。