RabbitMQ基础概念详解(一)——环境配置及模拟生产者和消费者简单消息发送

一、简介:

RabbitMq 是实现了高级消息队列协议(AMQP)的开源消息代理中间件。消息队列是一种应用程序对应用程序的通行方式,应用程序通过写消息,将消息传递于队列,由另一应用程序读取 完成通信。而作为中间件的 RabbitMq 无疑是目前最流行的消息队列之一。

AMQP,即Advanced Message Queuing Protocol,高级消息队列协议,是应用层协议的一个开放标准,为面向消息的中间件设计。消息中间件主要用于组件之间的解耦,消息的发送者无需知道消息使用者的存在,反之亦然。
AMQP的主要特征是面向消息、队列、路由(包括点对点和发布/订阅)、可靠性、安全。
RabbitMQ是一个开源的AMQP实现,服务器端用Erlang语言编写,支持多种客户端,如:Python、Ruby、.NET、Java、JMS、C、PHP、ActionScript、XMPP、STOMP等,支持AJAX。用于在分布式系统中存储转发消息,在易用性、扩展性、高可用性等方面表现不俗。

RabbitMq 应用场景广泛:

  • 系统的高可用:日常生活当中各种商城秒杀,高流量,高并发的场景。当服务器接收到如此大量请求处理业务时,有宕机的风险。某些业务可能极其复杂,但这部分不是高时效性,不需要立即反馈给用户,我们可以将这部分处理请求抛给队列,让程序后置去处理,减轻服务器在高并发场景下的压力。
  • 分布式系统,集成系统,子系统之间的对接,以及架构设计中常常需要考虑消息队列的应用。

二、RabbitMQ下载安装

下载地址(windows):https://www.rabbitmq.com/install-windows.html

安装:一直下一步下一步就好了,因为是Erlang语言编写的,在安装RabbitMQ的时候会提醒你安装Erlang。

RabbitMQ python帮助文档:https://www.rabbitmq.com/tutorials/tutorial-one-python.html

安装完成后,在cmd窗口中执行以下命令来激活RabbitMQ Manage Plugin

 然后重启RabbitMQ服务

到这一步,RabbitMQ的安装就算是完成了,其中有几个默认值,我们要知道:

  • 默认的端口号:5672
  • 默认的用户是guest,密码是guest
  • 管理后台的默认端口号:15672

浏览器输入http://localhost:15672/,我们可以看到RabbitMQ的管理后台,然后使用默认的guest账号登录,在这个后台,可以完成新建用户,配置用户角色,新建队列等操作。

 

三、ConnectionFactory、Connection、Channel

ConnectionFactory、Connection、Channel都是RabbitMQ对外提供的API中最基本的对象。Connection是RabbitMQ的socket链接,它封装了socket协议相关部分逻辑。ConnectionFactory为Connection的制造工厂。
Channel是我们与RabbitMQ打交道的最重要的一个接口,我们大部分的业务操作是在Channel这个接口中完成的,包括定义Queue、定义Exchange、绑定Queue与Exchange、发布消息等。

四、队列(Queue)、生产者、消费者

队列是RabbitMQ的内部对象,用于存储消息。生产者(下图中的P)生产消息并投递到队列中,消费者(下图中的C)可以从队列中获取消息并消费。

多个消费者可以订阅同一个队列,这时队列中的消息会被平均分摊给多个消费者进行处理,而不是每个消费者都收到所有的消息并处理。

 

队列的作用:

  • 存储信息,数据
  • 保证消息的顺序
  • 保证数据的正确交付

五、RabbitMQ架构介绍

Producter

队列消息的产生者,负责生产消息,并将消息传入队列也是一个向交换器发布消息的客户端应用程序。

Exchange

交换器,用来接收生产者发送的消息并将这些消息路由给服务器中的队列。

Queue

消息队列,用来保存消息直到发送给消费者。它是消息的容器,也是消息的终点。一个消息可投入一个或多个队列。消息一直在队列里面,等待消费者连接到这个队列将其取走。

Channel

信道,多路复用连接中的一条独立的双向数据流通道

Consumer

消息的消费者,表示一个从消息队列中取得消息的客户端应用程序

RabbitMQ安装

pip install pika

生产者和消费者简单的消息发送

生产者  (创建一个队列test,然后往消息队列里发送消息hello test)

import pika
credentials
= pika.PlainCredentials('guest','guest') #mq用户名和密码,如果设置了,在消费者中也要有一样的 connection = pika.BlockingConnection(pika.ConnectionParameters(host="localhost", credentials=credentials)) channel = connection.channel() #信道 channel.queue_declare('test') #声明消息队列,消息将在这个队列传递 channel.basic_publish(exchange='', routing_key='test', body='hello test') #向队列插入数值 routing_key是队列名,body是往消息队列中传递的数据 print('publish done') connection.close() #关闭连接

运行上面这段代码,在后台可以看到队列创建成功,并且有一个消息在等待。

 

消费者 (从test队列中获取数据)

import pika

credentials = pika.PlainCredentials('guest','guest')  #和生产者一样的用户名和密码
connection = pika.BlockingConnection(pika.ConnectionParameters(host="localhost", credentials=credentials))
channel = connection.channel()  #创建信道,数据流通道
channel.queue_declare(queue='test')   #队列
def callback(ch, method, properties, body):   #定义一个回调函数来处理消息队列中的消息
    print("consume done", ch, method, properties,body)
channel.basic_consume('test',callback, auto_ack=True)   #注意:队列参数放第一个,这部分源码改了。使用auto_ack和no_ack是同一个意思
channel.start_consuming()   #开始接收消息,并进入阻塞状态,队列里有消息才会调用callback进行处理

运行消费者代码报错:

TypeError: basic_consume() got multiple values for argument 'queue'

是因为basic_consume的源码参数位置改变了:第一个参数放队列名字。 注意:queue参数和auto_ack参数

源码参数:

运行消费者代码会从队列中取出信息,Ready的消息数为0

 

 

更多讲解请看下一节

posted @ 2019-12-26 20:47  只会玩辅助  阅读(643)  评论(0编辑  收藏  举报