RabbitMQ在Ubuntu 16.04下的安装与配置及python RabbitMQ队列使用

本文转载自https://blog.csdn.net/rickey17/article/details/72756766

https://www.cnblogs.com/kerwinC/p/5967584.html

一、RabbitMQ在Ubuntu 16.04下的安装与配置

添加源

echo 'deb http://www.rabbitmq.com/debian/ testing main' | sudo tee /etc/apt/sources.list.d/rabbitmq.list

新增公钥

wget -O- https://www.rabbitmq.com/rabbitmq-release-signing-key.asc | sudo apt-key add -

更新源

sudo apt-get update

安装rabbitmq-server

sudo apt-get install rabbitmq-server

通过上篇介绍的命令invoke-rc.d rabbitmq-server stop/start/etc我们看见进程是启动的

xq@xq-VPCEG17YC:/etc/apt/sources.list.d$ invoke-rc.d rabbitmq-server status 
● rabbitmq-server.service - RabbitMQ broker
   Loaded: loaded (/lib/systemd/system/rabbitmq-server.service; enabled; vendor preset: enabled)
   Active: active (running) since 四 2017-05-25 20:42:25 CST; 5min ago
 Main PID: 4865 (beam.smp)
   Status: "Initialized"
   CGroup: /system.slice/rabbitmq-server.service
           ├─4865 /usr/lib/erlang/erts-7.3/bin/beam.smp -W w -A 64 -P 1048576 -t 5000000 -stbt db -zdbbl 32000 -K true -- -root /usr/lib/erlang
           ├─4942 /usr/lib/erlang/erts-7.3/bin/epmd -daemon
           ├─5074 inet_gethost 4
           └─5075 inet_gethost 4

5月 25 20:42:21 xq-VPCEG17YC rabbitmq-server[4865]:               RabbitMQ 3.6.10. Copyright (C) 2007-2017 Pivotal Software, Inc.
5月 25 20:42:21 xq-VPCEG17YC rabbitmq-server[4865]:   ##  ##      Licensed under the MPL.  See http://www.rabbitmq.com/
5月 25 20:42:21 xq-VPCEG17YC rabbitmq-server[4865]:   ##  ##
5月 25 20:42:21 xq-VPCEG17YC rabbitmq-server[4865]:   ##########  Logs: /var/log/rabbitmq/rabbit@xq-VPCEG17YC.log
5月 25 20:42:21 xq-VPCEG17YC rabbitmq-server[4865]:   ######  ##        /var/log/rabbitmq/rabbit@xq-VPCEG17YC-sasl.log
5月 25 20:42:21 xq-VPCEG17YC rabbitmq-server[4865]:   ##########
5月 25 20:42:21 xq-VPCEG17YC rabbitmq-server[4865]:               Starting broker...
5月 25 20:42:25 xq-VPCEG17YC rabbitmq-server[4865]: systemd unit for activation check: "rabbitmq-server.service"
5月 25 20:42:25 xq-VPCEG17YC systemd[1]: Started RabbitMQ broker.
5月 25 20:42:25 xq-VPCEG17YC rabbitmq-server[4865]:  completed with 0 plugins.

打开管理页面 

sudo rabbitmq-plugins enable rabbitmq_management

查看安装的插件 

sudo rabbitmqctl list_users

查看用户 

sudo rabbitmqctl list_users

新增管理员用户 

sudo rabbitmqctl add_user admin admin 
sudo rabbitmqctl set_user_tags admin administrator

用刚设置的账户登录管理页面 

http://127.0.0.1:15672


二、python RabbitMQ队列使用

1. 关于python的queue介绍

    关于python的队列,内置的有两种,一种是线程queue,另一种是进程queue,但是这两种queue都是只能在同一个进程下的线程间或者父进程与子进程之间进行队列通讯,并不能进行程序与程序之间的信息交换,这时候我们就需要一个中间件,来实现程序之间的通讯。

2. RabbitMQ

    MQ并不是python内置的模块,而是一个需要你额外安装的程序,安装完毕后可通过python中内置的pika模块来调用MQ发送或接收队列请求。接下来我们就看几种python调用MQ的模式(作者自定义中文形象的模式名称)与方法。

3. RabbitMQ设置远程链接账号密码

1) 启动rabbitmq web服务

2) 远程访问rabbitmq: 自己增加一个用户,步骤如下:

(1)  创建一个admin用户

sudo rabbitmqctl add_user admin 123123

(2)  设置该用户为administrator角色

sudo rabbitmqctl set_user_tags admin administrator

(3)  设置权限

sudo rabbitmqctl  set_permissions  -p  '/'  admin '.' '.' '.'

(4)  重启rabbitmq服务

sudo service rabbitmq-server restart

之后就能用admin用户远程连接rabbitmq server了。

4. 轮询消费模式

此模式下,发送队列的一方把消息存入mq的指定队列后,若有消费者端联入相应队列,即会获取到消息,并且队列中的消息会被消费掉。

若有多个消费端同时连接着队列,则会已轮询的方式将队列中的消息消费掉。

接下来是代码实例:

producer生产者

# !/usr/bin/env python
import pika
credentials = pika.PlainCredentials('admin','123456')
connection = pika.BlockingConnection(pika.ConnectionParameters(
    '192.168.56.19',5672,'/',credentials))
channel = connection.channel()

# 声明queue
channel.queue_declare(queue='balance')

