背景
在我们的系统中,有些时候需要用到一些延迟任务,比如我们的系统A依赖于另外一个系统B,只有这两个系统建立连接后,才能进行业务操作。 系统A把一些策略运行所需的参数、环境、指标数据发给B, B进行策略服务运行,获取结果后通知系统A。 系统A在与系统B建立连接后首先发送一些基础的系统参数,然后才可以发送正常的业务数据。 所以要求我们在两个系统建立连接成功后,稍微延迟一点时间发送系统参数。 其中原因是:系统建立成功后,系统A立即发送参数,系统B有时候会收不到,因为系统连接基于tcp建立连接后进行一些认证、初始化环境操作,所以tcp连接成功后,业务系统的环境还没有准备好。 因此我们需要引入一个延迟任务调度服务,在监听到连接成功后, 创建一个延迟任务,放入队列里面,然后进行调度运行。
因为对延迟任务调度队列要求很简单,不需要做故障恢复、数据持久等安全性保障,所以就引入了单机版的任务调度服务实现。 我们第一版本基于java提供的DelayQueue实现,后续有第二版本支持任务持久化、故障恢复、分布式等操作。 本文先介绍基于DelayQueue怎么实现一个延迟任务调度服务。
实现
首先定义一个抽象延迟任务类AbstractDelayedTask, 具体要实现的延迟任务通过继承该类就可以被调度。
延迟调度服务实现类DelayScheduleService, 该类通过DelayQueue实现延迟任务的调度运行。
用例
在springMvc里面直接声明一个bean对象,如下:
特别需要注意的是:配置该bean的3个属性,如下:
init-method="init"
destroy-method="shutdown"
scope="singleton"
声明一个延迟任务实现类
该任务类继承AbstractDelayedTask,实现其抽象方法process()
在需要的地方,把该延迟任务放入到队列里面去,如下:
logger.info("=======>scenarioDiscoveryStatus==== 已连接交易系统");
//加入延迟任务,默认10s,具体可以在实现类里面定制,也可以通过构造函数指定
delayScheduleService.put(new DelaySendControlRuleTask(controlRuleConfigService));
这样就完成了一个延迟任务调度服务了,使用非常简单。
缺点
第一版本实现的比较简陋, 时间精度不细致、不支持故障恢复、 不支持数据持久化、不支持分布式,适用于系统对延迟要求比较低,任务延迟精度低的场景下使用。 其他场景须慎用。
领取专属 10元无门槛券
私享最新 技术干货