RabbitMQ

筅森魡賤 提交于 2020-12-12 10:50:05

 

一、RabbitMQ

RabbitMQ 是一个由 Erlang 语言开发的 AMQP 的开源实现。
rabbitMQ是一款基于AMQP协议的消息中间件,它能够在应用之间提供可靠的消息传输。在易用性,扩展性,高可用性上表现优秀。使用消息中间件利于应用之间的解耦,生产者(客户端)无需知道消费者(服务端)的存在。而且两端可以使用不同的语言编写,大大提供了灵活性。
 

二、RabbitMQ的安装

 

rabbitmq-server服务端
1.下载centos源
wget -O /etc/yum.repos.d/CentOS-Base.repo   http://mirrors.cloud.tencent.com/repo/centos7_base.repo
2.下载epel源
wget -O /etc/yum.repos.d/epel.repo http://mirrors.cloud.tencent.com/repo/epel-7.repo
3.清空yum缓存并且生成新的yum缓存
yum clean all
yum makecache
4.安装erlang
   $ yum -y install erlang
5.安装RabbitMQ
   $ yum -y install rabbitmq-server
6.启动(无用户名密码):
    systemctl start/stop/restart/status rabbitmq-server
​
设置rabbitmq账号密码,以及角色权限设置

# 设置新用户yugo 密码123
sudo rabbitmqctl add_user yugo 123# 设置用户为administrator角色
sudo rabbitmqctl set_user_tags yugo administrator
​
# 设置权限,允许对所有的队列都有权限
对何种资源具有配置、写、读的权限通过正则表达式来匹配,具体命令如下:
set_permissions [-p <vhostpath>] <user> <conf> <write> <read>

sudo rabbitmqctl set_permissions -p "/" yugo ".*" ".*" ".*"#重启服务生效设置
service rabbitmq-server start/stop/restart

 

 

centso6 启动rabbitmq

service rabbitmq-server start
service rabbitmq-server stop

 

rabbitmq相关命令
// 新建用户
rabbitmqctl add_user {用户名} {密码}
​
// 设置权限
rabbitmqctl set_user_tags {用户名} {权限}
​
// 查看用户列表
rabbitmqctl list_users
​
// 为用户授权
添加 Virtual Hosts :    
rabbitmqctl add_vhost <vhost>// 删除用户
rabbitmqctl delete_user Username
​
// 修改用户的密码
rabbitmqctl change_password Username Newpassword
    
// 删除 Virtual Hosts :    
rabbitmqctl delete_vhost <vhost>    
    
// 添加 Users :    
rabbitmqctl add_user <username> <password>    
rabbitmqctl set_user_tags <username> <tag> ...    
rabbitmqctl set_permissions [-p <vhost>] <user> <conf> <write> <read>    
    
// 删除 Users :    
delete_user <username>// 使用户user1具有vhost1这个virtual host中所有资源的配置、写、读权限以便管理其中的资源
rabbitmqctl  set_permissions -p vhost1 user1 '.*' '.*' '.*' 
​
// 查看权限
rabbitmqctl list_user_permissions user1
​
rabbitmqctl list_permissions -p vhost1
​
// 清除权限
rabbitmqctl clear_permissions [-p VHostPath] User
​

 

清空队列步骤

rabbitmqctl reset 
  需要提前关闭应用
    rabbitmqctl stop_app ,   然后再清空队列,启动应用     rabbitmqctl start_app 此时查看队列rabbitmqctl list_queues ​ 查看所有的exchange: rabbitmqctl list_exchanges 查看所有的queue: rabbitmqctl list_queues 查看所有的用户: rabbitmqctl list_users 查看所有的绑定(exchange和queue的绑定信息): rabbitmqctl list_bindings 查看消息确认信息: rabbitmqctl list_queues name messages_ready messages_unacknowledged 查看RabbitMQ状态,包括版本号等信息:rabbitmqctl status
#开启web界面rabbitmq rabbitmq-plugins enable rabbitmq_management #访问web界面 http://server-name:15672/

 

四、 RabbitMQ组件解释

 

AMQP

