redis延迟消息队列不准时php,Redis实现延迟消息队列
消息队列是应用中常用的一个技术点,通常我们可以借助消息队列中间件来实现,但是并不是所有的情况下,都需要使用到MQ。
如果只需要实现简单的消息队列,那么借助Redis即可。
如果对消息有着严格的可靠性等要求,那么建议使用专业的MQ.(RocketMQ,Kafka,RabbitMQ)‘
Redis实现延迟消息队列的思想
可以借助zset有序集合来实现延迟消息队列。因为zset有一个score,它是可以按这个score来进行排序的,我们可以把时间戳作为zset的score,让它按时间去排序,然后在Java程序中使用轮询或者定时任务来消费里面的消息。这里使用的是点对点的消费模式。
以下是代码的展示.
第一步,先创建一个发送消息的对象
package com.xjm.redis;
public class RedisMessage {
private String id;
private Object message;
@Override
public String toString() {
return "RedisMessage{" +
"id='" + id + '\'' +
", message=" + message +
'}';
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public Object getMessage() {
return message;
}
public void setMessage(Object message) {
this.message = message;
}
}
第二步,引入序列化工具jackson
com.fasterxml.jackson.core
jackson-databind
2.10.3
第三步,编写一个消息队列的工具类,主要包含消息入队和消费功能
package com.xjm.redis;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import redis.clients.jedis.Jedis;
import java.util.Date;
import java.util.Set;
import java.util.UUID;
/**
* 延迟消息队列
*/
public class DelayMsgQueue {
private Jedis jedis;
private String queue;
public DelayMsgQueue(Jedis jedis, String queue) {
this.jedis = jedis;
this.queue = queue;
}
/**
* 消息入队,要发送的消息
* @param message
*/
public void queue(Object message){
RedisMessage redisMessage = new RedisMessage();
redisMessage.setId(UUID.randomUUID().toString());
redisMessage.setMessage(message);
try {
//序列化
String s = new ObjectMapper().writeValueAsString(redisMessage);
System.out.println("Redis发送消息:"+new Date());
//消息发送,score延迟5秒
jedis.zadd(queue,System.currentTimeMillis()+5000,s);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
}
/**
* 消息出队(消息消费)
*
*/
public void loop(){
/**
* 轮询,线程被中断时停止
*/
while (!Thread.interrupted()){
//读取score时间在0到当前时间戳的之间的消息,一次一条
Set message = jedis.zrangeByScore(queue, 0, System.currentTimeMillis(), 0, 1);
if (message.isEmpty()){
try {
//如果消息为空,则线程休眠一段时间
Thread.sleep(500);
} catch (InterruptedException e) {
break;
}
continue;
}
//如果读取到了消息,则直接加载
String next = message.iterator().next();
if(jedis.zrem(queue,next)>0){
//抢到了,接下来处理业务
try {
RedisMessage redisMessage = new ObjectMapper().readValue(next, RedisMessage.class);
System.out.println("抢到了!"+new Date());
System.out.println(redisMessage.toString());
} catch (JsonProcessingException e) {
e.printStackTrace();
}
}
}
}
}
第四步,测试
package com.xjm.redis;
public class DelayMsgTest {
public static void main(String[] args) {
Redis redis = new Redis();
redis.exeute(jedis -> {
//构造一个消息队列
DelayMsgQueue delayMsgQueue = new DelayMsgQueue(jedis, "jaymin-delay-queue");
Runnable producer = new Runnable() {
@Override
public void run() {
for (int i=0;i<5;i++){
delayMsgQueue.queue("Java>>>>>"+i);
}
}
};
Thread producerThread = new Thread(producer);
Runnable customer = new Runnable() {
@Override
public void run() {
delayMsgQueue.loop();
}
};
Thread customerThread = new Thread(customer);
producerThread.start();
customerThread.start();
try {
//休息7秒后,停止程序
Thread.sleep(7000);
customerThread.interrupt();
} catch (InterruptedException e) {
e.printStackTrace();
}
});
}
}
测试结果如下:
image.png
在此鸣谢@江南一点雨,感谢他的redis视频解析.
redis延迟消息队列不准时php,Redis实现延迟消息队列相关推荐
- redis延迟队列 实现_php使用redis的有序集合zset实现延迟队列
延迟队列就是个带延迟功能的消息队列,相对于普通队列,它可以在指定时间消费掉消息. 延迟队列的应用场景: 1.新用户注册,10分钟后发送邮件或站内信. 2.用户下单后,30分钟未支付,订单自动作废. 我 ...
- 【springboot】【redis】springboot+redis实现发布订阅功能,实现redis的消息队列的功能...
springboot+redis实现发布订阅功能,实现redis的消息队列的功能 参考:https://www.cnblogs.com/cx987514451/p/9529611.html 思考一个问 ...
- redis实现轮询算法_用redis实现支持优先级的消息队列
为什么需要消息队列 系统中引入消息队列机制是对系统一个非常大的改善.例如一个web系统中,用户做了某项操作后需要发送邮件通知到用户邮箱中.你可以使用同步方式让用户等待邮件发送完成后反馈给用户,但是这样 ...
- php redis消息队列用哪种好,phpredis提高消息队列的实时性方法(推荐)
搜索热词 数据库存贮都用list形式 要存2个队列 1个用作消息队列保存到数据 还有个 就是用来实时读取数据在redis $redis->lpush($queenkey,json_encode( ...
- python redis 消息队列_python中利用redis构建任务队列(queue)
Python中的使用标准queue模块就可以建立多进程使用的队列,但是使用redis和redis-queue(rq)模块使这一操作更加简单. Part 1. 比如首先我们使用队列来简单的储存数据:我们 ...
- SpringBoot整合RabbitMQ 消息可靠投递、手动ack、延迟队列、死信队列、消息幂等性保障、消息积压
1.消息可靠投递 在使用 RabbitMQ 的时候,作为消息发送方希望杜绝任何消息丢失或者投递失败场景.RabbitMQ 为我们提供了两种方式用来控制消息的投递可靠性模式. confirm 确认模式 ...
- thinkphp6实现redis连接池_详解thinkphp+redis+队列的实现代码
1,安装Redis,根据自己的PHP版本安装对应的redis扩展(此步骤简单的描述一下) 1.1,安装 php_igbinary.dll,php_redis.dll扩展此处需要注意你的php版本如图: ...
- Redis系列教程(二):详解Redis的存储类型、集群架构、以及应用场景
高并发架构系列 高并发架构系列:数据库主从同步的3种一致性方案实现,及优劣比较 高并发架构系列:Spring Cloud的核心成员.以及架构实现详细介绍 高并发架构系列:服务注册与发现的实现原理.及实 ...
- zincrby redis python_【Redis数据结构 序】使用redis-py操作Redis数据库
想要看更加舒服的排版.更加准时的推送 关注公众号"不太灵光的程序员" 每日八点有干货推送 同时发布<[Redis数据结构 1序]1使用redis-py操作Redis数据库&g ...
最新文章
- 电大计算机考试打开画图程序,最新国家开放大学电大《计算机绘图》形考任务网考试题及答案.pdf...
- 浅析网站结构如何开启优化工作
- 静态网页制作html语言入门
- python网站开发实例视频_Python实战-让在职教育类网站的视频全自动播放
- linux如何设置浏览器,如何从 命令行 设置默认浏览器?
- ASP.NET Core 3.0:将会拥有更少的依赖
- flowable实战(八)flowable核心数据库表详细表字段说明
- C语言答案杨崇艳,贯彻落实科学发展观,走新型工业化道路的要求是()。A.科技含量高B.经济效益好...
- 迅捷cad_迅捷套装
- 以 Google 为例,什么才是好的管理制度?
- PHP中字符串类型与数值类型混合计算
- 带本信息论看《三体》——信息论课程论文
- Supervised Contrastive Learning:有监督对比学习
- Smart V3触摸屏与S7-200Smart PLC实现时间同步的具体方法
- 数据结构线性表(C++ )
- lgv50进入工程模式_LG手机工程模式进入方法及菜单常用指令
- 如何将手机中Word文档转换成PDF
- 关于Muster 5.5.7的奇怪问题
- 对DHCP客户端创建黑名单或白名单
- Android手机不同频率的听力测试功能实现