Redis和RabbitMQ实现消息队列

AI权益加码!Claude Code、Cursor等20+工具免费用! 购周边限时加赠Coding Plan Lite,畅享主流AI工具!学习进阶更高效! 阅读详情

RabbitMQ简介

1什么是RabbitMQ?

RabbitMQ是实现AMQP(高级消息队列协议)的消息中间件的一种,最初起源于金融系统,用于在分布式系统中存储转发消息,在易用性、扩展性、高可用性等方面表现不俗。消息中间件主要用于组件之间的解耦,消息的发送者无需知道消息使用者的存在,反之亦然:


 

单向解耦


 

双向解耦(如:RPC)


    例如一个日志系统,很容易使用RabbitMQ简化工作量,一个Consumer可以进行消息的正常处理,另一个Consumer负责对消息进行日志记录,只要在程序中指定两个Consumer所监听的queue以相同的方式绑定到同一个exchange即可,剩下的消息分发工作由RabbitMQ完成。
 

 

使用RabbitMQ server需要:

1. ErLang语言包;

2. RabbitMQ安装包;

RabbitMQ同时提供了java的客户端(一个jar包)。

 

2      概念和特性

2.1      交换机(exchange):

1. 接收消息,转发消息到绑定的队列。四种类型:direct, topic, headers and fanout

direct:转发消息到routigKey指定的队列

topic:按规则转发消息(最灵活)

headers:(这个还没有接触到)

fanout:转发消息到所有绑定队列

2. 如果没有队列绑定在交换机上,则发送到该交换机上的消息会丢失。

3. 一个交换机可以绑定多个队列,一个队列可以被多个交换机绑定。

4. topic类型交换器通过模式匹配分析消息的routing-key属性。它将routing-key和binding-key的字符串切分成单词。这些单词之间用点隔开。它同样也会识别两个通配符:#匹配0个或者多个单词,*匹配一个单词。例如,binding key:*.stock.#匹配routing key:usd.stcok和eur.stock.db,但是不匹配stock.nana。

还有一些其他的交换器类型,如header、failover、system等,现在在当前的RabbitMQ版本中均未实现。

5. 因为交换器是命名实体,声明一个已经存在的交换器,但是试图赋予不同类型是会导致错误。客户端需要删除这个已经存在的交换器,然后重新声明并且赋予新的类型。

6. 交换器的属性:

- 持久性:如果启用,交换器将会在server重启前都有效。

- 自动删除:如果启用,那么交换器将会在其绑定的队列都被删除掉之后自动删除掉自身。

- 惰性:如果没有声明交换器,那么在执行到使用的时候会导致异常,并不会主动声明。

 

2.2      队列(queue):

1. 队列是RabbitMQ内部对象,存储消息。相同属性的queue可以重复定义。

2. 临时队列。channel.queueDeclare(),有时不需要指定队列的名字,并希望断开连接时删除队列。

3. 队列的属性:

- 持久性:如果启用,队列将会在server重启前都有效。

- 自动删除:如果启用,那么队列将会在所有的消费者停止使用之后自动删除掉自身。

- 惰性:如果没有声明队列,那么在执行到使用的时候会导致异常,并不会主动声明。

- 排他性:如果启用,队列只能被声明它的消费者使用。

这些性质可以用来创建例如排他和自删除的transient或者私有队列。这种队列将会在所有链接到它的客户端断开连接之后被自动删除掉。它们只是短暂地连接到server,但是可以用于实现例如RPC或者在AMQ上的对等通信。4. RPC的使用是这样的:RPC客户端声明一个回复队列,唯一命名(例如用UUID),并且是自删除和排他的。然后它发送请求给一些交换器,在消息的reply-to字段中包含了之前声明的回复队列的名字。RPC服务器将会回答这些请求,使用消息的reply-to作为routing key(默认绑定器会绑定所有的队列到默认交换器,名称为“amp.交换器类型名”)发送到默认交换器。注意这仅仅是惯例而已,可以根据和RPC服务器的约定,它可以解释消息的任何属性(甚至数据体)来决定回复给谁。

