为了账号安全,请及时绑定邮箱和手机立即绑定

RabbitMQ资料:新手入门教程

标签:
中间件
概述

RabbitMQ 是一个开源的消息代理和队列服务器,支持多种消息传递模型,包括发布/订阅、请求/响应和路由模型。本文详细介绍了 RabbitMQ 的作用、应用场景、优势和安装配置方法,并提供了丰富的示例代码和常见问题解决方案。RabbitMQ 资料在此文章中得到了全面的阐述。

RabbitMQ简介

RabbitMQ 是一个开源的消息代理和队列服务器,其实现了高级消息队列协议(AMQP)。AMQP 是一种网络协议,它可以在网络和系统之间传输数据交换。RabbitMQ 是使用 Erlang 语言编写的,支持发布/订阅、请求/响应和路由等多种消息传递模型。

RabbitMQ的作用和应用场景

RabbitMQ 的主要作用是提供一个可靠的消息传递系统,它可以在不同的应用程序和系统之间传递消息。它的应用场景非常广泛,包括但不限于以下几种:

  • 解耦应用程序:通过使用 RabbitMQ,可以轻松地将应用程序解耦,使一个应用程序可以异步通信,而不会影响到另一个应用程序的正常运行。
  • 任务分发:可以将任务异步地分布到多个工作者(worker)上,从而提高系统的吞吐量。
  • 数据缓存:可以将某些数据缓存在消息队列中,以便后续处理。
  • 数据同步:可以通过 RabbitMQ 进行实时数据同步,确保不同系统之间的数据一致性。
  • 负载均衡:可以将请求分发给多个后端服务,从而实现负载均衡。
  • 日志聚合与分析:可以采集来自不同系统的日志并发送到消息队列,然后通过分析工具进行处理。
RabbitMQ的优势和特点

RabbitMQ 具有以下优势和特点:

  • 高可用性:RabbitMQ 支持集群模式,可以将多个节点组成一个集群,提高系统的可用性和可靠性。
  • 灵活性:支持多种消息传递模型,包括发布/订阅、请求/响应、路由等。
  • 可靠性:消息可以持久化存储,确保消息不会因为系统故障而丢失。
  • 可扩展性:可以通过增加更多的节点来扩展系统,提供更高的吞吐量和并发处理能力。
  • 社区支持:拥有庞大的开发者社区,以及大量的插件和工具支持。
  • 多种编程语言支持:支持多种编程语言,包括但不限于 Java、Python、Node.js、C#、PHP 等。
RabbitMQ安装与配置

安装 RabbitMQ 可以在不同的操作系统上进行,这里主要介绍在 Windows 和 Linux 上的安装方法。

在不同操作系统上的安装方法

Windows 安装

  1. 下载 RabbitMQ Windows 版本

    • 访问 RabbitMQ 官方下载页面,选择适合 Windows 版本的安装包。
    • 目前最新版本为 3.10.x,下载的文件名类似于 rabbitmq-server-windows-3.10.1-super-20221014.zip。
  2. 安装和配置 Erlang

    • RabbitMQ 需要依赖 Erlang 环境,因此需要首先安装 Erlang。
    • 访问 Erlang 官方下载页面,下载适合 Windows 系统的安装包。
    • 安装 Erlang,配置好环境变量 Path 指向 Erlang 的安装路径。
  3. 解压并安装 RabbitMQ

    • 将下载的 RabbitMQ 压缩包解压到指定目录。
    • 执行解压目录中的 rabbitmq-service.bat 脚本,安装 RabbitMQ 服务。
    • 使用 rabbitmq-plugins.bat enable rabbitmq_management 命令,启用 RabbitMQ 管理插件。
  4. 启动服务
    • 使用 rabbitmq-service.bat install 命令安装 RabbitMQ 服务。
    • 使用 rabbitmq-service.bat start 命令启动服务。
    • 使用 rabbitmq-service.bat status 命令检查服务状态。

