消息队列是应用中常用的一个技术点,通常我们可以借助消息队列中间件来实现,但是并不是所有的情况下,都需要使用到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实现延迟消息队列相关推荐

  1. redis延迟队列 实现_php使用redis的有序集合zset实现延迟队列

    延迟队列就是个带延迟功能的消息队列,相对于普通队列,它可以在指定时间消费掉消息. 延迟队列的应用场景: 1.新用户注册,10分钟后发送邮件或站内信. 2.用户下单后,30分钟未支付,订单自动作废. 我 ...

  2. 【springboot】【redis】springboot+redis实现发布订阅功能,实现redis的消息队列的功能...

    springboot+redis实现发布订阅功能,实现redis的消息队列的功能 参考:https://www.cnblogs.com/cx987514451/p/9529611.html 思考一个问 ...

  3. redis实现轮询算法_用redis实现支持优先级的消息队列

    为什么需要消息队列 系统中引入消息队列机制是对系统一个非常大的改善.例如一个web系统中,用户做了某项操作后需要发送邮件通知到用户邮箱中.你可以使用同步方式让用户等待邮件发送完成后反馈给用户,但是这样 ...

  4. php redis消息队列用哪种好,phpredis提高消息队列的实时性方法(推荐)

    搜索热词 数据库存贮都用list形式 要存2个队列 1个用作消息队列保存到数据 还有个 就是用来实时读取数据在redis $redis->lpush($queenkey,json_encode( ...

  5. python redis 消息队列_python中利用redis构建任务队列(queue)

    Python中的使用标准queue模块就可以建立多进程使用的队列,但是使用redis和redis-queue(rq)模块使这一操作更加简单. Part 1. 比如首先我们使用队列来简单的储存数据:我们 ...

  6. SpringBoot整合RabbitMQ 消息可靠投递、手动ack、延迟队列、死信队列、消息幂等性保障、消息积压

    1.消息可靠投递 在使用 RabbitMQ 的时候,作为消息发送方希望杜绝任何消息丢失或者投递失败场景.RabbitMQ 为我们提供了两种方式用来控制消息的投递可靠性模式. confirm 确认模式 ...

  7. thinkphp6实现redis连接池_详解thinkphp+redis+队列的实现代码

    1,安装Redis,根据自己的PHP版本安装对应的redis扩展(此步骤简单的描述一下) 1.1,安装 php_igbinary.dll,php_redis.dll扩展此处需要注意你的php版本如图: ...

  8. Redis系列教程(二):详解Redis的存储类型、集群架构、以及应用场景

    高并发架构系列 高并发架构系列:数据库主从同步的3种一致性方案实现,及优劣比较 高并发架构系列:Spring Cloud的核心成员.以及架构实现详细介绍 高并发架构系列:服务注册与发现的实现原理.及实 ...

  9. zincrby redis python_【Redis数据结构 序】使用redis-py操作Redis数据库

    想要看更加舒服的排版.更加准时的推送 关注公众号"不太灵光的程序员" 每日八点有干货推送 同时发布<[Redis数据结构 1序]1使用redis-py操作Redis数据库&g ...

最新文章

  1. 电大计算机考试打开画图程序,最新国家开放大学电大《计算机绘图》形考任务网考试题及答案.pdf...
  2. 浅析网站结构如何开启优化工作
  3. 静态网页制作html语言入门
  4. python网站开发实例视频_Python实战-让在职教育类网站的视频全自动播放
  5. linux如何设置浏览器,如何从 命令行 设置默认浏览器?
  6. ASP.NET Core 3.0:将会拥有更少的依赖
  7. flowable实战(八)flowable核心数据库表详细表字段说明
  8. C语言答案杨崇艳,贯彻落实科学发展观,走新型工业化道路的要求是()。A.科技含量高B.经济效益好...
  9. 迅捷cad_迅捷套装
  10. 以 Google 为例,什么才是好的管理制度?
  11. PHP中字符串类型与数值类型混合计算
  12. 带本信息论看《三体》——信息论课程论文
  13. Supervised Contrastive Learning:有监督对比学习
  14. Smart V3触摸屏与S7-200Smart PLC实现时间同步的具体方法
  15. 数据结构线性表(C++ )
  16. lgv50进入工程模式_LG手机工程模式进入方法及菜单常用指令
  17. 如何将手机中Word文档转换成PDF
  18. 关于Muster 5.5.7的奇怪问题
  19. 对DHCP客户端创建黑名单或白名单
  20. Android手机不同频率的听力测试功能实现

热门文章

  1. 测试keras和mxnet的速度
  2. pyqt QGridLayout示例
  3. python二分法查找
  4. Max-Flow Min-Cut
  5. OpenCV霍夫变换:霍夫线变换,霍夫圆变换合辑
  6. Opencv卷积滤波cvFilter2D-高通与低通
  7. 60 Celery队列
  8. 一文带你学会国产加密算法SM4的vue实现方案
  9. freemarker中js里面取字符串,换行导致报错的解决办法
  10. Maven入门教程(一)