目录
- [简介](#简介)
- [安装与配置](#安装与配置)
- [安装 RabbitMQ](#安装-rabbitmq)
- [配置 RabbitMQ](#配置-rabbitmq)
- [基本概念](#基本概念)
- [消息](#消息)
- [队列](#队列)
- [交换器](#交换器)
- [绑定](#绑定)
- [第一个 RabbitMQ 应用](#第一个-rabbitmq-应用)
- [发送端](#发送端)
- [接收端](#接收端)
- [工作模式](#工作模式)
- [发布/订阅模式](#发布订阅模式)
- [路由模式](#路由模式)
- [主题模式](#主题模式)
- [RPC 模式](#rpc-模式)
- [高级特性](#高级特性)
- [持久化](#持久化)
- [发布确认](#发布确认)
- [公平分发](#公平分发)
- [总结](#总结)
简介
RabbitMQ 是一个开源的消息代理和队列服务器,它实现了 AMQP (Advanced Message Queuing Protocol) 协议。RabbitMQ 可以帮助开发者实现解耦、异步处理、流量削峰等应用场景。
安装与配置
安装 RabbitMQ
```bash
Ubuntu/Debian
sudo apt-get update
sudo apt-get install rabbitmq-server
CentOS/Fedora
sudo yum install epel-release
sudo yum install rabbitmq-server
启动服务
sudo service rabbitmq-server start
```
配置 RabbitMQ
```bash
开启管理插件
sudo rabbitmq-plugins enable rabbitmq_management
创建用户
rabbitmqctl add_user myuser mypassword
设置用户角色
rabbitmqctl set_user_tags myuser administrator
设置权限
rabbitmqctl set_permissions -p / myuser ".*" ".*" ".*"
```
基本概念
消息
消息是应用程序之间传递的数据单元。
队列
队列用于存储消息,直到它们被消费。
交换器
交换器负责将消息路由到一个或多个队列。
绑定
绑定告诉交换器如何将消息路由到队列。
第一个 RabbitMQ 应用
发送端
```python
import pika
connection = pika.BlockingConnection(pika.ConnectionParameters('localhost'))
channel = connection.channel()
channel.queue_declare(queue='hello')
channel.basic_publish(exchange='',
routing_key='hello',
body='Hello World!')
print(" [x] Sent 'Hello World!'")
connection.close()
```
接收端
```python
import pika
def callback(ch, method, properties, body):
print(" [x] Received %r" % body)
connection = pika.BlockingConnection(pika.ConnectionParameters('localhost'))
channel = connection.channel()
channel.queue_declare(queue='hello')
channel.basic_consume(queue='hello',
on_message_callback=callback,
auto_ack=True)
print(' [*] Waiting for messages. To exit press CTRL+C')
channel.start_consuming()
```
工作模式
发布/订阅模式
```python
发布者
channel.exchange_declare(exchange='logs', exchange_type='fanout')
result = channel.queue_declare(queue='', exclusive=True)
queue_name = result.method.queue
channel.queue_bind(exchange='logs', 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(queue=queue_name, on_message_callback=callback, auto_ack=True)
channel.start_consuming()
```
路由模式
```python
发布者
channel.exchange_declare(exchange='direct_logs', exchange_type='direct')
severity = sys.argv[1] if len(sys.argv) > 1 else 'info'
message = ' '.join(sys.argv[2:]) or 'Hello World!'
channel.basic_publish(exchange='direct_logs', routing_key=severity, body=message)
print(" [x] Sent %r:%r" % (severity, message))
connection.close()
```
主题模式
```python
发布者
channel.exchange_declare(exchange='topic_logs', exchange_type='topic')
routing_key = sys.argv[1] if len(sys.argv) > 2 else 'anonymous.info'
message = ' '.join(sys.argv[2:]) or 'Hello World!'
channel.basic_publish(exchange='topic_logs', routing_key=routing_key, body=message)
print(" [x] Sent %r:%r" % (routing_key, message))
connection.close()
```
RPC 模式
```python
客户端
response = None
corr_id = str(uuid.uuid4())
def on_response(ch, method, props, body):
global response
if corr_id == props.correlation_id:
response = body
channel.basic_consume(queue=callback_queue, on_message_callback=on_response, auto_ack=True)
channel.basic_publish(exchange='',
routing_key='rpc_queue',
properties=pika.BasicProperties(
reply_to=callback_queue,
correlation_id=corr_id,
),
body=str(n))
while response is None:
connection.process_data_events()
result = int(response)
```
高级特性
持久化
```python
channel.queue_declare(queue='task_queue', durable=True)
channel.basic_publish(exchange='',
routing_key='task_queue',
body=message,
properties=pika.BasicProperties(
delivery_mode = 2, # make message persistent
))
```
发布确认
```python
channel.confirm_delivery()
for i in range(1, 11):
msg = f'Message {i}'
channel.basic_publish(exchange='', routing_key='test_queue', body=msg)
print(f'Sent: {msg}')
```
公平分发
```python
channel.basic_qos(prefetch_count=1)