Linux 安装

  1. 安装 Erlang

    • 在 Ubuntu 上安装 Erlang:
      sudo apt-get update
      sudo apt-get install erlang
  2. 安装 RabbitMQ

    • 在 Ubuntu 上安装 RabbitMQ:
      sudo apt-get update
      sudo apt-get install rabbitmq-server
  3. 启用管理插件

    • 启用 RabbitMQ 管理插件:
      sudo rabbitmq-plugins enable rabbitmq_management
  4. 启动 RabbitMQ

    • 启动 RabbitMQ 服务:
      sudo systemctl start rabbitmq-server
    • 设置 RabbitMQ 服务开机自启动:
      sudo systemctl enable rabbitmq-server
  5. 访问管理界面
    • 默认情况下,管理界面可通过 http://localhost:15672 访问。
    • 默认的用户名和密码为 guestguest
基本配置步骤和注意事项
  1. 修改默认配置

    • RabbitMQ 的默认配置文件位于 /etc/rabbitmq/rabbitmq.conf
    • 可以根据需要修改配置文件中的参数,例如设置虚拟主机、用户权限等。
    • 示例代码:修改默认配置
      # 复制默认配置文件
      sudo cp /etc/rabbitmq/rabbitmq.conf /etc/rabbitmq/rabbitmq.conf.default
      # 修改配置文件中的参数
      sudo nano /etc/rabbitmq/rabbitmq.conf
  2. 配置虚拟主机和用户

    • 创建虚拟主机:
      rabbitmqctl add_vhost /myvhost
    • 创建用户并设置权限:
      rabbitmqctl add_user myuser mypassword
      rabbitmqctl set_permissions -p /myvhost myuser ".*" ".*" ".*"
  3. 配置网络绑定

    • 如果需要 RabbitMQ 通过网络访问,可以修改 /etc/rabbitmq/rabbitmq.conf 文件中的 loopback_users 参数。
    • 例如,允许所有用户通过网络访问:
      loopback_users = none
  4. 配置磁盘配额
    • 可以配置 RabbitMQ 的磁盘配额,避免磁盘空间耗尽。
    • 配置文件中的 disk_free_limit 参数可以设置磁盘空间限制。
验证安装是否成功
  1. 检查 RabbitMQ 服务状态

    • 在 Windows 上使用 rabbitmq-service.bat status
    • 在 Linux 上使用 sudo systemctl status rabbitmq-server
  2. 访问管理界面

    • 打开浏览器,访问 http://localhost:15672
    • 使用默认用户名和密码 guest/guest 登录。
  3. 创建测试消息
    • 使用 rabbitmqadmin 工具发送一条测试消息。
    • 例如,发送一条消息到指定队列:
      rabbitmqadmin publish vhost=/ myqueue message='Hello, RabbitMQ!'
RabbitMQ基本概念

RabbitMQ 的核心组件包括交换机(Exchange)、队列(Queue)、消息(Message)和绑定(Binding)。

交换机(Exchange)

交换机是消息传递的核心,它负责将消息传递到合适的队列中。在 RabbitMQ 中,交换机的工作方式是由其类型决定的,常见的交换机类型包括:

  • Direct(直接)交换机:消息按照路由键(Routing Key)进行路由。
  • Fanout(广播)交换机:消息广播到所有绑定到该交换机的队列。
  • Topic(主题)交换机:按照路由键模式匹配进行路由。
  • Headers(头)交换机:按照消息头进行路由。

示例代码:创建一个 Direct 交换机

import pika

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

channel.exchange_declare(exchange='direct_logs', exchange_type='direct')

channel.close()
connection.close()
队列(Queue)

队列是消息的存储容器。消息在队列中等待被消费者(Consumer)接收和处理。队列可以配置持久化,即消息可以被存储在磁盘上,从而增加系统的可靠性。

示例代码:创建一个持久化的队列

import pika

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

channel.queue_declare(queue='hello', durable=True)

channel.close()
connection.close()
消息(Message)

消息是 RabbitMQ 中的基本传输单位。消息包含两个部分:一个可选的属性(metadata)头,以及一个指定传输的消息体(payload)。消息可以被持久化,这样即使在 RabbitMQ 重启后,消息也不会丢失。

示例代码:发送一条持久化消息

import pika

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

channel.queue_declare(queue='hello', durable=True)

channel.basic_publish(exchange='',
                      routing_key='hello',
                      body='Hello World!',
                      properties=pika.BasicProperties(
                         delivery_mode = 2, # 消息持久化
                      ))

channel.close()
connection.close()
绑定(Binding)

绑定是交换机和队列之间的关联关系。一个队列可以通过绑定到交换机来接收消息。绑定可以包含一个路由键(Routing Key),用于指定消息的路由方式。

