redis mysql 生成序列_spring+redis+mysql定时重发

产品需求:发布信息时候,用户可以选择重新发布时间,重新发布间隔时间以及次数,如重发6次时间间隔为2分钟。

实现设计:

可以通过定时查询数据库的发布时间,以及信息中重发次数时间,update数据(或者直接写一个厉害的update语句也可以),但是定时的查询整个数据库表,而且中间还会涉及到运算,无法命中索引,会使数据库压力较大,咨询好多朋友,大多数建议降低数据查询次数,如半个小时update一次,但是这样时间误差会很大,产品无法接受。

在通过仔细调研以之后,计算使用spring定时任务、redis中list结构、update数据实现。当用户发布信息的时候,依据次数生成多个序列的key,并将信息id存储到redis中(如果多个信息,在同一个序列中,直接在list尾部添加数据),spring通过定时任务,每隔10秒依据生成的序列,读取redis中list数据,将list中数据,转化为id1,id2,id3,通过数据库in关键字,实现更新数据。

关键代码:

spring定时任务配置

public classRepublishCargoJob {private Log log = LogFactory.getLog(RepublishCargoJob.class);/*** 货源重发定时任务*/

public voiddoRepublish(){//获取WebApplicationContext

WebApplicationContext wac =ContextLoader.getCurrentWebApplicationContext();//获取redis读取序列工具

TimedPublishTask timedPublishTask=(TimedPublishTask) wac.getBean("timedPublishTask");//获取本次需要更新的id list

Listlist=timedPublishTask.getBatch();if(list!=null&&list.size()>0){//update数据库

ResourceCargoInfoDAO resourceCargoInfoDAO=(ResourceCargoInfoDAO) wac.getBean("resourceCargoInfoDAO");

ResourceCargoInfo rci=newResourceCargoInfo();

rci.setRciPublishDatetime(DateUtils.getDateTime());

ResourceCargoInfoExample resourceCargoInfoExample=newResourceCargoInfoExample();

resourceCargoInfoExample.createCriteria().andRciIdIn(list).andRciAvalibleStatusEqualTo(1);try{

resourceCargoInfoDAO.updateByExampleSelective(rci, resourceCargoInfoExample);

}catch(SQLException e) {//TODO Auto-generated catch block

e.printStackTrace();

log.error("=======重发货源失败======");

}

}

}

packagecom.ada.wuliu.common.redis.timertask;importjava.util.ArrayList;importjava.util.List;importjavax.annotation.Resource;importorg.apache.commons.logging.Log;importorg.apache.commons.logging.LogFactory;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.data.redis.connection.jedis.JedisConnection;importorg.springframework.data.redis.connection.jedis.JedisConnectionFactory;importorg.springframework.stereotype.Component;importorg.springframework.web.bind.annotation.InitBinder;importcom.ada.wuliu.common.dictionaries.utils.DateUtils;importcom.ada.wuliu.common.dictionaries.utils.StateCode;importcom.ada.wuliu.common.dto.result.SimpleResult;importcom.ada.wuliu.common.redis.dao.RedisList;importcom.ada.wuliu.common.redis.dao.RedisString;importcom.ada.wuliu.common.redis.dto.TimerPublish;importcom.ada.wuliu.common.redis.util.SessionImpl_Temp_01;importcom.ada.wuliu.common.redis.util.StringUtil;

@Component("timedPublishTask")public classTimedPublishTask {//定时任务执行周期

public Integer taskFrequency=10000;//默认任务开始\(^o^)/

private String defaultIncr="1000";private static String TIMER_PUBLISH_KEY_TODO=null;

@AutowiredprivateRedisList redisList;

@AutowiredprivateRedisString redisString;private final static Log log = LogFactory.getLog(TimedPublishTask.class);

@Resource(name="connectionFactory")privateJedisConnectionFactory connectionFactory;publicTimedPublishTask(){

initKeyHeader();

}private voidinitKeyHeader(){if(TIMER_PUBLISH_KEY_TODO==null){

TIMER_PUBLISH_KEY_TODO="TIMER_PUBLISH_KEY_TODO_CYC_"+StringUtil.getLocalOsName();

}

}/***

*@paramtimerPublish 需要重新发布的对象*/

publicSimpleResult addBatch(TimerPublish timerPublish){

JedisConnection connection=connectionFactory.getConnection();

SimpleResult cr= null;try{//获取最新的批次号

String batchNo=redisString.get(TIMER_PUBLISH_KEY_TODO, connection);if(batchNo==null){

batchNo=redisString.incr(TIMER_PUBLISH_KEY_TODO, connection).toString();

}//刷新频率

Integer frequency=timerPublish.getFrequency()/10;//刷新次数

Integer number=timerPublish.getNumber();//对象key

Long key=timerPublish.getKey();

Listlist=new ArrayList();for(int i=1;i

long addBatchNo=i*frequency/taskFrequency+Long.parseLong(batchNo);

addBatchNo=addBatchNo-1;

String batchKey=TIMER_PUBLISH_KEY_TODO+addBatchNo;//list 第一个为更新时间 如果更新时间

log.info("新添加批次号:======"+batchKey+"====="+key);

List ll=redisList.get(batchKey, 1, 2, connection);if(ll==null||ll.size()==0){

redisList.lPush(batchKey, (System.currentTimeMillis()+i*frequency)+"", connection);

}

redisList.rPush(batchKey, key+"", connection);

}return new SimpleResult("成功", StateCode.SUCCESS, StateCode.SUCCESS, true);

}catch(Exception e) {

log.error("-----TimedPublishTask::addBatch Throwable Error! -----", e);return new SimpleResult("服务器错误", StateCode.SERVER_ERROR, null, false);

}catch(Throwable th) {

log.error("-----TimedPublishTask::addBatch Throwable Error! -----", th);return new SimpleResult("服务器错误", StateCode.SERVER_ERROR, null, false);

}finally{

connection.close();

}

}/***

*@parambatchNo 获取本批次需要更新的对象的key

*@return

*/

public ListgetBatch(){

JedisConnection connection=connectionFactory.getConnection();

SimpleResult cr= null;try{//获取当前需要更新的批次号

String batchNo=redisString.get(TIMER_PUBLISH_KEY_TODO, connection);//如果没有批次则初始化批次

if(batchNo==null){

batchNo=redisString.incr(TIMER_PUBLISH_KEY_TODO, connection).toString();

}

Listlist=redisList.getAll(TIMER_PUBLISH_KEY_TODO+batchNo, connection);

log.info("当前任务"+TIMER_PUBLISH_KEY_TODO+batchNo);//出现掉任务处理

if(list!=null&&list.size()>0){

Long addTime=Long.parseLong(list.get(0));

Long nowTime=System.currentTimeMillis();if(nowTime-addTime>2*taskFrequency){

log.info("发现队列冗余数据,开始尝试执行=========");//获取偏移量

long offset=(nowTime-addTime)/taskFrequency+1;

log.info("偏移量======"+offset);

Integer batchNoRe=Integer.parseInt(batchNo);int i=1;if(offset<50){ i=1;}else{i=(int) (offset-50L);}for(;i

batchNoRe++;

log.info("添加任务"+TIMER_PUBLISH_KEY_TODO+batchNoRe);

Listlistre=redisList.getAll(TIMER_PUBLISH_KEY_TODO+batchNoRe, connection);if(listre.size()>0) listre.remove(0);

redisString.del(TIMER_PUBLISH_KEY_TODO+batchNoRe, connection);

redisString.incr(TIMER_PUBLISH_KEY_TODO, connection);//redisString.incr(TIMER_PUBLISH_KEY_TODO, connection);

list.addAll(listre);

}

}

}if(list.size()>0) list.remove(0);

log.info("执行批次==========="+TIMER_PUBLISH_KEY_TODO+batchNo+"======VALUES====="+getListStr(list));

redisString.incr(TIMER_PUBLISH_KEY_TODO, connection);

redisString.del(TIMER_PUBLISH_KEY_TODO+batchNo, connection);returnlist;

}catch(Exception e) {

e.printStackTrace();

log.error("-----TimedPublishTask::getBatch Throwable Error! -----", e);return null;

}catch(Throwable th) {

log.error("-----TimedPublishTask::getBatch Throwable Error! -----", th);return null;

}finally{

connection.close();

}

}public String getListStr(Listlist){if(list==null)return null;

StringBuffer sb=newStringBuffer();for(String s:list){

sb.append(s+",");

}returnsb.toString();

}

}

初始化批次15秒执行一次,需要执行10次

新添加批次号:======TIMER_PUBLISH_KEY_TODO_KTSDKLHL1=====114102091

新添加批次号:======TIMER_PUBLISH_KEY_TODO_KTSDKLHL3=====114102091

新添加批次号:======TIMER_PUBLISH_KEY_TODO_KTSDKLHL4=====114102091

新添加批次号:======TIMER_PUBLISH_KEY_TODO_KTSDKLHL6=====114102091

新添加批次号:======TIMER_PUBLISH_KEY_TODO_KTSDKLHL7=====114102091

新添加批次号:======TIMER_PUBLISH_KEY_TODO_KTSDKLHL9=====114102091

新添加批次号:======TIMER_PUBLISH_KEY_TODO_KTSDKLHL10=====114102091

新添加批次号:======TIMER_PUBLISH_KEY_TODO_KTSDKLHL12=====114102091

新添加批次号:======TIMER_PUBLISH_KEY_TODO_KTSDKLHL13=====114102091

新添加批次号:======TIMER_PUBLISH_KEY_TODO_KTSDKLHL15=====114102091

初始化批次15秒执行一次,需要执行10次

新添加批次号:======TIMER_PUBLISH_KEY_TODO_KTSDKLHL1=====114102095

新添加批次号:======TIMER_PUBLISH_KEY_TODO_KTSDKLHL3=====114102095

新添加批次号:======TIMER_PUBLISH_KEY_TODO_KTSDKLHL4=====114102095

新添加批次号:======TIMER_PUBLISH_KEY_TODO_KTSDKLHL6=====114102095

新添加批次号:======TIMER_PUBLISH_KEY_TODO_KTSDKLHL7=====114102095

新添加批次号:======TIMER_PUBLISH_KEY_TODO_KTSDKLHL9=====114102095

新添加批次号:======TIMER_PUBLISH_KEY_TODO_KTSDKLHL10=====114102095

新添加批次号:======TIMER_PUBLISH_KEY_TODO_KTSDKLHL12=====114102095

新添加批次号:======TIMER_PUBLISH_KEY_TODO_KTSDKLHL13=====114102095

新添加批次号:======TIMER_PUBLISH_KEY_TODO_KTSDKLHL15=====114102095

当前任务TIMER_PUBLISH_KEY_TODO_KTSDKLHLSK1

发现队列冗余数据,开始尝试执行=========

偏移量======5

添加任务TIMER_PUBLISH_KEY_TODO_KTSDKLHLSK2

添加任务TIMER_PUBLISH_KEY_TODO_KTSDKLHLSK3

添加任务TIMER_PUBLISH_KEY_TODO_KTSDKLHLSK4

添加任务TIMER_PUBLISH_KEY_TODO_KTSDKLHLSK5

执行批次===========TIMER_PUBLISH_KEY_TODO_KTSDKLHLSK6======VALUES=====114102091,114102095,

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值