目录

Rabbitmq基础

RabbitMQ

一、核心概念和组件

1、Broker

  • 一个RabbitMQ实例就是一个Broker

2、Virtual Host

  • 虚拟主机。相当于Mysql的Database,一个Broker上可以存在多个vhost,vhost之间可以相互隔离。每个vhost都有自己的队列、交换机、绑定和权限机制。vhost必须在连接时指定,默认的vhost是/

3、Exchange

  • 负责接收生产者发送的消息,并将消息路由到Queue。Exchange可以通过不同的类型和配置来实现不同的路由逻辑,常见的Exchange类型有:Direct、Topic、Headers、Fanout

4、Queue

  • 负责存储消息,并将消息传递给消费者。Queue可以通过不同的配置来实现不同的消息处理逻辑,例如:消息持久化、消息优先级、消息抵消等

5、Binding

  • 负责将Exchange和Queue连接起来,实现消息路由。Binging可以通过配置Exchange和Queue之间的关系,实现不同的路由逻辑

6、Message

  • 实际发送的消息内容,可以是任何可以被序列化的数据,例如:字符串、对象、文件等

7、Connection

  • 生产者/消费者与broker之间的TCP连接

8、Channel

  • 管道,一条双向数据流通道。不管是发布消息、订阅队列还是接收消息,这些动作都是通过管道完成。因为对于操作系统来说,建立和销毁TCP都是非常昂贵的开销,所以引入管道的概念,以复用一条TCP连接

二、Exchange

<一>、fanout(广播)

  • 路由规则非常简单,不需要处理RouteKey,会把所有发送到fanout Exchange的消息都会被转发到与该Exchange绑定(Binding)的所有Queue上

声明Exchange

java 复制代码
channel.exchangeDeclare("exchange_fanout", "fanout");
//将消息发送给exchange
channel.basicPublish("exchange_fanout","",null,msg.getBytes);

声明临时队列(Temporary queues)

  • 一个non_durable(不持久化的)、exclusive(单独的)、autodelete(随着消费者的消亡自动删除)、random(随机命名)的队列
java 复制代码
String queueName = channel.queueDeclare().getQueue();

绑定(Bindings)

  • 绑定queue和exchange
java 复制代码
channel.queueBind("队列名","exchange名","");

<二>、Direct

  • exchange和queue通过routeKey绑定,消息传递时,RouteKey必须完全匹配,才会被队列接收,否则该消息会被抛弃

声明Exchange

java 复制代码
channel.exchangeDeclare("exchange_direct", "direct");

发布消息

  • 发布消息时带上RouteKey
java 复制代码
channel.basicPublish("exchange_direct","routeKey_direct",null,msg.getBytes);

绑定(Bindings)

  • 绑定queue和exchange,可以带一个RouteKey参数,表示队列只对该routeKey的消息感兴趣
java 复制代码
channel.queueBind(queueName,exchangeName,RouteKey);

<三>、topic

direct类型的Exchange路由规则是完全匹配binding Key与RouteKey,但这种严格的匹配方式在很多情况下不能满足实际业务需求,topic类型的exchange在匹配规则上进行了扩展,它约定:

  • a)、routekey为一个句点号"."分隔的字符串,如"stock.usd.nyse"、"nyse.vmw"、"quick.orange.rabbit"
  • b)、binding key与routekey一样也是句点号"."分隔的字符串
  • c)、binding key可以存在两种特殊字符""与"#",用于做模糊匹配,其中'"'用于匹配一个单词,"#"用于匹配多个单词(可以是零个)

所有发送到Topic Exchange的消息被转发到所有关心RouteKey指定Topic的Queue上,声明多个RouteKey,同时声明多个Binding Key进行模糊匹配,比如"log.#"能够匹配到"log.info.oa",但是"log.",只会匹配到log.error

声明Exchange

java 复制代码
channel.exchangeDeclare("exchange_topic", "topic", false, true, null);

声明RouteKey

java 复制代码
private final static String ROUTING_KEY = "log.info";

发布消息

  • 发布消息时带上RouteKey
java 复制代码
channel.basicPublish("exchange_topic", ROUTING_KEY, null, msg.getBytes);

绑定(Bindings)

  • 绑定queue和exchange,可以带一个RouteKey参数,表示队列只对该routeKey的消息感兴趣
  • 此时消费者的RouteKey可以带上通配符
java 复制代码
private final static String ROUTING_KEY = "log.#";
java 复制代码
channel.queueBind(queueName,exchangeName,ROUTING_KEY );

