Skip to content
jason edited this page Jan 2, 2019 · 1 revision

FAQ

同一个jvm中,不同线程之间如何防止任务被重复执行?一个scheduleServer的内部线程间如何进行任务分片?

  1. 数据分片是在不同的jvm,获知同一个jvm中不同的线程组间起作用。在同一个线程组内的10个线程,是通过一个同步的任务队列来实现的。
  2. 每个线程从队列中取任务执行,如果没有任务了,则由一个线程负责调用selectTasks方法再获取一批新的任务。

任务项设置的意义和selectTasks方法的参数含义

  1. 任务项(0,1,2,3,4,5,6,7,8,9)就是任务分片的策略。这个配置就是把数据分成10片。可以表示 ID的最后一位,也可以是一个独立的字段。根据你的业务来定。

  2. 如果只有1组线程,则所有的任务片都分配给他。这时selectTasks方法的参数:taskItemNum =10, queryCondition由10个元素,分别对应0,1,2,3,4,5,6,7,8,9。

  3. 如果只有2组线程,则任务片被分成两份。这时:

一个线程组的selectTasks方法的参数:taskItemNum =10, queryCondition有5个元素(0,2,4,6,8)
另外一个线程组的selectTasks方法的参数:taskItemNum =10, queryCondition有5个元素(1,3,5,7,9)

4、 如果有10个线程组。则每组线程只会获取到1个任务片。这时selectTasks方法的参数:taskItemNum =10, queryCondition只有一个元素,对应0到9中的一个。

执行期间和时间的修改功能

a) 在创建任务和修改任务的时候,有两个属性(执行开始时间,执行结算时间)用于控制任务的执行时间。
b) 时间格式遵循标准的cron格式 http://dogstar.javaeye.com/blog/116130 还增强了原来不支持的倒数第几天的能力。
c) 当时间到底开始时间的时候,就开始执行任务,到达结束时间则终止调度(不管是否所有的任务都处理完)。如果没有设置执行结束时间。则一直运行,直到selectTasks返回的记录数为0,就终止执行。等待下个开始运行时间在启动。 d) 如果要动态修改任务的执行时间区间,则先 点击“暂停”按钮,等所有的服务器都停止完毕(大概需要几秒时间)。当再次单击任务,出现如下情形表示停止完毕。然后修改执行开始时间,执行结算时间。在恢复任务调度,就可以实现调度时间的修改

任务处理的问题

a) Schedule主要是提供任务调度的分配管理。每一个任务是否执行成功,是通过业务方的bean来实现的。
b) 你需求的例子,我理解的解决方案如下:

i. 你从云梯拉下来100万数据放到保险应用的数据库中。这个表中有两个关键字段USER_ID和STS(状态 0-未发送,1-已发送)
ii. 在bean的selectTasks方法的查询sql中除了根据任务进行分片外,还需要增加状态条件。例如 USER_ID % 10 in( ?,?,?) AND sts =0 iii. 在bean的execute方法中,在发送完消息后,你还需要 修改数据状态 update table STS =1 where USER_ID =? 。这样下次就不会取到这条数据了。
iv. 这样就可以保障机器重新启动后,也不会出现问题。你可以参考DBDemoSingle.java的实现模式。你使用的接口应该是IScheduleTaskDealSingle。 如果旺旺的接口支持批量发送消息的时候,你才需要使用IScheduleTaskDealMulti接口。