PS:(由于实际情况,实现方式存在很多问题,只是简单分享),受到种种因素影响,目前正在改进实现方式。后面会继续分享改进版
大致流程如下:
- 不是微服务架构,是属于分布式的主备模式和异地双活的架构(四台后端服务器),共享存储,共享数据库,oracle为三个实例,区分相关实例模块。搜索使用solr.三节点,一主两从(solr为1T内存,直接挂载内存盘),目前正在新加六台服务器来增加效率,由solr5.5.3升级到solr7.2.1过程中
- 由于solr更新,和系统存在很多文件导出和相对耗时的业务,都需要用到异步任务进行处理,故而有了自定义的线程池和异步任务的实现。
- 系统的异步任务实现和java中的实现大致思路一致,有所区别。
- 服务端是多节点部署,存在一张server表(server_id),区别不同服务节点,也是决定异步任务由那台机器执行的重要信息,多节点同时配置开启异步任务即可
- 在多节点部署后,启动服务时,都会在spring的初始化操作中,去决定由哪台节点来执行异步任务,这里的实现是用到一张lock表。
- Lock用的是java的Timer每15秒进行一次心跳检测,执行完异步任务或服务异常退出都会有释放锁是为了允许其他节点进行锁的争抢,用以一定程度均衡服务器的资源。
- 这里的锁,锁的是执行任务的服务器节点,而不是正常理解的锁任务。
- 在启动后,根据bean.xml中配置的线程池信息进行实例化线程池
- 根据生产者和消费者进行灵活配置具体使用的线程池
- 和java线程池类似,也是有具体执行任务的类Worker用以执行具体任务,任务放在一个支持优先级的无界阻塞队列中,当队列执行过程中,锁所在服务器一直持有锁,会定时续租,同样更新锁到期时间(每次续租时间为8秒)
- 除了该异步任务的执行方式后,也支持自定义回调,是通过初始化时,将生产者和对应消费者(执行者)存放到map缓存,通过具体实现和抽象类来进行调用(通过Tsak顶级接口和多继承封装来进一步实现)。
下面放一下经过模糊处理的关键实现和代码分享(如有相关不合理处,请联系我,我会及时删除)