初次实践SpringBoot整合RabbitMQ

RabbitMQ

工作模式

消息队列,顾名思义就是将消息进行排队处理,后边来的消息进入不同的对列进行排队,然后消费者从队列中获取数据进行处理处理;
RabbitMQ的组件有生产者、消费者、交换机、队列、消息、路由等。他们之间的工作模式如下图所示:

  • Exchange和fanout-Exchange:
  • Direct-Exchange+路由消息模型:
  • Topic-Exchange+路有消息模型:

    (图片来源:https://blog.csdn.net/u013871100/article/details/82982235)

交换机模式

  • 交换的常用的模式有Fanout-Exchange、Direct-Exchange,Topic-Exchange;
    • Fanout-Exchange会忽略routingKey的绑定内容,它会将接收到的消息复制发送到每个绑定的每个队列(queue),而不会进行分流,它的作用相当于广播,对他的每个子队列都会发送消息;
    • Driect-Exchange:交换机会与队列以一个routing-key绑定起来,发送消息后,交换机会按照routing-key将消息发送到相应的队列中去;如果没有队列接收该routing-key则,该条消息将被丢弃;

安装RabbitMQ服务

  • 安装RabbitMQ之前需要先安装Erlang;
  • Erlang下载地址:http://www.erlang.org/downloads
  • 增加环境变量;
  • RabbitMQ下载地址:https://www.rabbitmq.com/releases/rabbitmq-server/v3.6.15/rabbitmq-server-3.6.15.exe
  • Linux在:这里查找相应的版本和安装包进行安装;
  • 安装并配置环境变量 RABBITMQ_HOME;步骤:我的电脑右击->系统->高级系统设置->环境变量->系统变量->新建;
    初次实践SpringBoot整合RabbitMQ_第1张图片
    再将其加入到Path变量中:
    初次实践SpringBoot整合RabbitMQ_第2张图片

SpringBoot整合RabbitMQ

引入pom依赖:

<dependency>
   <groupId>org.springframework.amqpgroupId>
   <artifactId>spring-rabbitartifactId> 
dependency>

配置文件中作如下配置

生产者代码如下:

1.  public class Send {  
3.  private final static String EXCHANGE_NAME = "test_exchange_direct";  

5.  public static void main(String[] argv) throws Exception {  

6.  // 获取到连接以及mq通道  

7.  Connection connection = ConnectionUtil.getConnection();  

8.  Channel channel = connection.createChannel();  

10.  //声明一个direct类型的exchange

11.  channel.exchangeDeclare(EXCHANGE_NAME, "direct");  

13.  // 消息内容  

14.  String message = "删除商品, id = 1001";  
//发送routing-key为delete的消息;
15.  channel.basicPublish(EXCHANGE_NAME, "delete", null, message.getBytes());  

16.  System.out.println(" [x] Sent '" + message + "'");  

18.  channel.close();  

19.  connection.close();  

20.  }  

21.  }

消费者代码如下:

1.  public class Recv {  

3.  private final static String QUEUE_NAME = "test_queue_direct_1";  

5.  private final static String EXCHANGE_NAME = "test_exchange_direct";  

7.  public static void main(String[] argv) throws Exception {  

9.  // 获取到连接以及mq通道  

10.  Connection connection = ConnectionUtil.getConnection();  

11.  Channel channel = connection.createChannel();  

13.  // 声明队列  

14.  channel.queueDeclare(QUEUE_NAME, false, false, false, null);  

16.  // 绑定队列到交换机 并接受routing-key为update的消息;

17.  channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, "update");  
//banding队列到交换机,并接收 rou't
18.  channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, "delete");  

20.  // 同一时刻服务器只会发一条消息给消费者  

21.  channel.basicQos(1);  

23.  // 定义队列的消费者  

24.  QueueingConsumer consumer = new QueueingConsumer(channel);  

25.  // 监听队列,手动返回完成  

26.  channel.basicConsume(QUEUE_NAME, false, consumer);  

28.  // 获取消息  

29.  while (true) {  

30.  QueueingConsumer.Delivery delivery = consumer.nextDelivery();  

31.  String message = new String(delivery.getBody());  

32.  System.out.println(" 前台系统: '" + message + "'");  

33.  Thread.sleep(10);  

35.  channel.basicAck(delivery.getEnvelope().getDeliveryTag(), false);  

36.  }  

37.  }  

38.  }

  • Topic-Exchange+路由消息模型是一个功能非常强大的交换机;它跟通配符结合可以代替上述两类交换机模型;
    • 通配符‘’表示匹配一个关键字:如test. 可以与test.student匹配;却无法与test.student.list匹配;
    • 通配符‘#’ 表示匹配0个或多个关键字;如上述例子,test.# 则可以与上述两个都可以匹配;
      生产者代码如下:
1.  public class Send {  

3.  private final static String EXCHANGE_NAME = "test_exchange_topic";  

5.  public static void main(String[] argv) throws Exception {  

6.  // 获取到连接以及mq通道  

7.  Connection connection = ConnectionUtil.getConnection();  

8.  Channel channel = connection.createChannel();  

10.  // 声明exchange  

11.  channel.exchangeDeclare(EXCHANGE_NAME, "topic");  

13.  // 消息内容  

14.  String message = "删除商品,id = 1001";  

15.  channel.basicPublish(EXCHANGE_NAME, "test.delete", null, message.getBytes());  

16.  System.out.println(" [x] Sent '" + message + "'");  

18.  channel.close();  

19.  connection.close();  

20.  }  

21.  }

消费者代码如下:

1.  public class Recv2 {  

3.  private final static String QUEUE_NAME = "test_queue_topic_2";  

5.  private final static String EXCHANGE_NAME = "test_exchange_topic";  

7.  public static void main(String[] argv) throws Exception {  

9.  // 获取到连接以及mq通道  

10.  Connection connection = ConnectionUtil.getConnection();  

11.  Channel channel = connection.createChannel();  

13.  // 声明队列  

14.  channel.queueDeclare(QUEUE_NAME, false, false, false, null);  

16.  // 绑定队列到交换机并以"test.#"为路由键  

17.  channel.queueBind(QUEUE_NAME, EXCHANGE_NAME, "test.#");  

19.  // 同一时刻服务器只会发一条消息给消费者  

20.  channel.basicQos(1);  

22.  // 定义队列的消费者  

23.  QueueingConsumer consumer = new QueueingConsumer(channel);  

24.  // 监听队列,手动返回完成  

25.  channel.basicConsume(QUEUE_NAME, false, consumer);  

27.  // 获取消息  

28.  while (true) {  

29.  QueueingConsumer.Delivery delivery = consumer.nextDelivery();  

30.  String message = new String(delivery.getBody());  

31.  System.out.println(" 搜索系统: '" + message + "'");  

32.  Thread.sleep(10);  

34.  channel.basicAck(delivery.getEnvelope().getDeliveryTag(), false);  

35.  }  

36.  }  

37.  }

此处的队列则可以接收任何以test. 开头的任何消息;
参照地址:https://blog.csdn.net/u013871100/article/details/82982235

你可能感兴趣的:(#,java学习笔记)