• 第四章 第一个rabbitmq程序


    rabbitmq消息发送模型

    要素:

    • 生产者
    • 消费者
    • 交换器:生产者将消息发送到交换器
    • 队列:交换器通过某种路由规则绑定到指定队列,将消息加入队列,消费者从队列消费消息

    前提:

    引入rabbitmq的java客户端jar包

            <!-- import rabbitmq/amqp-client -->
            <dependency>
                <groupId>com.rabbitmq</groupId>
                <artifactId>amqp-client</artifactId>
                <version>3.5.6</version>
            </dependency>

    一、消息生产者

    1、代码:

     1 package com.xxx.producer;
     2 
     3 import java.io.IOException;
     4 import java.util.concurrent.TimeoutException;
     5 
     6 import com.rabbitmq.client.Channel;
     7 import com.rabbitmq.client.Connection;
     8 import com.rabbitmq.client.ConnectionFactory;
     9 
    10 /**
    11  * 消息生产者
    12  */
    13 public class HelloWorldProducer {
    14     private static final String QUEUE_NAME    = "helloQueue";
    15     private static final String EXCHANGE_NAME = "helloExchange";
    16 
    17     public static void main(String[] args) throws IOException, TimeoutException {
    18         ConnectionFactory factory = new ConnectionFactory();// 建立连接工厂
    19         factory.setHost("192.168.20.238");// 设置rabbitmq服务器地址
    20         factory.setPort(5672);// 设置rabbitmq服务器端口
    21         factory.setUsername("zhaojigang");
    22         factory.setPassword("wangna");
    23         factory.setVirtualHost("zhaojigangvhost");
    24 
    25         Connection connection = factory.newConnection();// 建立连接
    26         Channel channel = connection.createChannel();// 建立信道
    27 
    28         /**
    29          * queueDeclare(String queue, boolean durable, boolean exclusive, boolean autoDelete, Map<String, Object> arguments)
    30          * durable:队列是否持久化
    31          * exclusive:当最后一个消费者取消订阅时,是否自动删除
    32          * autoDelete:只有当前应用程序才能够消费队列消息(场景:限制一个队列只有一个消费者)
    33          * arguments:other properties (construction arguments) for the queue
    34          */
    35         channel.queueDeclare(QUEUE_NAME, false, false, false, null);// 创建队列(如果队列不存在,创建;如果存在,什么都不做)
    36         /**
    37          * exchangeDeclare(String exchange, String type, boolean durable, boolean autoDelete, Map<String, Object> arguments)
    38          * exchange:交换器名字
    39          * type:3种类型 direct/fanout/topic
    40          */
    41         channel.exchangeDeclare(EXCHANGE_NAME, "direct", false, false, null);
    42 
    43         for (int i = 0; i < 10; i++) {
    44             String msg = "helloworld_" + i;// 创建消息
    45             /**
    46              * basicPublish(String exchange, String routingKey, BasicProperties props, byte[] body)
    47              * exchange:交换器
    48              * routingKey:路由键
    49              * props:other properties for the message - routing headers etc
    50              * body:消息体
    51              */
    52             channel.basicPublish(EXCHANGE_NAME, QUEUE_NAME, null, msg.getBytes());// 发布消息
    53             System.out.println("发送消息:msg-->" + msg);
    54         }
    55 
    56         channel.close();// 关闭信道
    57         connection.close();// 关闭连接
    58     }
    59 }

    2、步骤:

    • 创建并设置连接工厂
      • host、port、username、password、vhost
      • 值得注意的是,一定要现在rabbitmq server上把username和password设置好,并且开启该用户在指定vhost上的权限,才可以设置连接工厂成功
    • 创建连接
    • 创建信道
    • 创建队列
    • 创建交换器
    • 创建(创建之后也可以配置消息)并发送消息
    • 关闭信道
    • 关闭连接

    3、注意点:

    • queueDeclare方法:如果队列不存在,创建;如果存在,什么都不做

    • basicPublish:发布消息到指定的交换器,并制定路由规则(用于消费者部分的绑定操作)

    二、消息消费者

    1、代码:

     1 package com.xxx.consumer;
     2 
     3 import java.io.IOException;
     4 import java.util.concurrent.TimeoutException;
     5 
     6 import com.rabbitmq.client.Channel;
     7 import com.rabbitmq.client.Connection;
     8 import com.rabbitmq.client.ConnectionFactory;
     9 import com.rabbitmq.client.Consumer;
    10 import com.rabbitmq.client.DefaultConsumer;
    11 import com.rabbitmq.client.Envelope;
    12 import com.rabbitmq.client.AMQP.BasicProperties;
    13 
    14 /**
    15  * 消息消费者
    16  */
    17 public class HelloWorldConsumer {
    18     private final static String QUEUE_NAME = "helloQueue";
    19     private static final String EXCHANGE_NAME = "helloExchange";
    20 
    21     public static void main(String[] args) throws IOException, TimeoutException {
    22         ConnectionFactory factory = new ConnectionFactory();// 建立连接工厂
    23         factory.setHost("192.168.20.238");// 设置rabbitmq服务器地址
    24         factory.setPort(5672);// 设置rabbitmq服务器端口
    25         factory.setUsername("zhaojigang");
    26         factory.setPassword("wangna");
    27         factory.setVirtualHost("zhaojigangvhost");
    28 
    29         Connection connection = factory.newConnection();// 建立连接
    30         Channel channel = connection.createChannel();// 建立信道
    31 
    32         /**
    33          * Note that we declare the queue here, as well. 
    34          * Because we might start the receiver before the sender, 
    35          * we want to make sure the queue exists before we try to consume messages from it.
    36          */
    37         channel.queueDeclare(QUEUE_NAME, false, false, false, null);// 创建队列(如果队列不存在,创建;如果存在,什么都不做)
    38         channel.exchangeDeclare(EXCHANGE_NAME, "direct", false, false, null);
    39         /**
    40          * queueBind(String queue, String exchange, String routingKey)
    41          */
    42         channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, QUEUE_NAME);
    43         Consumer consumer = new DefaultConsumer(channel){
    44             @Override
    45             public void handleDelivery(String consumerTag, 
    46                                        Envelope envelope, 
    47                                        BasicProperties properties,
    48                                        byte[] body) throws IOException {
    49                 String msg = new String(body,"UTF-8");
    50                 System.out.println("接收消息:msg-->" + msg);
    51             }
    52         };54             /**
    55              * basicConsume(String queue, boolean autoAck, Consumer callback)
    56              * autoAck true if the server should consider messages acknowledged once delivered; 
    57              * false if the server should expect explicit acknowledgements
              * 这里启动一个consume,该consume会不断的接收消息,如果此处用while(true)包起来的话,就会不断的启动consume
    58 */ 59 channel.basicConsume(QUEUE_NAME, true, consumer);61 62 // channel.close();// 关闭信道 63 // connection.close();// 关闭连接 64 } 65 }

    2、步骤:

    • 创建并设置连接工厂
      • host、port、username、password、vhost
    • 创建连接
    • 创建信道
    • 创建队列
    • 创建交换器
    • 通过路由规则绑定队列和交换器
    • 创建消息处理函数
    • 从队列获取消息并消费消息(根据消息处理函数)

    三、测试

    1、启动rabbitmq服务器

    2、启动消费者进程

    3、启动生产者进程

    4、查看console即可或者查看rabbitmq的webUI

  • 相关阅读:
    AtCoder 杂题乱写
    JOISC2020 遗迹
    【考试总结】20220107
    AGC021F Trinity
    CCPC2021 广州A/CF Gym103415A
    【考试总结】20220115
    JDK8 时间api当天的开始和截至时间
    技术方案模板
    正则表达式
    组合算法
  • 原文地址:https://www.cnblogs.com/java-zhao/p/5672771.html
Copyright © 2020-2023  润新知