<四>、headers

  • headers类型的exchange不依赖于routekey与binding key的匹配规则来路由消息,而是根据发送的消息内容中的headers属性进行匹配
  • 在绑定queue与exchange时指定一组键值对;当消息发送到Exchange时,rabbitmq会取到该消息的headers(也是一个键值对的形式),对比其中的键值对是否完全匹配Queue与Exchange绑定时指定的键值对;如果完全匹配则消息会路由到该Queue,否则不会路由到该Queue

fanout和headers类型都不需要路由键routeKey,交换时通过Headers头部来将消息映射到队列的,Hash结构中要求携带一个键"x-match",这个键的Value可以是Any或者All,这代表消息携带的Hash是需要全部匹配(all),还是仅匹配一个键Any就可以了,相比直连交换机,首部交换机的优势是匹配的规则不被限定为字符串(string)而是Object类型

  • any:只要在发布消息时携带的有一对键值对headers满足队列定义的多个参数arguments的其中一个就能匹配上,注意这里是键值对的完全匹配,只匹配到键了,值却不一样是不行的
  • all:在发布消息时携带的所有Entry必须和绑定在队列上的所有Entry完全匹配

生产者:

声明Exchange

java 复制代码
channel.exchangeDeclare("exchange_topic", "headers");

声明键值对

java 复制代码
Map<String, Object> heardersMap = new HashMap<String, Object>();
heardersMap.put("api", "login");
heardersMap.put("version", 1.0);
heardersMap.put("radom", UUID.randomUUID().toString());
BasicProperties.Builder properties = new BasicProperties().builder().headers(heardersMap);

发布消息

  • 发布消息时带上键值对
java 复制代码
channel.basicPublish(EXCHANGE_NAME, "", properties.build(), msg.getBytes());

消费者:

声明键值对

java 复制代码
Map<String, Object> arguments = new HashMap<String, Object>();
arguments.put("x-match", "any");
arguments.put("api", "login");
arguments.put("version", 1.0);
arguments.put("dataType", "json");

绑定(Bindings)

  • 绑定queue和exchange,无需路由键RouteKey,但是仍然不能写成null,需要写成空字符串
java 复制代码
 channel.queueBind(queueName, EXCHANGE_NAME, "", arguments);
java 复制代码
// all:匹配失败,缺少{"dataType", "json"}
Map<String, Object> heardersMap = new HashMap<String, Object>();
heardersMap.put("api", "login");
heardersMap.put("version", 1.0);

// all:匹配成功,生产者多发送一个head没关系
Map<String, Object> heardersMap = new HashMap<String, Object>();
heardersMap.put("api", "login");
heardersMap.put("version", 1.0);
heardersMap.put("dataType", "json");
heardersMap.put("ext", false);

Map<String, Object> arguments = new HashMap<String, Object>();
arguments.put("x-match", "all");
arguments.put("api", "login");
arguments.put("version", 1.0);
arguments.put("dataType", "json");

//------------------------------------------
// any: 匹配成功,只要有一个键值对能满足队列的arguments即可
Map<String, Object> heardersMap = new HashMap<String, Object>();
heardersMap.put("api", "login");

Map<String, Object> arguments = new HashMap<String, Object>();
arguments.put("x-match", "any");
arguments.put("api", "login");
arguments.put("version", 1.0);
arguments.put("dataType", "json");

// any: 匹配失败,键值对中的key和value必须全部匹配上
Map<String, Object> heardersMap = new HashMap<String, Object>();
heardersMap.put("api", "regist");

Map<String, Object> arguments = new HashMap<String, Object>();
arguments.put("x-match", "any");
arguments.put("api", "login");
arguments.put("version", 1.0);
arguments.put("dataType", "json");

三、RabbitMQ控制台

本文是转载文章,点击查看原文
如有侵权,请联系 xyy@jishuzhan.net 删除
相关推荐
点纭2 分钟前
JBDC Java数据库连接(1)
java·数据库·oracle
kill bert7 分钟前
Java八股文背诵 第六天 pring MVC spring Boot Java 新特性
java·spring boot·mvc
suimeng69 分钟前
Java的Selenium元素定位-cssSelector
java·selenium
RainbowSea14 分钟前
10. RabbitMQ 负载集群的详细搭建以及“镜像队列”的搭建配置说明
java·消息队列·rabbitmq
RainbowSea25 分钟前
9. RabbitMQ 消息队列幂等性,优先级队列,惰性队列的详细说明
java·消息队列·rabbitmq
时光呢29 分钟前
‌Spring 事务传播属性和隔离级别
java·数据库
LUCIAZZZ32 分钟前
说一下java的探针agent的应用场景
java·spring boot·spring·agent·链路追踪
玦尘、41 分钟前
计网相关面试题
java·计算机网络·面试题
步行cgn42 分钟前
红黑树(Red-Black Tree)核心知识点与面试高频问题
java·面试·职场和发展