AMQP协议是一个高级抽象层消息通信协议,RabbitMQ是AMQP协议的实现。它主要包括以下组件:

1.Server(broker): 接受客户端连接,实现AMQP消息队列和路由功能的进程。

2.Virtual Host:其实是一个虚拟概念,类似于权限控制组,一个Virtual Host里面可以有若干个Exchange和Queue,但是权限控制的最小粒度是Virtual Host

3.Exchange:接受生产者发送的消息,并根据Binding规则将消息路由给服务器中的队列。ExchangeType决定了Exchange路由消息的行为,例如,在RabbitMQ中,ExchangeType有direct、Fanout和Topic三种,不同类型的Exchange路由的行为是不一样的。

4.Message Queue:消息队列,用于存储还未被消费者消费的消息。

5.Message: 由Header和Body组成,Header是由生产者添加的各种属性的集合,包括Message是否被持久化、由哪个Message Queue接受、优先级是多少等。而Body是真正需要传输的APP数据。

6.Binding:Binding联系了Exchange与Message Queue。Exchange在与多个Message Queue发生Binding后会生成一张路由表,路由表中存储着Message Queue所需消息的限制条件即Binding Key。当Exchange收到Message时会解析其Header得到Routing Key,Exchange根据Routing Key与Exchange Type将Message路由到Message Queue。Binding Key由Consumer在Binding Exchange与Message Queue时指定,而Routing Key由Producer发送Message时指定,两者的匹配方式由Exchange Type决定。 

7.Connection:连接,对于RabbitMQ而言,其实就是一个位于客户端和Broker之间的TCP连接。

8.Channel:信道,仅仅创建了客户端到Broker之间的连接后,客户端还是不能发送消息的。需要为每一个Connection创建Channel,AMQP协议规定只有通过Channel才能执行AMQP的命令。一个Connection可以包含多个Channel。之所以需要Channel,是因为TCP连接的建立和释放都是十分昂贵的,如果一个客户端每一个线程都需要与Broker交互,如果每一个线程都建立一个TCP连接,暂且不考虑TCP连接是否浪费,就算操作系统也无法承受每秒建立如此多的TCP连接。RabbitMQ建议客户端线程之间不要共用Channel,至少要保证共用Channel的线程发送消息必须是串行的,但是建议尽量共用Connection。

9.Command:AMQP的命令,客户端通过Command完成与AMQP服务器的交互来实现自身的逻辑。例如在RabbitMQ中,客户端可以通过publish命令发送消息,txSelect开启一个事务,txCommit提交一个事务。

 

 

五、Python客户端

 

// rabbitmq官方推荐的python客户端pika模块
pip3 install pika

 

六、应用场景,简单练习

 

6.1单发送单接收

  生产者-消费者模型

复制代码

RabbitMQ组件解释

复制代码
AMQP

AMQP协议是一个高级抽象层消息通信协议,RabbitMQ是AMQP协议的实现。它主要包括以下组件:

1.Server(broker): 接受客户端连接,实现AMQP消息队列和路由功能的进程。

2.Virtual Host:其实是一个虚拟概念,类似于权限控制组,一个Virtual Host里面可以有若干个Exchange和Queue,但是权限控制的最小粒度是Virtual Host

3.Exchange:接受生产者发送的消息,并根据Binding规则将消息路由给服务器中的队列。ExchangeType决定了Exchange路由消息的行为,例如,在RabbitMQ中,ExchangeType有direct、Fanout和Topic三种,不同类型的Exchange路由的行为是不一样的。

4.Message Queue:消息队列,用于存储还未被消费者消费的消息。

5.Message: 由Header和Body组成,Header是由生产者添加的各种属性的集合,包括Message是否被持久化、由哪个Message Queue接受、优先级是多少等。而Body是真正需要传输的APP数据。

6.Binding:Binding联系了Exchange与Message Queue。Exchange在与多个Message Queue发生Binding后会生成一张路由表,路由表中存储着Message Queue所需消息的限制条件即Binding Key。当Exchange收到Message时会解析其Header得到Routing Key,Exchange根据Routing Key与Exchange Type将Message路由到Message Queue。Binding Key由Consumer在Binding Exchange与Message Queue时指定,而Routing Key由Producer发送Message时指定,两者的匹配方式由Exchange Type决定。 