2.3      消息传递:

1. 消息在队列中保存,以轮询的方式将消息发送给监听消息队列的消费者,可以动态的增加消费者以提高消息的处理能力。

2. 为了实现负载均衡,可以在消费者端通知RabbitMQ,一个消息处理完之后才会接受下一个消息。

channel.basic_qos(prefetch_count=1)

注意:要防止如果所有的消费者都在处理中,则队列中的消息会累积的情况。

3. 消息有14个属性,最常用的几种:

deliveryMode:持久化属性

contentType:编码

replyTo:指定一个回调队列

correlationId:消息id


实例代码:


4. 消息生产者可以选择是否在消息被发送到交换器并且还未投递到队列(没有绑定器存在)和/或没有消费者能够立即处理的时候得到通知。通过设置消息的mandatory和/或immediate属性为真,这些投递保障机制的能力得到了强化。

5. 此外,一个生产者可以设置消息的persistent属性为真。这样一来,server将会尝试将这些消息存储在一个稳定的位置,直到server崩溃。当然,这些消息肯定不会被投递到非持久的队列中。

 

2.4      高可用性(HA):

1. 消息ACK,通知RabbitMQ消息已被处理,可以从内存删除。如果消费者因宕机或链接失败等原因没有发送ACK(不同于ActiveMQ,在RabbitMQ里,消息没有过期的概念),则RabbitMQ会将消息重新发送给其他监听在队列的下一个消费者。

channel.basicConsume(queuename, noAck=false, consumer);

2. 消息和队列的持久化。定义队列时可以指定队列的持久化属性(问:持久化队列如何删除?)

channel.queueDeclare(queuename, durable=true, false, false, null);

发送消息时可以指定消息持久化属性:

channel.basicPublish(exchangeName, routingKey,

            MessageProperties.PERSISTENT_TEXT_PLAIN,

            message.getBytes());

这样,即使RabbitMQ服务器重启,也不会丢失队列和消息。

3. publisher confirms

4. master/slave机制,配合Mirrored Queue,这种情况下,publisher会正常发送消息和接收消息的confirm,但对于subscriber来说,需要接收Consumer Cancellation Notifications来得到主节点失败的通知,然后re-consume from the queue,此时要求client有处理重复消息的能力。注意:如果queue在一个新加入的节点上增加了一个slave,此时slave上没有此前queue的信息(目前还没有同步机制)。