# n RabbitMQ a message can never be sent directly to the queue, it always needs to go through an exchange.
channel.basic_publish(exchange='',
                      routing_key='balance',
                      body='Hello World!')
print(" [x] Sent 'Hello World!'")
connection.close()

发送过队列后,可在MQ服务器中查看队列状态

[root@localhost ~]# rabbitmqctl list_queues
Listing queues ...
hello    1

consumer消费者

# _*_coding:utf-8_*_
__author__ = 'Alex Li'
import pika

credentials = pika.PlainCredentials('admin','123456')
connection = pika.BlockingConnection(pika.ConnectionParameters(
    '192.168.56.19',5672,'/',credentials))
channel = connection.channel()

# You may ask why we declare the queue again ‒ we have already declared it in our previous code.
# We could avoid that if we were sure that the queue already exists. For example if send.py program
# was run before. But we're not yet sure which program to run first. In such cases it's a good
# practice to repeat declaring the queue in both programs.
channel.queue_declare(queue='balance')


def callback(ch, method, properties, body):
    print(" [x] Received %r" % body)


channel.basic_consume(callback,
                      queue='balance',
                      no_ack=True)

print(' [*] Waiting for messages. To exit press CTRL+C')
channel.start_consuming()

接收队列后,查看一下队列状态

[root@localhost ~]#  rabbitmqctl list_queues
Listing queues ...
hello    0

5. 队列持久化

当rabbitMQ意外宕机时,可能会有持久化保存队列的需求(队列中的消息不消失)。
producer
# Cheng
# !/usr/bin/env python
import pika

credentials = pika.PlainCredentials('admin','123456')
connection = pika.BlockingConnection(pika.ConnectionParameters(
    '192.168.56.19',5672,'/',credentials))
channel = connection.channel()

# 声明queue
channel.queue_declare(queue='durable',durable=True)

# n RabbitMQ a message can never be sent directly to the queue, it always needs to go through an exchange.
channel.basic_publish(exchange='',
                      routing_key='durable',
                      body='Hello cheng!',
                      properties=pika.BasicProperties(
                          delivery_mode=2,  # make message persistent
                      )
                      )
print(" [x] Sent 'Hello cheng!'")
connection.close()

执行后查看队列,记下队列名字与队列中所含消息的数量

[root@localhost ~]# rabbitmqctl list_queues
Listing queues ...
durable    1
#重启rabbitmq
[root@localhost ~]# systemctl restart rabbitmq-server
#重启完毕后再次查看
[root@localhost ~]# rabbitmqctl list_queues
Listing queues ...
durable   #队列以及消息并未消失
执行消费者代码

cunsumer

# Cheng
# _*_coding:utf-8_*_
__author__ = 'Alex Li'
import pika

credentials = pika.PlainCredentials('admin','123456')
connection = pika.BlockingConnection(pika.ConnectionParameters(
    '192.168.56.19',5672,'/',credentials))
channel = connection.channel()

# You may ask why we declare the queue again ‒ we have already declared it in our previous code.
# We could avoid that if we were sure that the queue already exists. For example if send.py program
# was run before. But we're not yet sure which program to run first. In such cases it's a good
# practice to repeat declaring the queue in both programs.
channel.queue_declare(queue='durable',durable=True)


def callback(ch, method, properties, body):
    print(" [x] Received %r" % body)
    ch.basic_ack(delivery_tag=method.delivery_tag)

channel.basic_consume(callback,
                      queue='durable',
                      #no_ack=True
                      )

print(' [*] Waiting for messages. To exit press CTRL+C')
channel.start_consuming()
可正确接收到信息。

再次查看队列的情况。

[root@localhost ~]# rabbitmqctl list_queues
Listing queues ...
durable    0

7. 广播模式

当producer发送消息到队列后,所有的consumer都会收到消息,需要注意的是,此模式下producer与concerned之间的关系类似与广播电台与收音机,如果广播后收音机没有接受到,那么消息就会丢失。
建议先执行concerned
concerned
# _*_coding:utf-8_*_
__author__ = 'Alex Li'
import pika

credentials = pika.PlainCredentials('admin','123456')
connection = pika.BlockingConnection(pika.ConnectionParameters(
    '192.168.56.19',5672,'/',credentials))
channel = connection.channel()

channel.exchange_declare(exchange='Clogs',
                         type='fanout')

result = channel.queue_declare(exclusive=True)  # 不指定queue名字,rabbit会随机分配一个名字,exclusive=True会在使用此queue的消费者断开后,自动将queue删除
queue_name = result.method.queue

channel.queue_bind(exchange='Clogs',
                   queue=queue_name)

print(' [*] Waiting for logs. To exit press CTRL+C')


def callback(ch, method, properties, body):
    print(" [x] %r" % body)


channel.basic_consume(callback,
                      queue=queue_name,
                      no_ack=True)

channel.start_consuming()

producer

import pika
import sys

credentials = pika.PlainCredentials('admin','123456')
connection = pika.BlockingConnection(pika.ConnectionParameters(
    '192.168.56.19',5672,'/',credentials))
channel = connection.channel()

channel.exchange_declare(exchange='Clogs',
                         type='fanout')

message = ' '.join(sys.argv[1:]) or "info: Hello World!"
channel.basic_publish(exchange='Clogs',
                      routing_key='',
                      body=message)
print(" [x] Sent %r" % message)
connection.close()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值