示例代码:为队列与 Direct 交换机绑定

import pika

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

channel.exchange_declare(exchange='direct_logs', exchange_type='direct')

channel.queue_declare(queue='hello', durable=True)

channel.queue_bind(exchange='direct_logs',
                   queue='hello',
                   routing_key='hello')

channel.close()
connection.close()
RabbitMQ常用操作

RabbitMQ 中的主要操作包括发布(Publish)消息、订阅(Subscribe)消息、消费(Consume)消息以及关闭连接和通道。

发布(Publish)消息

发布消息是将消息发送到指定交换机的操作。发布消息时可以指定消息的路由键,以便交换机根据路由键将消息路由到合适的队列。

示例代码:发布消息到 Direct 交换机

import pika

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

channel.exchange_declare(exchange='direct_logs', exchange_type='direct')

channel.basic_publish(exchange='direct_logs',
                      routing_key='hello',
                      body='Hello World!',
                      properties=pika.BasicProperties(
                         delivery_mode = 2, # 消息持久化
                      ))

print(" [x] Sent 'Hello World!'")
channel.close()
connection.close()
订阅(Subscribe)消息

订阅消息是将队列绑定到交换机的操作。队列通过绑定到交换机来接收消息。

示例代码:订阅消息到 Direct 交换机

import pika

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

channel.exchange_declare(exchange='direct_logs', exchange_type='direct')

channel.queue_declare(queue='hello', durable=True)

channel.queue_bind(exchange='direct_logs',
                   queue='hello',
                   routing_key='hello')

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

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

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

消费消息是接收并处理队列中的消息。消费者通过 basic_consume 方法订阅队列,并通过回调函数处理接收到的消息。

示例代码:消费 Direct 交换机中的消息

import pika

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

channel.exchange_declare(exchange='direct_logs', exchange_type='direct')

channel.queue_declare(queue='hello', durable=True)

channel.queue_bind(exchange='direct_logs',
                   queue='hello',
                   routing_key='hello')

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

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

print(' [*] Waiting for messages. To exit press CTRL+C')
channel.start_consuming()
关闭连接和通道

在完成消息传递操作后,需要关闭通道和连接,以释放系统资源。

示例代码:关闭连接和通道

import pika

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

# 发布消息
channel.exchange_declare(exchange='direct_logs', exchange_type='direct')
channel.basic_publish(exchange='direct_logs',
                      routing_key='hello',
                      body='Hello World!',
                      properties=pika.BasicProperties(
                         delivery_mode = 2, # 消息持久化
                      ))

# 订阅消息
channel.queue_declare(queue='hello', durable=True)
channel.queue_bind(exchange='direct_logs',
                   queue='hello',
                   routing_key='hello')

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

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

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

# 关闭连接和通道
channel.close()
connection.close()
RabbitMQ常见问题与解决方案

在使用 RabbitMQ 的过程中可能会遇到各种问题,以下是一些常见的错误代码及解释,以及相应的排查方法和性能优化策略。

常见错误代码及解释
  • 403:权限不足。通常是因为用户没有足够的权限访问特定的虚拟主机或资源。
  • 404:资源未找到。通常是因为尝试访问的队列、交换机或其他资源不存在。
  • 500:内部服务器错误。通常是因为 RabbitMQ 服务器遇到不可预见的问题。
  • 400:请求错误。通常是因为客户端发送的请求不符合预期格式。
常见问题排查方法
  • 检查用户权限:使用 rabbitmqctl list_users 列出所有用户,使用 rabbitmqctl list_vhosts 列出所有虚拟主机,使用 rabbitmqctl list_permissions -p / 查看特定虚拟主机的权限。
  • 检查队列和交换机是否存在:使用 rabbitmqadmin list queuesrabbitmqadmin list exchanges 查看队列和交换机的状态。
  • 检查网络连接:确保 RabbitMQ 服务已启动,并且可以从客户端访问。
常见性能优化策略
  • 使用集群:通过将多个节点组成一个集群,可以提高系统的可用性和可靠性。
  • 合理配置磁盘配额:避免磁盘空间耗尽,影响系统性能。
  • 优化消息持久化设置:合理配置消息的持久化设置,避免不必要的磁盘写操作。
  • 使用消息确认机制:通过消息确认机制确保消息被正确接收和处理。
  • 监控和日志:通过监控工具收集系统性能数据,并通过日志分析系统状态。
