开源消息中间件RabbitMQ

RabbitMQ

  • 二、开源消息中间件RabbitMQ
    • 1.RabbitMQ 简介
    • 2.RabbitMQ 整体逻辑架构
    • 3.RabbitMQ Exchange类型
    • 4.RabbitMQ 工作流程
    • 5.RabbitMQ 实践
      • 5.1 安装
      • 5.2 运行和管理
      • 5.3 Java客户端访问
    • 6.RabbitMQ 集群


二、开源消息中间件RabbitMQ

开源消息中间件RabbitMQ_第1张图片

1.RabbitMQ 简介

  RabbitMQ俗称“兔子MQ”(轻巧、敏捷),是目前热门的一款开源消息中间件,不管是互联网行业还是传统行业都广泛使用,它最早出现是为了解决电信行业系统之间的可靠通信而设计。

  1. 高可靠性、易扩展、高可用、功能丰富等。
  2. 支持大多数(甚至冷门)的编程语言客户端。
  3. RabbitMQ遵循AMQP协议,自身采用Erlang(由爱立信开发的通用面向并发编程的语言)编写(有兴趣的可以了解一下JMS规范和AMQP协议)。RabbitMQ也支持MQTT等其他协议。

2.RabbitMQ 整体逻辑架构

开源消息中间件RabbitMQ_第2张图片

3.RabbitMQ Exchange类型

  RabbitMQ常用的交换器类型有: fanout 、 direct 、 topic 、 headers 四种。

  1. direct(完全匹配模式):只会讲消息交给路由键和消息队列一致的消息队列。
  2. fanout(广播模式):会把所有发送到该交换器的消息路由到所有与该交换器绑定的队列中。
  3. topic(正则匹配模式):topic类型的交换器在direct匹配规则上进行了扩展,也是将消息路由到BindingKey和RoutingKey相匹配的队列中,这里的匹配规则稍微不同,它约定:BindingKey和RoutingKey一样都是由"."分隔的字符串;BindingKey中可以存在两种特殊字符“”和“#”,用于模糊匹配,其中"“用于匹配一个单词,”#"用于匹配多个单词(可以是0个)。
  4. headers(请求头模式):headers类型的交换器不依赖于路由键的匹配规则来路由信息,而是根据发送的消息内容中的headers属性进行匹配。不实用。

4.RabbitMQ 工作流程

– 生产者发送消息的流程

  1. 生产者连接RabbitMQ,建立TCP连接( Connection),开启信道(Channel)。
  2. 生产者声明一个Exchange(交换器),并设置相关属性,比如交换器类型、是否持久化等。
  3. 生产者声明一个队列并设置相关属性,比如是否排他、是否持久化、是否自动删除等。
  4. 生产者通过 bindingKey (绑定Key)将交换器和队列绑定( binding )起来。
  5. 生产者发送消息至RabbitMQ Broker,其中包含 routingKey (路由键)、交换器等信息。
  6. 相应的交换器根据接收到的 routingKey 查找相匹配的队列。
  7. 如果找到,则将从生产者发送过来的消息存入相应的队列中。
  8. 如果没有找到,则根据生产者配置的属性选择丢弃还是回退给生产者。
  9. 关闭信道。
  10. 关闭连接。

– 消费者接收消息的过程

  1. 消费者连接到RabbitMQ Broker ,建立一个连接(Connection ) ,开启一个信道(Channel) 。
  2. 消费者向RabbitMQ Broker 请求消费相应队列中的消息,可能会设置相应的回调函数, 以及做一些准备工作。
  3. 等待RabbitMQ Broker 回应并投递相应队列中的消息, 消费者接收消息。
  4. 消费者确认(ack) 接收到的消息。
  5. RabbitMQ从队列中删除相应己经被确认的消息。
  6. 关闭信道。
  7. 关闭连接。

5.RabbitMQ 实践

5.1 安装

首先安装Erlang(可以去Erlang官网下载)。
然后安装RabbitMQ(官网下载安装包,之后解压缩即可)。

5.2 运行和管理

  • 启动。到安装后的RabbitMQ所在目录下的 sbin 目录,直接执行 rabbitmq-server 。

