Redis做消息队列
在一个程序中存储一个数据
java
/**
* @description 文字转语音指令下发至队列
* @author xuwz
* @date 2023/12/26 19:46
*/
@Override
public void sendCmd1ByQueue(SlalarmCmdParam param, TextToSpeedCmd cmd) {
BwtQueueCmd1 queueCmd = new BwtQueueCmd1();
queueCmd.setParam(param);
queueCmd.setCmd(cmd);
JSONObject cmdJo = new JSONObject();
cmdJo.put("cmdType", 1);
cmdJo.put("cmdContent", queueCmd);
redisUtil.strLeftPush(RedisKey.BWT_CMD_QUEUE, cmdJo, TimeUnit.HOURS.toMillis(1));
}
java
/**
* @description leftPush
* @author xuwz
* @date 2023/3/3 14:08
*/
public boolean strLeftPush(final String key, final Object value, final long time) {
try {
stringRedisTemplate.opsForList().leftPush(encodeKey(key), MicrovideoJsonUtil.toJSONString(value));
if (time > 0) {
expire(key, time);
}
return true;
} catch (final Exception e) {
log.error(MicrovideoStringUtil.EMPTY, e);
return false;
}
}
/**
* @description rightPop
* @author xuwz
* @date 2023/3/3 14:13
*/
public String strRigthPop(final String key) {
try {
return stringRedisTemplate.opsForList().rightPop(encodeKey(key));
} catch (Exception e) {
log.error(MicrovideoStringUtil.EMPTY, e);
return null;
}
}
redis方法使用描述
stringRedisTemplate.opsForList().leftPush 是 Spring Data Redis 提供的一个方法,用于在 Redis 列表的左侧(即列表的开始)插入一个元素。
在 Redis 中,列表(List)是一种有序集合,支持从两端插入或弹出元素。leftPush 方法将一个元素推送到列表的左边,即在列表的开头添加这个元素。如果列表不存在,Redis 会自动创建一个新的列表。
存储数据以后,通过定时任务来弹出存储的元素。
相关方法
rightPush: 将元素推送到列表的右侧(即列表的末尾)。
leftPop: 从列表的左侧弹出一个元素。
rightPop: 从列表的右侧弹出一个元素。
注意事项
如果列表的名称(例如 myList)已经存在,leftPush 会将新元素添加到现有列表的开头。
如果列表不存在,leftPush 会创建一个新的列表并将元素推送进去。
通过这些操作,你可以在 Redis 列表中高效地插入和删除元素,满足多种数据处理需求。
通过定时任务去弹出数据,并操作
java
@Slf4j
@Component
public class BwtSlaCmdHandleTimer {
@Resource
private MicrovideoCommRedisRepository redisUtil;
@Resource
private ISlaStdCmdHandleService slaStdCmdHandleService;
@Value("${BWTslalarmCmdUrl}")
private String bwtSlalarmCmdUrl;
@PostConstruct
public void init() {
try {
InitC initC = new InitC();
Thread thread = new Thread(initC);
thread.start();
} catch (Exception e) {
log.error("", e);
}
}
private class InitC implements Runnable {
@Override
public void run() {
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
log.error("", e);
}
log.info("start bwtSlaCmdHandle timer task...");
Timer timer = new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
cmdHandle();
}
}, 1000, 1000);
}
}
private void cmdHandle() {
try {
String cmdStr = redisUtil.strRigthPop(RedisKey.BWT_CMD_QUEUE);
if (StringUtils.isEmpty(cmdStr)) {
return;
}
JSONObject cmdJo = JSONObject.parseObject(cmdStr);
Integer cmdType = cmdJo.getInteger("cmdType");
String cmdContent = cmdJo.getString("cmdContent");
if (cmdType.equals(1)) {
// 指令类型为文字转语音
BwtQueueCmd1 queueCmd = JSONObject.parseObject(cmdContent, BwtQueueCmd1.class);
slaStdCmdHandleService.sendTextToSpeedCmd(queueCmd.getParam(), queueCmd.getCmd());
} else if (cmdType.equals(2)) {
// 指令类型为设备停止
BwtQueueCmd2 queueCmd = JSONObject.parseObject(cmdContent, BwtQueueCmd2.class);
slaStdCmdHandleService.sendStopCmdByEqId(bwtSlalarmCmdUrl, queueCmd.getTaskId(),
queueCmd.getEventId(), queueCmd.getEqId());
} else {
log.warn("未知指令类型");
}
} catch (Exception e) {
log.error("", e);
}
}
}
解释
timer.schedule(...): Timer 类的 schedule 方法用于安排一个任务(TimerTask)在指定的时间执行。
new TimerTask() { ... }: 创建一个匿名内部类,继承自 TimerTask,并重写了 run 方法。TimerTask 是一个抽象类,用于定义你要执行的任务。
@Override public void run() { cmdHandle(); }: 重写 TimerTask 类的 run 方法,这个方法包含了你希望在定时任务中执行的代码。这里的 cmdHandle() 是你定义的一个方法,会在每次任务执行时被调用。
1000 (首次延迟): 任务开始执行的初始延迟时间,单位是毫秒。在这里,1000 毫秒意味着任务会在 1 秒后开始第一次执行。
1000 (周期性间隔): 任务执行的周期间隔时间,单位是毫秒。在这里,1000 毫秒意味着任务会每隔 1 秒执行一次。
总结
这段代码的作用是安排一个定时任务 cmdHandle()。它会在 1 秒钟(1000 毫秒)后第一次执行,然后每隔 1 秒钟再次执行一次。具体的执行过程是:
在任务开始之前等待 1 秒钟(首次延迟)。