内置交换机类型
Fanout
fanout英文是扇形,分裂的意思。
将接受到的消息广播到所有已知队列。
Direct
a message goes to the queues whose binding key exactly matches the routing key of the message.
直接模式,比fanout模式更精确。只有队列的绑定的routingKey和消息publish的时候一致,exchange才会将该消息投递到此队列。fanout类型的交换机routingKey参数就没有意义会失效。
channel.queueBind(queue, exchange, routingKey)
默认交换机(default exchange)也是direct模式。默认交换机说明:
The default exchange is implicitly bound to every queue, with a routing key equal to the queue name. It is not possible to explicitly bind to, or unbind from the default exchange. It also cannot be deleted.
默认交换机默认绑定到每个队列,routeKey是队列名字。默认交换机不能明确的进行绑定使用
也不能解绑。不能被删除。
图虫队列Q1绑定了一个routeKey (orange),Q2绑定了两个key(black,green)。当消息发布绑定的key是orange交换机会将消息投递给Q1,Q2不会收到消息。同理black和green。
当交换机收到消息没有匹配的routekey时就会丢弃消息。
Topic
主题模式,就是多种规则主题订阅。
这种模式在publish消息时routekey不能是任意的,必须单词列表,用"."分割。就是将消息属性分类。key的长度最长是255个字节。
channel.basicPublish(exchange, routingKey, props, message);
例如新闻类消息,发布一条消息可以根据消息内容定义三级分类:
发布所有NBA消息,这个消息属性就是:体育.篮球.NBA。key便可以定义为sport.baskball.nba。
就是将消息抽象分类。
这时候一个队列关注nba消息的话就可以绑定该key。
channel.queueBind(queue, exchange, "sport.baskball.nba")
该队列就可以收到nba类的消息。如果有发布一条cba消息(sport.baskball.cba)这个队列也关注的话需要再绑定这个key。这样进行一一绑定其实和direct模式功效是一样的。如果是这样使用的话topic就没什么意义了。
主题模式消费绑定有两个特殊绑定方式:
- * (star) can substitute for exactly one word.
- # (hash) can substitute for zero or more words.
*可以匹配一个单词。前面说了key可以被分解成多个单词使用"."分割。
#可以匹配0-n个单词
这样前面例子即关注nba又关注cba消息,绑定key就可以用“sport.baskball.*”。也就关注所有足球方面消息。同理如果需要所有体育类消息就可以绑定key为:“sport.#”。#匹配多个单词。
当一个队列绑定key为"#",接收所有消息。当即不使用"*","#"进行路由绑定时,那么这个topic交换机类型其实就等价于direct模式。
官方图例:
小结
主题模式就是发布时候将路由key值根据消息内容分类定义多个单词。订阅者根据自己需求可以进行多个模糊匹配。
Headers
用的比较少。通过设置header参数匹配进行队列消息投递。一般不用这么复杂的匹配,direct类型的单路由key匹配就可以满足需求。
发送消息
AMQP.BasicProperties props = new AMQP.BasicProperties.Builder().
//设置props的header
headers(Map<String,Object> headers).build();
channel.basicPublish(String exchange, String routingKey, BasicProperties props, byte[] body)
队列与交换机绑定
channel.queueBind(String queue, String exchange, String routingKey,Map<String,Object> arguments);
//最后一个参数就是指定与header属性里的匹配项
注意 :以x-开头的参数名不会参与匹配。
x-match:参数指定匹配规则.x-match:all表示完全匹配所有的header属性,any表示任一条匹配即可。
常用方法
定义
方法1:
channel.exchangeDeclare(String exchange,BuiltinExchangeType type);
BuiltinExchangeType是一个枚举类,可选值有:
DIRECT , FANOUT , TOPIC , HEADERS
方法2:
channel.exchangeDeclare(String exchange,String type);
直接使用字符串值指定类型。(“direct”,“fanout”,“topic”)。
发布消息绑定
channel.basicPublish(String exchange, String routingKey, BasicProperties props, byte[] body)
exchange:交换机名字
routingKey:路由key
props:消息属性
body:消息内容
消费绑定
channel.queueBind(String queue, String exchange, String routingKey)
queue:队列名称
exchange:交换机名称
routingKey:路由key。和发布对应。
总结
fanout模式就是广播,不需要路由key。交换机会将消息投递到所有绑定的队列。
direct模式是有选择的进行消息发送,只有路由key匹配的进行投放消息到队列。选择性投递消息。
topic模式也是选择新的转发消息。按路由规则进行匹配。按模式匹配。
header模式是比direct更精细匹配。可以多个属性值进行匹配,不依赖路由,可以将路由key丰富成一个对象。
交换机类型 | 是否需要路由key | 接受消息队列 |
---|---|---|
fanout | 否 | 所有绑定的队列 |
direct | 是 | 路由匹配的队列 |
topic | 是 | 路由规则匹配的队列(一组) |
header | 否 | header属性值匹配的队列 |
参考:
https://www.rabbitmq.com/getstarted.html
https://www.rabbitmq.com/tutorials/amqp-concepts.html