RabbitMQ 快速入门

1.简介

RabbitMQ是一个由erlang开发的AMQP(Advanced Message Queue protocol)的开源实现。AMQP高级消息队列,说白了就是一个开源的消息中间件。它能解决不同组件、模块、系统间消息通信。

2.系统架构

RabbitMQ Server: 也叫broker server,存储消息的地方

Producer:数据的发送方

Consumer:数据的接收方

Connection: 就是一个TCP的连接。Producer和Consumer都是通过TCP连接到RabbitMQ Server的。以后我们可以看到,程序的起始处就是建立这个TCP连接。

Channels: 虚拟连接。它建立在上述的TCP连接中。数据流动都是在Channel中进行的。也就是说,一般情况是程序起始建立TCP连接,第二步就是建立这个Channel。

 那么,为什么使用Channel,而不是直接使用TCP连接?

对于OS来说,建立和关闭TCP连接是有代价的,频繁的建立关闭TCP连接对于系统的性能有很大的影响,而且TCP的连接数也有限制,这也限制了系统处理高并发的能力。但是,在TCP连接中建立Channel是没有上述代价的。对于Producer或者Consumer来说,可以并发的使用多个Channel进行Publish或者Receive。

Message:消息。服务器和应用程序之间传递的数据,本质上就是一段数据,由Properties和Body组成。

Exchange:交换机。接收消息,根据路由键转发消息到绑定的队列。

Binding:Exchange和Queue之间的虚拟连接,binding中可以包含routing key。

Routing key:一个虚拟地址,虚拟机可用它来确定如何路由一个特定消息。

Queue:也称为Message Queue,消息队列,保存消息并将它们转发给消费者。

Virtual Host:其实是一个虚拟概念。类似于权限控制组,一个Virtual Host里面可以有若干个Exchange和Queue,可以用来隔离Exchange和Queue。,同一个Virtual Host里面不能有相同名称的Exchange和Queue。但是权限控制的最小粒度是Virtual Host。(下面会讲到)

3、图解

    1. 信息生产者将消息(message)发送到exchange

  2. exchange接受消息之后,负责将其路由到具体的队列中

  3. Bindings负责连接exchange和队列(queue)

  4. 消息到达队列(queue),然后等待被消息接收端处理

  5. 消息接收端处理消息

Exchanges有三种类型:direct, fanout,topic。 每个实现了不同的路由算法(routing algorithm)。

Direct exchange: 如果 routing key 匹配, 那么Message就会被传递到相应的queue中。其实在queue创建时,它会自动的以queue的名字作为routing key来绑定那个exchange。

Fanout exchange: 会向响应的queue广播。

Topic exchange: 对key进行模式匹配,比如ab*可以传递到所有ab*的queue。

Consumer和Procuder都可以通过 queue.declare 创建queue。如果queue已经存在,也不会报错。如果没有,要么发送不了消息,要么取不到消息,所以还是都创建吧。

Bindings就是将通过Exchange将queue和routing keys绑定。

总结:生产者将消息发送到Exchange交换机的,不是发送到Queue上的,生产者不知道消息是谁消费,有哪些消费者消费。Exchange根据一定的路由规则将消息转发到Queue。
消费者是监听队列的,不知道是哪个生产者发送的

4.具体代码

添加maven 依赖

<dependency>
            <groupId>com.rabbitmq</groupId>
            <artifactId>amqp-client</artifactId>
            <version>3.6.5</version>
        </dependency>

消费者

package com.flying.rabbitmq.quickstart;

import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import com.rabbitmq.client.QueueingConsumer;

import java.io.IOException;
import java.util.concurrent.TimeoutException;

public class Consumer {
    public static void main(String[] args) throws IOException, TimeoutException, InterruptedException {
        //创建connectionFactory 并进行配置
        ConnectionFactory connectionFactory=new ConnectionFactory();
        connectionFactory.setHost("127.0.0.1");
        connectionFactory.setPort(5672);
        connectionFactory.setVirtualHost("/");
        //2.通过连接工厂创建连接
        Connection connection=connectionFactory.newConnection();
        //3.通过connection 创建一个channel 通道
        Channel channel=connection.createChannel();
        //4 声明(创建)一个队列
        String queueName = "test001";
        channel.queueDeclare(queueName,true,false,false,null);
        //5.声明一个消费者
        QueueingConsumer queueingConsumer=new QueueingConsumer(channel);
        //6.设置Channel
        channel.basicConsume(queueName,true,queueingConsumer);
        while (true){
            //7.获取消息
            QueueingConsumer.Delivery delivery=queueingConsumer.nextDelivery();
            String msg=new String(delivery.getBody());
            System.err.println("消费端"+msg);
        }
    }
}

生产端

package com.flying.rabbitmq.quickstart;

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 并进行配置
        ConnectionFactory connectionFactory=new ConnectionFactory();
        connectionFactory.setHost("127.0.0.1");
        connectionFactory.setPort(5672);
        connectionFactory.setVirtualHost("/");
        //2.通过连接工厂创建连接
        Connection connection=connectionFactory.newConnection();
        //3.通过connection 创建一个channel 通道
        Channel channel=connection.createChannel();
        //4.通过Channel 发送数据
        for(int i=0; i < 5;i++){
            String msg="Hello rabbitmq";
            channel.basicPublish("","test001",null,msg.getBytes());
        }

        //5 记得要关闭相关的连接
        channel.close();
        connectionFactory.clone();

    }
}

运行结果

猜你喜欢

转载自www.cnblogs.com/lflying/p/11107150.html