./sbin/rabbitmq-server

  • 后台启动。让 RabbitMQ 以守护程序的方式在后台运行,则启动时加上 -detached参数。

./sbin/rabbitmq-server -detached

查询服务器状态。查询 RabbitMQ 服务器的状态信息可以用参数 status。

./sbin/rabbitmqctl status

  • 关闭 RabbitMQ 节点。如果要关闭整个 RabbitMQ 节点可以用参数 stop。

./sbin/rabbitmqctl stop

  • 关闭 RabbitMQ 应用程序。只想关闭应用程序,同时保持 Erlang 节点运行则可以用 stop_app。

./sbin/rabbitmqctl stop_app

等等…

5.3 Java客户端访问

&emcp;&emcp;RabbitMQ 支持多种语言,这里以 Java 为例。

  1. maven工程的pom文件中添加依赖
<dependency>
    <groupId>com.rabbitmq</groupId>
    <artifactId>amqp-client</artifactId>
    <version>4.1.0</version>
</dependency>
  1. 消息生产者
package org.study.rabbitmq;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
public class Producer {
     

    public static void main(String[] args) throws IOException, TimeoutException {
     
        //创建连接工厂
        ConnectionFactory factory = new ConnectionFactory();
        factory.setUsername("guest");
        factory.setPassword("guest");
        //设置 RabbitMQ 地址
        factory.setHost("localhost");
        //建立到代理服务器到连接
        Connection conn = factory.newConnection();
        //获得信道
        Channel channel = conn.createChannel();
        //声明交换器
        String exchangeName = "hello-exchange";
        channel.exchangeDeclare(exchangeName, "direct", true);

        String routingKey = "hola";
        //发布消息
        byte[] messageBodyBytes = "quit".getBytes();
        channel.basicPublish(exchangeName, routingKey, null, messageBodyBytes);

        channel.close();
        conn.close();
    }
}
  1. 消息消费者
package org.study.rabbitmq;
import com.rabbitmq.client.*;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
public class Consumer {
     

    public static void main(String[] args) throws IOException, TimeoutException {
     
        ConnectionFactory factory = new ConnectionFactory();
        factory.setUsername("guest");
        factory.setPassword("guest");
        factory.setHost("localhost");
        //建立到代理服务器到连接
        Connection conn = factory.newConnection();
        //获得信道
        final Channel channel = conn.createChannel();
        //声明交换器
        String exchangeName = "hello-exchange";
        channel.exchangeDeclare(exchangeName, "direct", true);
        //声明队列
        String queueName = channel.queueDeclare().getQueue();
        String routingKey = "hola";
        //绑定队列,通过键 hola 将队列和交换器绑定起来
        channel.queueBind(queueName, exchangeName, routingKey);

        while(true) {
     
            //消费消息
            boolean autoAck = false;
            String consumerTag = "";
            channel.basicConsume(queueName, autoAck, consumerTag, new DefaultConsumer(channel) {
     
                @Override
                public void handleDelivery(String consumerTag,
                                           Envelope envelope,
                                           AMQP.BasicProperties properties,
                                           byte[] body) throws IOException {
     
                    String routingKey = envelope.getRoutingKey();
                    String contentType = properties.getContentType();
                    System.out.println("消费的路由键:" + routingKey);
                    System.out.println("消费的内容类型:" + contentType);
                    long deliveryTag = envelope.getDeliveryTag();
                    //确认消息
                    channel.basicAck(deliveryTag, false);
                    System.out.println("消费的消息体内容:");
                    String bodyStr = new String(body, "UTF-8");
                    System.out.println(bodyStr);

                }
            });
        }
    }
}
  1. 启动 RabbitMQ服务器
./sbin/rabbitmq-server
  1. 运行 Consumer
    首先运行Consumer,当生产者发送消息时,能在消费者后端看到消息记录。
  2. 运行 Producer
    然后运行Producer,并发布一条消息,在Consumer的控制台能看到接收到消息。

6.RabbitMQ 集群

感兴趣的同学可以阅读相关文章,作者后续有阅读再更新。

你可能感兴趣的:(消息中间件,rabbitmq,分布式)