执行流程:

    

java rabbitmq 生产者发送topic消息 rabbitmq 消息发送的流程_java

组成部分说明如下:


Broker:消息队列服务进程,此进程包括两个部分:Exchange和Queue。 Exchange:消息队列交换机,按一定的规则将消息路由转发到某个队列,对消息进行过虑。 Queue:消息队列,存储消息的队列,消息到达队列并转发给指定的消费方。 Producer:消息生产者,即生产方客户端,生产方客户端将消息发送到MQ。 Consumer:消息消费者,即消费方客户端,接收MQ转发的消息。


消息发布接收流程:

  • ----发送消息-----

1 、生产者和Broker建立TCP连接。

2 、生产者和Broker建立通道。

3 、生产者通过通道消息发送给Broker,由Exchange将消息进行转发。

4 、Exchange将消息转发到指定的Queue(队列)

- ---接收消息-----

1 、消费者和Broker建立TCP连接

2 、消费者和Broker建立通道

3 、消费者监听指定的Queue(队列)

4 、当有消息到达Queue时Broker默认将消息推送给消费者。

5 、消费者接收到消息。

1,创建maven项目,在pom.xml中加入依赖

<!-- rabbitmq依赖   -->
    <dependency>
      <groupId>com.rabbitmq</groupId>
      <artifactId>amqp-client</artifactId>
      <version>4.0.3</version>
    </dependency>

2,创建生产者类

package cn.pika.mq;

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

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

/**
 * 生产者01
 */
public class Producer01 {

    //队列的名称
    private static final String QUEUE="hello_queue";

    public static void main(String[] args) {
        Connection connection=null;
        Channel channel=null;
        try {
            //1,创建链接的工厂对象
            ConnectionFactory factory = new ConnectionFactory();
            //1.1 设置链接的参数
            factory.setHost("localhost");   //本地链接地址
            factory.setPort(5672);          //端口号
            factory.setUsername("guest");   //用户名
            factory.setPassword("guest");   //密码
            factory.setVirtualHost("/");    //rabbitmq默认虚拟机名称为“/”,虚拟机相当于一个独立的mq服务器
            //1.2 创建链接对象
            connection =factory.newConnection();

            //2,创建与Exchange(交换机)的通道,每个连接可以创建多个通道,每个通道代表一个会话任务
            channel =connection.createChannel();

            //3,声明一个队列,如果Rabbit中没有此队列将自动创建
            /**
             * 参数介绍:
             *      * param1:队列名称
             *      * param2:是否持久化,若持久化,mq重启后该队列仍然存在
             *      * param3:队列是否独占此连接,队列只允许在该连接中访问,如果连接关闭,则队列自动删除
             *      * param4:队列不再使用时是否自动删除此队列
             *      * param5:扩展参数
             */
            channel.queueDeclare(QUEUE,true,false,false,null);

            //4,发送消息
                // 定义发送的消息内容
            String message="hello word 皮卡丘~"+System.currentTimeMillis();
            /**
             *       * param1:Exchange(交换机)的名称,如果没有指定,则使用Default Exchange 注意:不可以写null
             *       * param2:routingKey,消息的路由Key,是用于Exchange(交换机)将消息转发到指定的消息队列
             *       * param3:消息包含的属性,没有可以写null
             *       * param4:消息体,要发送的消息,字节数组 byte【】类型
             */
            channel.basicPublish("",QUEUE,null,message.getBytes());
            System.out.println("发送的消息是:"+message);


        } catch (IOException e) {
            e.printStackTrace();
        } catch (TimeoutException e) {
            e.printStackTrace();
        }finally {
                try {
                    //5,关闭连接对象,倒着关!
                    if(channel != null){
                        channel.close();
                    }
                    if(connection != null){
                        connection.close();
                    }

                } catch (IOException | TimeoutException e) {
                    e.printStackTrace();
                }
        }
    }
}

3,创建消费者类

package cn.pika.mq;

import com.rabbitmq.client.*;

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

/**
 * 消费者01类
 */
public class Consumer01 {
    //队列的名称
    private static final String QUEUE="hello_queue";

    public static void main(String[] args) {
        Connection connection = null;
        Channel channel = null;
        try {
            //1,创建链接的工厂对象
            ConnectionFactory factory = new ConnectionFactory();
            //1.1 设置链接的参数
            factory.setHost("localhost");   //本地链接地址
            factory.setPort(5672);          //端口号
            factory.setUsername("guest");   //用户名
            factory.setPassword("guest");   //密码
            factory.setVirtualHost("/");    //rabbitmq默认虚拟机名称为“/”,虚拟机相当于一个独立的mq服务器
            //1.2 创建链接对象
            connection =factory.newConnection();

            //2,创建与Exchange(交换机)的通道,每个连接可以创建多个通道,每个通道代表一个会话任务
            channel =connection.createChannel();

            //3,声明一个队列,如果Rabbit中没有此队列将自动创建
            /**
             * 参数介绍:
             *      * param1:队列名称
             *      * param2:是否持久化,若持久化,mq重启后该队列仍然存在
             *      * param3:队列是否独占此连接,队列只允许在该连接中访问,如果连接关闭,则队列自动删除
             *      * param4:队列不再使用时是否自动删除此队列
             *      * param5:扩展参数
             */
            channel.queueDeclare(QUEUE,true,false,false,null);

            //4,定义消费方法,监听到队列中有消息以后要做什么
            DefaultConsumer consumer = new DefaultConsumer(channel){

                //4.1重写handleDelivery()方法,消费着接受消息以后会自动调用此方法
                /**
                 *
                 * @param consumerTag 消费者的标签,在channel.basicConsume()去指定
                 * @param envelope    消息包的内容,可从中获取消息id,消息routingkey,交换机,消息和重传标志(收到消息失败后是否需要重新发送)
                 * @param properties
                 * @param body 消息体(接受到的消息内容)
                 * @throws IOException
                 */
                @Override
                public void handleDelivery(String consumerTag, Envelope envelope,
                                           AMQP.BasicProperties properties, byte[] body) throws IOException {
                    //4.2 获取接收到的消息
                    String message=new String(body);
                    System.out.println("接收到的消息是:"+message);
                }
            };

            //5,监听队列
            /**
             * 参数1:String queue:队列名称
             * 参数2:boolean autoAck:是否自动回复,设置为true为表示消息接收到自动向mq回复接收到了,mq接收到回复会删除消息,设置为false则需要手动回复
             * 参数3:Consumer callback:消费方法,消费者接收到消息后调用此方法
             */
            channel.basicConsume(QUEUE,true,consumer);
        } catch (TimeoutException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

4,运行生产者,在运行消费者!

结果:消费者接收到了生产者着发送的消息。