消息中间件RabbitMQ

ubuntu下安装:

先安装erlang,因为rabbitmq是基于erlang开发的

$ sudo apt-get update

$ sudo apt-get install erlang

完成后控制台输入erl 如下图显示说明安装成功

python发消息到kafka python发送mq消息_python发消息到kafka


再安装rabbitmq

sudo apt-get install rabbitmq-server

使用:

先用rabbitmq发送个helloworld

python发消息到kafka python发送mq消息_用户名_02


P为生产者,即主动发送消息;C为消费者,即接受消息。中间的为传输队列。

发送者 send.py 的实现:
建立连接:

import pika
# 建立连接
# 中间件和发送者在同一台机器,则host为localhsot。host为安装了rabbitmq的机器的ip
connection = pika.BlockingConnection(pika.ConnectionParameters('localhost'))
channel = connection.channel()

创建接受消息的队列:

channel.queue_declare(queue='hello')  # 创建一个名为hello的队列

此时send.py已做好了发送的准备,要将 字符串"hello world"发送到名字为“hello”的队列。
但消息不能直接发送到队列,需要通过exchange(交换器),先用默认的exchange,稍后再将exchange是什么。

channel.basic_publish(exchange='',  #空串,定义默认的exchange
                      routing_key='hello',  # 队列名称需要routing_key指定
                      body='Hello World!')  # 需要发送的内容'Hello World!'
print(" [x] Sent 'Hello World!'")

在退出程序之前,通过close()可以确保网络缓冲区已刷新,并且我们的消息已传递到rabbitmq。

connection.close()

生产者 send.py 完整的代码:

import pika
# 建立连接
# 中间件和发送者在同一台机器,则host为localhsot
connection = pika.BlockingConnection(pika.ConnectionParameters('localhost'))
channel = connection.channel()

channel.queue_declare(queue='hello')  # 创建一个名为hello的队列

channel.basic_publish(exchange='',  #空串,定义默认的exchange
                      routing_key='hello',  # 队列名称需要routing_key指定
                      body='Hello World!')  # 需要发送的内容'Hello World!'
print(" [x] Sent 'Hello World!'")
connection.close()  # 关闭连接

此时生产者,即发送者写好了,开始写消费者 receive.py 同样先连接上:

import pika
# 建立连接
# 中间件和接受在同一台机器,则host为localhsot
connection = pika.BlockingConnection(pika.ConnectionParameters('localhost'))
channel = connection.channel()

声明一个队列,从这个队列接受数据

channel.queue_declare(queue='hello')  #建立队列,名字为‘hello’

之前在生产者中已经声明了一个队列‘hello’,消费者怎么又声明一次呢?这是因为我们不确定生产者和消费者哪个程序先运行,为了保证队列一定存在,所以在两个程序中都声明了名为‘hello’的队列。
放心,channel.queue_declare(queue=‘hello’)这句话不管执行多少次,都会只生成一个名为‘hello’的队列。

当消费者接受消息时,触发回调函数,打印出接受到的消息

# 回调函数
def callback(ch, method, properties, body):
    print(" [x] Received %r" % body)
channel.basic_consume(callback,  # 指明回调函数
                      queue='hello',  # 指明队列为‘hello’
                      no_ack=True)  # no_ack=True是接收到消息后不用给生产者发确认消息

开始无限循环的接受消息,并随时调用callback处理消息

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

消费者 receive.py 的完整代码:

import pika

connection = pika.BlockingConnection(pika.ConnectionParameters(host='localhost'))
channel = connection.channel()


channel.queue_declare(queue='hello')

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

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

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

启动两个程序后,消费者一直等待消息的到来,程序 receive.py 不会停止。

如果rabbitmq服务没有启动,则会报错误 :
“由于目标计算机积极拒绝,无法连接。”
所以首先要保证rabbitmq服务已启动,rabbitmq的安装我就不说了。

本来到这里发送‘helloworld’就结束了,但这个例子是生产者和消费者和rabbitmq在同一台机子上。下面说一下远程连接。

我的rabbitmq安装在A机器上,生产者 send.py 也在A机器上,所以生产者连接rabbitmq时,host为localhost。即
connection = pika.BlockingConnection(pika.ConnectionParameters(host=‘localhost’))
但消费者 receive.py 在B机器上,所以消费者连接时, host=A机器的ip,即
connection = pika.BlockingConnection(pika.ConnectionParameters(host=‘A的ip地址’))

此时运行B上的消费者 receive.py 时会报错:
“ pika.exceptions.ProbableAuthenticationError: (403, ‘ACCESS_REFUSED - Login was refused using authentication mechanism PLAIN. For details see the broker logfile.’) ”

因为远程连接时要为rabbitmq建立一个用户,然后用用户名和密码来远程连接,所以B机上的消费者 receive.py在连接rabbitmq时的代码为

username = 'username'  #指定远程rabbitmq的用户名
pwd = 'password'       #指定远程rabbitmq的密码

user_pwd = pika.PlainCredentials(username, pwd)

connection = pika.BlockingConnection(pika.ConnectionParameters(host='192.168.2.174', credentials=user_pwd))
channel = connection.channel()

下面说一下在怎么配置这个用户名,在安装有rabbitmq的电脑上
rabbitmqctl list_users          //查看所有用户
rabbitmqctl add_user username password         //新建用户并设置密码
rabbitmqctl set_user_tags username administrator          //新建用户配置为administrator的角色,超级管理员
rabbitmqctl set_permissions -p / username ‘.*’ ‘.*’ ‘.*’          //为新建用户配置权限
此时就可以用这个用户来远程访问了。

其他常用命令:

service rabbitmq-server status 查看状态
rabbitmq-server start & 后台启动rabbitmq
rabbitmq-plugins list 查看rabbitmq插件
sudo rabbitmq-plugins enable rabbitmq_management 启动管控台,页面端口为15672