RabbitMQ实践案例

在实际应用中,RabbitMQ 可以实现多种消息传递模式,包括发布/订阅、请求/响应和路由模式。以下是一些简单的案例示例。

简单的发布/订阅模式示例

发布/订阅模式是一种消息传递模式,其中消息广播到所有订阅该主题的消费者。

发布者代码示例

import pika

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

channel.exchange_declare(exchange='logs',
                         exchange_type='fanout')

channel.basic_publish(exchange='logs',
                      routing_key='',
                      body='Hello World!',
                      properties=pika.BasicProperties(
                         delivery_mode = 2, # 消息持久化
                      ))

print(" [x] Sent 'Hello World!'")
channel.close()
connection.close()

订阅者代码示例

import pika

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

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)

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

channel.basic_consume(queue=queue_name,
                      on_message_callback=callback,
                      auto_ack=True)

print(' [*] Waiting for messages. To exit press CTRL+C')
channel.start_consuming()
请求/响应模式示例

请求/响应模式是一种同步消息传递模式,其中客户端发送请求消息,服务端发送响应消息。

发起请求的客户端代码示例

import pika
import uuid

class FibonacciRpcClient:
    def __init__(self):
        self.connection = pika.BlockingConnection(pika.ConnectionParameters('localhost'))
        self.channel = self.connection.channel()
        result = self.channel.queue_declare(queue='', exclusive=True)
        self.callback_queue = result.method.queue
        self.channel.basic_consume(
            queue=self.callback_queue,
            on_message_callback=self.on_response,
            auto_ack=True)
        self.response = None

    def on_response(self, ch, method, props, body):
        if self.corr_id == props.correlation_id:
            self.response = body

    def call(self, n):
        self.corr_id = str(uuid.uuid4())
        self.channel.basic_publish(
            exchange='',
            routing_key='rpc_queue',
            properties=pika.BasicProperties(reply_to=self.callback_queue, correlation_id=self.corr_id),
            body=str(n))
        while self.response is None:
            self.connection.process_data_events()
        return int(self.response)

fibonacci_rpc = FibonacciRpcClient()
print(" [x] Requesting fib(30)")
response = fibonacci_rpc.call(30)
print(" [.] Got %r" % response)

响应服务端代码示例

import pika
import time

def fib(n):
    if n == 0:
        return 0
    elif n == 1:
        return 1
    else:
        return fib(n-1) + fib(n-2)

def on_request(ch, body):
    n = int(body)
    print(" [.] fib(%s)" % n)
    response = fib(n)
    ch.basic_publish(exchange='',
                     routing_key='',
                     properties=pika.BasicProperties(content_type='application/json'),
                     body=str(response))
    ch.basic_ack(delivery_tag=ch.delivery_tag)

connection = pika.BlockingConnection(pika.ConnectionParameters('localhost'))
channel = connection.channel()
channel.queue_declare(queue='rpc_queue')

channel.basic_qos(prefetch_count=1)
channel.basic_consume(queue='rpc_queue', on_message_callback=on_request)

print(" [x] Awaiting RPC requests")
channel.start_consuming()
路由模式示例

路由模式是一种消息传递模式,其中消息根据路由键(Routing Key)进行路由。

发布者代码示例

import pika

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

channel.exchange_declare(exchange='topic_logs',
                         exchange_type='topic')

channel.basic_publish(exchange='topic_logs',
                      routing_key='kern.info',
                      body='Hello World!',
                      properties=pika.BasicProperties(
                         delivery_mode = 2, # 消息持久化
                      ))

print(" [x] Sent 'Hello World!'")
channel.close()
connection.close()

订阅者代码示例

import pika

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

channel.exchange_declare(exchange='topic_logs',
                         exchange_type='topic')

result = channel.queue_declare(queue='', exclusive=True)
queue_name = result.method.queue

channel.queue_bind(exchange='topic_logs',
                   queue=queue_name,
                   routing_key='kern.*')

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

channel.basic_consume(queue=queue_name,
                      on_message_callback=callback,
                      auto_ack=True)

print(' [*] Waiting for messages. To exit press CTRL+C')
channel.start_consuming()
点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消