SpringBoot+Rabbit

1.安装Rabbit,参考(https://www.cnblogs.com/ericli-ericli/p/5902270.html

2.进入http://localhost:15672,账户密码都是   guest

3.新建一个消息队列

 Durability:选择Transient。

4.新建一个交换机exchange

 

 解释①    这个是消息队列的名字  queue1  。

        ②    Routing key  正则表达式去匹配对应的key,从头开始匹配

5.java代码实现

(1)在pom文件引入jar包

<!-- 添加springboot对amqp的支持 -->
<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-amqp</artifactId>
</dependency>

(2)新建2个SpeingBoot项目   receive、sender

         在启动项加注解  @EnableRabbit;

          在配置文件加配置:

spring:
  application:
    name: sender
  rabbitmq:
    host: 127.0.0.1
    port: 5672
    username: guest
    password: guest

       

         新建发送类

import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class HelloSender {

   @Autowired
   private AmqpTemplate amqpTemplate;

   public void send(String va){
      amqpTemplate.convertAndSend("queue","queue",va);
      System.out.print("OK");
   }
}

备注:convertAndSend中3个参数的含义,第一个是交换机的名字,第二个是对应Routing key 的值(有可能第二个参数是queue123,Routing key 的值也可以是queue,因为是正则表达式从头匹配的,不同的策略不同的计算方法),第三个是消息内容

(3)新建测试类

        

@SpringBootTest(classes = SenderApplication.class)
@RunWith(SpringJUnit4ClassRunner.class)
public class TestRabbitMQ {

   @Autowired
   private HelloSender helloSender;

   @Test
   public void testRabbit() {
      helloSender.send("wdwdwd12312s");
   }
}

至此发送端简单发送成功

(4)在receive项目中引入jar包,启动项加注解,和发送端相同;

         新建监听消息队列接口

        

import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

@Component
public class HelloReceive {
   @RabbitListener(queues = "queue1")
   public void processC(String str) {
      System.out.println("Receive:"+str);
   }
}

至此整个简单的发送和接收都能起作用。

至于Rebbit的基本知识可以百度

6.RabbitMQ是通过Binding将Exchange和Queue链接在一起,这样Exchange就知道如何将消息准确的推送到Queue中去

7.在绑定(Binding)Exchange和Queue的同时,一般会指定一个Binding Key,生产者将消息发送给Exchange的时候,一般会产生一个Routing Key,当Routing Key和Binding Key对应上的时候,消息就会发送到对应的Queue中去。那么Exchange有四种类型,不同的类型有着不同的策略。也就是表明不同的类型将决定绑定的Queue不同,换言之就是说生产者发送了一个消息,Routing Key的规则是A,那么生产者会将Routing Key=A的消息推送到Exchange中,这时候Exchange中会有自己的规则,对应的规则去筛选生产者发来的消息,如果能够对应上Exchange的内部规则就将消息推送到对应的Queue中去。那么接下来就来详细讲解下Exchange里面类型。

     Exchange Type

    我来用表格来描述下类型以及类型之间的区别。

  • fanout

        fanout类型的Exchange路由规则非常简单,它会把所有发送到该Exchange的消息路由到所有与它绑定的Queue中。

    上图所示,生产者(P)生产消息1将消息1推送到Exchange,由于Exchange Type=fanout这时候会遵循fanout的规则将消息推送到所有与它绑定Queue,也就是图上的两个Queue最后两个消费者消费。

  • direct

        direct类型的Exchange路由规则也很简单,它会把消息路由到那些binding key与routing key完全匹配的Queue中

     当生产者(P)发送消息时Rotuing key=booking时,这时候将消息传送给Exchange,Exchange获取到生产者发送过来消息后,会根据自身的规则进行与匹配相应的Queue,这时发现Queue1和Queue2都符合,就会将消息传送给这两个队列,如果我们以Rotuing key=create和Rotuing key=confirm发送消息时,这时消息只会被推送到Queue2队列中,其他Routing Key的消息将会被丢弃。

  • topic

      前面提到的direct规则是严格意义上的匹配,换言之Routing Key必须与Binding Key相匹配的时候才将消息传送给Queue,那么topic这个规则就是模糊匹配,可以通过通配符满足一部分规则就可以传送。它的约定是:

  1. routing key为一个句点号“. ”分隔的字符串(我们将被句点号“. ”分隔开的每一段独立的字符串称为一个单词),如“stock.usd.nyse”、“nyse.vmw”、“quick.orange.rabbit”
  2. binding key与routing key一样也是句点号“. ”分隔的字符串
  3. binding key中可以存在两种特殊字符“*”与“#”,用于做模糊匹配,其中“*”用于匹配一个单词,“#”用于匹配多个单词(可以是零个)

  当生产者发送消息Routing Key=F.C.E的时候,这时候只满足Queue1,所以会被路由到Queue中,如果Routing Key=A.C.E这时候会被同是路由到Queue1和Queue2中,如果Routing Key=A.F.B时,这里只会发送一条消息到Queue2中。

  • headers

headers类型的Exchange不依赖于routing key与binding key的匹配规则来路由消息,而是根据发送的消息内容中的headers属性进行匹配。
在绑定Queue与Exchange时指定一组键值对;当消息发送到Exchange时,RabbitMQ会取到该消息的headers(也是一个键值对的形式),对比其中的键值对是否完全匹配Queue与Exchange绑定时指定的键值对;如果完全匹配则消息会路由到该Queue,否则不会路由到该Queue。
该类型的Exchange没有用到过(不过也应该很有用武之地),所以不做介绍。

这里在对其进行简要的表格整理:

Exchange规则
类型名称 类型描述
fanout 把所有发送到该Exchange的消息路由到所有与它绑定的Queue中
direct Routing Key==Binding Key
topic 我这里自己总结的简称模糊匹配
headers Exchange不依赖于routing key与binding key的匹配规则来路由消息,而是根据发送的消息内容中的headers属性进行匹配。

  补充说明:

  ConnectionFactory、Connection、Channel

  ConnectionFactory、Connection、Channel都是RabbitMQ对外提供的API中最基本的对象。Connection是RabbitMQ的socket链接,它封装了socket协议相关部分逻辑。ConnectionFactory为Connection的制造工厂。
  Channel是我们与RabbitMQ打交道的最重要的一个接口,我们大部分的业务操作是在Channel这个接口中完成的,包括定义Queue、定义Exchange、绑定Queue与Exchange、发布消息等。

  Connection就是建立一个TCP连接,生产者和消费者的都是通过TCP的连接到RabbitMQ Server中的,这个后续会再程序中体现出来。

  Channel虚拟连接,建立在上面TCP连接的基础上,数据流动都是通过Channel来进行的。为什么不是直接建立在TCP的基础上进行数据流动呢?如果建立在TCP的基础上进行数据流动,建立和关闭TCP连接有代价。频繁的建立关闭TCP连接对于系统的性能有很大的影响,而且TCP的连接数也有限制,这也限制了系统处理高并发的能力。但是,在TCP连接中建立Channel是没有上述代价的。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章