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

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

声明临时队列(Temporary queues)

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

绑定(Bindings)

  • 绑定queue和exchange
channel.queueBind("队列名","exchange名","");

<二>、Direct

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

声明Exchange

channel.exchangeDeclare("exchange_direct", "direct");

发布消息

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

绑定(Bindings)

  • 绑定queue和exchange,可以带一个RouteKey参数,表示队列只对该routeKey的消息感兴趣
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

channel.exchangeDeclare("exchange_topic", "topic", false, true, null);

声明RouteKey

private final static String ROUTING_KEY = "log.info";

发布消息

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

绑定(Bindings)

  • 绑定queue和exchange,可以带一个RouteKey参数,表示队列只对该routeKey的消息感兴趣
  • 此时消费者的RouteKey可以带上通配符
private final static String ROUTING_KEY = "log.#";
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

channel.exchangeDeclare("exchange_topic", "headers");

声明键值对

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);

发布消息

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

消费者:

声明键值对

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,需要写成空字符串
 channel.queueBind(queueName, EXCHANGE_NAME, "", arguments);
// 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控制台

  • 19
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我爱夜来香A

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值