7.Connection:连接,对于RabbitMQ而言,其实就是一个位于客户端和Broker之间的TCP连接。

8.Channel:信道,仅仅创建了客户端到Broker之间的连接后,客户端还是不能发送消息的。需要为每一个Connection创建Channel,AMQP协议规定只有通过Channel才能执行AMQP的命令。一个Connection可以包含多个Channel。之所以需要Channel,是因为TCP连接的建立和释放都是十分昂贵的,如果一个客户端每一个线程都需要与Broker交互,如果每一个线程都建立一个TCP连接,暂且不考虑TCP连接是否浪费,就算操作系统也无法承受每秒建立如此多的TCP连接。RabbitMQ建议客户端线程之间不要共用Channel,至少要保证共用Channel的线程发送消息必须是串行的,但是建议尽量共用Connection。

9.Command:AMQP的命令,客户端通过Command完成与AMQP服务器的交互来实现自身的逻辑。例如在RabbitMQ中,客户端可以通过publish命令发送消息,txSelect开启一个事务,txCommit提交一个事务。

复制代码

python客户端

// rabbitmq官方推荐的python客户端pika模块
pip3 install pika

应用场景1:单发送单接收

生产-消费者模型

P   是生产者
C 是消费者
中间hello是消息队列
可以有多个P、多个C
P发送消息给hello队列,C消费者从队列中获取消息,默认轮询方式

 

 

 

 

 

 

 

生产者send.py

我们的第一个程序send.py将向队列发送一条消息。我们需要做的第一件事是建立与RabbitMQ服务器的连接。
#coding:utf-8
import pika


# 创建凭证,使用rabbitmq用户密码登录
credentials = pika.PlainCredentials("jin","123")

# 新建连接,这里localhost可以更换为服务器ip
connection = pika.BlockingConnection(pika.ConnectionParameters('118.24.9.23',credentials=credentials))


# 创建频道
# 建造一个大邮箱,隶属于这家邮局的邮箱,就是个连接
channel = connection.channel()

# 声明一个队列,用于接收消息,队列名字叫“king”
channel.queue_declare(queue="king")


# 注意在rabbitmq中,消息想要发送给队列,必须经过交换(exchange),
        #初学可以使用空字符串交换(exchange=''),
        #它允许我们精确的指定发送给哪个队列(routing_key=''),
        #参数body值发送的数据
channel.basic_publish(
            exchange='',
            routing_key='king',
            body='the_word'

)
print('已经发送')

# 程序退出前,确保刷新网络缓冲以及消息发送给rabbitmq,需要关闭本次连接
connection.close()

 

 

 

可以同时存在多个接受者,等待接收队列的消息,默认是轮训方式分配消息

接受者receive.py,可以运行多次,运行多个消费者

 

#coding:utf-8

import pika

# 建立与rabbitmq的连接
credentials = pika.PlainCredentials("jin","123")

connection = pika.BlockingConnection(pika.ConnectionParameters('118.24.9.23',credentials=credentials))

channel = connection.channel()
channel.queue_declare(queue='king')

def callback(ch,method,properties,body):
    print("消费者接收到了任务:%r"%body.decode("utf8"))


# 有消息来临,立即执行callbak,没有消息则夯住,等待消息
# 老百姓开始去邮箱取邮件啦,队列名字是king
channel.basic_consume(on_message_callback=callback,queue="king",)

# 开始消费,接收消息
channel.start_consuming()

 

 注: 

channel.basic_consume(callbak,queue="水许传",no_ack=True)

提示

Traceback (most recent call last):
  File "reveive.py", line 19, in <module>
    channel.basic_consume(callback,queue="king",no_ack=True)
TypeError: basic_consume() got multiple values for argument 'queue'


查看源码

def basic_consume(self,
                      queue,
                      on_message_callback,
                      auto_ack=False,
                      exclusive=False,
                      consumer_tag=None,
                      arguments=None):

按源码修改即可

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!