(通过命令行或管理插件可以查看哪个slave是同步的:

rabbitmqctl list_queues name slave_pids synchronised_slave_pids

    当一个slave重新加入mirrored-queue时,如果queue是durable的,则会被清空。

 

2.5      集群(cluster):

1. 不支持跨网段(如需支持,需要shovel或federation插件)

2. 可以随意的动态增加或减少、启动或停止节点,允许节点故障

3. 集群分为RAM节点和DISK节点,一个集群最好至少有一个DISK节点保存集群的状态。

4. 集群的配置可以通过命令行,也可以通过配置文件,命令行优先。

 

3      使用

3.1      简易使用流程


 

3.2      RabbitMQ在OpenStack中的使用



 

 

    在Openstack中,组件之间对RabbitMQ使用基本都是“Remote Procedure Calls”的方式。每一个Nova服务(比如计算服务、存储服务等)初始化时会创建两个队列,一个名为“NODE-TYPE.NODE-ID”,另一个名为“NODE-TYPE”,NODE-TYPE是指服务的类型,NODE-ID指节点名称。

    从抽象层面上讲,RabbitMQ的组件的使用类似于下图所示:



每个服务会绑定两个队列到同一个topic类型的exchange,从不同的队列中接收不同类型的消息。消息的发送者如果关心消息的返回值,则会监听另一个队列,该队列绑定在一个direct类型的exchange。接受者收到消息并处理后,会将消息的返回发送到此exchange。

Openstack中,如果不关心消息返回,消息的流程图如下:



 

    如果关心消息返回值,流程图如下:



 

 

3.3      为什么要使用RabbitMQ?

曾经有过一个人做过一个测试(http://www.cnblogs.com/amityat/archive/2011/08/31/2160293.html),发送1百万个并发消息,对性能有很高的需求,于是作者对比了RabbitMQ、MSMQ、ActiveMQ、ZeroMQueue,整个过程共产生1百万条1K的消息。测试的执行是在一个Windows Vista上进行的,测试结果如下:



    虽然ZeroMQ性能较高,但这个产品不提供消息持久化,需要自己实现审计和数据恢复,因此在易用性和HA上不是令人满意,通过测试结果可以看到,RabbitMQ的性能确实不错。

    我在本机也做了一些测试,但我的测试是基于组件的原生配置,没有做任何的配置优化,因此总觉的不靠谱。我只测试了RabbitMQ和ActiveMQ两款产品,虽然网上都说ActiveMQ性能不如前者,但平心而论,ActiveMQ提供了很多配置,存在很大的调优空间,也许修改一个配置参数就会使组件的性能有一个质的飞跃。


Redis简介

1      什么是Redis?

    REmote DIctionary Server(Redis) 是一种面向“键/值”对类型数据的分布式NoSQL数据库系统。Redis提供了一些丰富的数据结构,包括 lists, sets, ordered sets 以及 hashes ,当然还有和Memcached一样的 strings结构.Redis当然还包括了对这些数据结构的丰富操作。没有做任何的配置优化,包括 lists, sets, ordered sets 以及 hashes ,当然还有和Memcached一样的 strings结构.Redis当然还包括了对这些数据结构的丰富操作。   

   redis目前提供四种数据类型:string,list,set及zset(sorted set)。

  • string是最简单的类型,你可以理解成与Memcached一模一个的类型,一个key对应一个value,其上支持的操作与Memcached的操作类似。但它的功能更丰富。
  • list是一个链表结构,主要功能是push、pop、获取一个范围的所有值等等。操作中key理解为链表的名字。
  • set是集合,和我们数学中的集合概念相似,对集合的操作有添加删除元素,有对多个集合求交并差等操作。操作中key理解为集合的名字。
  • zset是set的一个升级版本,他在set的基础上增加了一个顺序属性,这一属性在添加修改元素的时候可以指定,每次指定后,zset会自动重新按新的值调整顺序。可以理解了有两列的mysql表,一列存value,一列存顺序。操作中key理解为zset的名字。

  

2      概述

  Redis通过定义一个 struct redisServer 类型的全局变量server 来保存服务器的相关信息(比如:配置信息,统计信息,服务器状态等等)。启动时通过读取配置文件里边的信息对server进行初始化(如果没有指定配置文件,将使用默认值对sever进行初始化),初始化的内容有:起监听端口,绑定有新连接时的回调函数,绑定服务器的定时函数,虚拟内存初始化,log初始化等等

3      适用场景

Redis和RabbitMQ性能对比

    RabbitMQ是使用Erlang编写的一个开源的消息队列,本身支持很多的协议:AMQP,XMPP, SMTP, STOMP,也正是如此,使的它变的非常重量级,更适合于企业级的开发。个人认为,在互联网开发中,使用消息队列,更多的因为在高并发环境下,由于来不及同步处理,请求会发生堵塞,所以我们需要一个队列服务来进行异步的处理,在这种场景下,只要队列服务满足最基本的Push/Pop已经足够了。
    Redis是一个Key-Value的NoSQL数据库,开发维护很活跃,虽然它是一个Key-Value数据库存储系统,但它本身支持list数据结构的操作,所以完全可以当做一个轻量级的队列服务来使用。
    对于入队操作,当数据比较小时Redis的性能要高于RabbitMQ,而如果数据大小超过了10K,Redis慢的无法忍受。
    对于出队操作,无论数据大小,Redis都表现出非常好的性能,而RabbitMQ的出队性能则远低于Redis。
    Redis比较适合在Web场景下作为队列服务使用,但当数据比较大的时候,入队性能有些问题,也可能是我配置上不正确,所以还需要进一步研究。而RabbitMQ本身支持太多的协议,不适合在Web环境中使用。另外有一个MySQL的插件Q4M,可以使用SQL语法来操作消息队列,只不过性能表现怎么样,还需要进一步测试。

Quartz任务调度

    Quartz是一个强大的企业级任务调度框架,Spring中继承并简化了Quartz。Quartz API 采用多面方式在java应用程序中进行任务调度,提供了丰富的作业调度集。这个也可以实现消息队列,小编不是很熟,再次不多赘述,有兴趣的可以下去了解一下。

转载自:http://blog.csdn.net/educast/article/details/34521603

               http://lynnkong.iteye.com/blog/1699684

   

RedisRabbitMQ配合使用多线程(多消费者)处理消息 通过本次演示的案例,希望大家可以掌握并且多加练习,在日常的开发中缓存数据库异步队列是必备的手段,同时也是大家找工作时的一个亮点。本文如有不妥之处希望大家指正!!! 阅读详情

相关推荐

Redis vs RabbitMQ:不是选择题,而是生存题

本文对比了RedisRabbitMQ作为消息队列的适用性差异。Redis作为内存数据库,虽然能做消息队列但不适合高并发场景,存在消息丢失风险。通过真实案例展示了Redis被误用导致系统崩溃的问题(促销活动期间内存爆满)。技术对比表显示:Redis吞吐量高但可靠性低,RabbitMQ专为消息传递设计,支持持久化高并发。文章提供了C#代码示例,分别演示Redis作为缓存(设置/获取缓存)RabbitMQ作为消息队列的正确用法,强调二者应各司其职:Redis处理缓存,RabbitMQ负责消息传递。

墨夶的博客 1696

MQ对比之RabbitMQ & Redis

消息队列选择:RabbitMQ & Redis RabbitMQ RabbitMQ是一个由erlang开发的AMQP(Advanced Message Queue )的开源实现的产品,RabbitMQ是一个消息代理,从“生产者”接收消息并传递消息至“消费者”,期间可根据规则路由、缓存、持久化消息。“生产者”也即message发送者以下简称P,相对应的“消费者”乃message接收者以下...

夜空中最亮的星 4201

RabbitMQ vs Redis: 比较区别

RabbitMQ是一个开源的消息队列系统,采用AMQP(Advanced Message Queuing Protocol)协议。它允许应用程序之间通过消息进行通信,并提供了可靠的消息传递机制。RabbitMQ使用生产者(Producer)将消息发送到队列,消费者(Consumer)从队列中接收处理消息。可靠性:RabbitMQ提供持久化存储,确保消息在发送接收过程中不会丢失。

EvktJava的博客 886

Redis&RabbitMQ

Redis是非关系型数据库,其存储的形式是键值对的形式key: value,是使用c语言编写的,数据是基于内存存储的,支持持久化,读写速度快,·通过集群模式提供高可靠。作用:(1)用来存放热点数据(首页数据热搜)(2)作为缓存使用(mybatis二级缓存)(3)作为消息队列使用(4)分布式锁redis的持久化就是把内存的数据写到磁盘中去,防止服务宕机了内存数据丢失。是Redis DataBase缩写快照RDB是Redis默认的持久化方式。

weixin_70730532的博客 5730

实现商品秒杀之——Redis+RabbitMQ消息队列

RabbitMQ消息队列 RabbitMQ是一套开源的消息队列服务软件,实现了高级消息队列协议(AMQP),服务器采用Erlang语言开发,支持多种客户端,如:Python、Ruby、Java、JMS、C#、PHP、JavaScript等。 其特点包含: 异步处理:通过把消息发送给消息中间件,消息中间件并不立即处理它,而是后续再慢慢处理 应用解耦:单个系统出现故障,消息队列也...

王绍桦 3147

RabbitMQRedis结合实现消息队列

相比之下,Redis是一个内存中的数据存储系统,它提供了快速的读写速度丰富的数据结构支持。通过这个简单的示例,我们可以看到如何使用RabbitMQ发送消息,并通过Redis进行数据存储。这种结合使用的方式可以帮助我们构建灵活、高效的应用程序,实现异步通信可靠的数据存储。使用RabbitMQRedis的组合,您可以根据自己的需求设计实现更加复杂的消息队列系统数据存储方案。要将RabbitMQRedis结合使用,我们可以利用它们各自的优势来实现不同的功能。首先,我们需要安装相应的依赖库。

EvktJava的博客 501

分布式锁消息队列RedisRabbitMQ实现

1.背景介绍 在现代互联网应用中,分布式系统已经成为主流。分布式系统具有高性能、高可用性高扩展性等优点,但同时也带来了一系列复杂性,如数据一致性、分布式锁、消息队列等。在这篇文章中,我们将深入探讨分布式锁消息队列实现,以及如何使用RedisRabbitMQ来解决这些问题。 2.核心概念与联系 2.1 分布式锁 分布式锁是一种在分布式系统中实现互斥访问的方法,它允许多个节点在不同的计...

AI天才研究院 1669

PHP + Laravel + RabbitMQ + Redis 实现消息队列 (二) 消费队列在RabbitMQredis中的简单使用

这里我们的测试环境使用的是larveal;其中P端代码我放到了,作为一个基础的路由进行访问,但是在因为这里消费的代码不能这样处理所以消费端的代码我使用了 larveal 提供的命令行。我们进行一个测试,可以看到消费者先是输出了接收到的数据,然后正常的打印出来了;在上面这段代码中 我们需要注意的是。

weixin_43193813的博客 1430

【黑马点评】 使用RabbitMQ消息队列实现秒杀下单(完美契合点评Redis要求)

这里创建redis消费组队列我就不说了,直接看消费组是怎么实现的:用RabbbitMQ替代Stream我的想法如下,结合Stream的特点逐一增加RabbitMQ的功能:特点:1.Stream可持久化(所以我们采用RabbitMQ的lazy队列以及消息,交换机,队列的可持久化机制)

qq_51597192的博客 5672

RabbitMQ、Kafka、RocketMQ以及Redis 实现消息队列介绍,优缺点对比

本文系统介绍了消息队列技术及其在Redis中的实现方式。首先阐述了消息队列的基本概念、核心特性(有序性、重复消息处理、可靠性)典型应用场景(商品秒杀、系统解耦)。然后对比分析了三种主流消息中间件(RabbitMQ、Kafka、RocketMQ)的特点适用场景。重点讲解了Redis实现消息队列的三种方法:基于List的FIFO队列(支持阻塞读取消息备份)、发布订阅模式(支持频道模式订阅)以及Stream类型(支持消息分组、确认机制全局唯一ID)。最后指出Redis适合轻量级消息队列场景,而重量级场景

DN金猿的博客 317

PHP + Laravel + RabbitMQ + Redis 实现消息队列 (三) 消费队列在RabbitMQredis中的发布订阅

对于消息队列传统的模式来说,一个消费者消费一条消息,这条消息被消费之后就不会再次被其它的消费者消费。但是在发布订阅模式中,一条消息是可以被多个消费者消费的,这些消费者其实相当于是订阅了这条队列的消息。当有新的消息出现在队列中,就会像广播一样让所有订阅者都获得这条消息。

weixin_43193813的博客 2035

RedisRabbitMQ实现消息队列

RabbitMQ简介 1什么是RabbitMQRabbitMQ实现AMQP(高级消息队列协议)的消息中间件的一种,最初起源于金融系统,用于在分布式系统中存储转发消息,在易用性、扩展性、高可用性等方面表现不俗。消息中间件主要用于组件之间的解耦,消息的发送者无需知道消息使用者的存在,反之亦然:   单向解耦   双向解耦(如:RPC)

逍遥飞鹤的专栏 4807

php mysql redis mq_php消息队列实现及应用(Redis RabbitMQ

1.消息队列概念队列结构的中间件消息放入后,不需要立即处理由订阅者/消费者按顺序处理2.应用场景冗余解耦流量削峰(秒杀系统)异步通信扩展性排序保证3.队列介质mysql:可靠性高,易实现,速度慢redis:速度快,单条大消息包时效率低消息系统:专业性强、可靠,学习成本高4.消息处理触发机制死循环方式读取:易实现,故障时无法及时恢复定时任务:压力均分,有处理量上限守护进程:类似于PHP-FPMPH...

weixin_30802953的博客 379

PHP消息队列使用教程:Redis/RabbitMQ实现异步处理

消息队列在PHP开发中不是可选项,而是处理高并发、解耦系统组件实现异步任务的关键技术。它把耗时操作从请求响应链路中剥离,让PHP脚本快速返回,后台任务按顺序可靠执行。

2509_93883384的博客 320

redis发布订阅模式下实现消息队列rabbitmq的对比

  redis rabbitmq 可靠性 没有相应的机制保证消息的可靠消费,如果发布者发布一条消息,而没有对应的订阅者的话,这条消息将丢失,不会存在内存中 具有消息消费确认机制,如果发布一条消息,还没有消费者消费该队列,那么这条消息将一直存放在队列中,直到有消费者消费了该条消息,以此可以保证消息的可靠消费 实时性 redis作为高效的缓存服务器,所有数据都存在...

U.R.M.L 2311

PHP + Laravel + RabbitMQ + Redis 实现消息队列 (五) 异常处理(死信)、延时队列与优先队列

当我们遇到消息没有被正常消费的时候,需要对这条异常的消息进行处理,这里就会遇到一个问题,如果是直接丢弃消息,那么这条消息就会丢失。如果是直接重试,那么如果还是存在异常,这里就会陷入死循环。

weixin_43193813的博客 1149

RabbitMQ,Apache的ActiveMQ,阿里RocketMQ,Kafka,ZeroMQ,MetaMQ,Redis也可实现消息队列RabbitMQ的应用场景以及基本原理介绍,RabbitMQ

RabbitMQ,Apache的ActiveMQ,阿里RocketMQ,Kafka,ZeroMQ,MetaMQ,Redis也可实现消息队列RabbitMQ的应用场景以及基本原理介绍,RabbitMQ消息队列及常见消息队列介绍 一、消息队列(MQ)概述 消息队列(Message Queue),是分布式系统中重要的组件,其通用的使用场景可以简单地描述为: 当不需要立即获得结果,但是并发量又需要进行控制的时候,差不多就是需要使用消息队列的时候。 消息队列主要解决了应用耦合、异步处理、流量削锋等问题。 当

m0_58477546的博客 696

Redis 如何实现消息队列

消息队列(Messeage Queue,MQ)是在分布式系统架构中常用的一种中间件技术,从字面表述看,是一个存储消息的队列,所以它一般用于给 MQ 中间的两个组件提供通信服务。

hello_1566的博客 1746

PHP + Laravel + RabbitMQ + Redis 实现消息队列 (一) RabbitMQ安装 Error: unable to perform an operation on node

首先这里我们需要 找到用户目录下有一个 .erlang.cookie 还有一个在。可能是因为 .erlang.cookie 的配置不一致问题;然后修改两个文件一致即可;

weixin_43193813的博客 1365
上一篇: 关于Mongodb的全面总结,学习mongodb的人,可以从这里开始!
下一篇: LocalDate和Date的互换,以及LocalDate的使用
夜唯美不离
博客等级 码龄14年 6粉丝 9原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值