都是坑!!!
①配置文件@Configuration写法,不会创建交换机和队列,会报错。
可以尝试手动创建配合使用(未检验)
②利用注解开发(@RabbitListener+属性+注解),会自动创建交换机和队列,但是要去【15672】检查,第一次可能会报错(未找到原因)
yml配置
spring:
rabbitmq:
host: 127.0.0.1 #ip
port: 5672 #端口
username: guest #账号
password: guest #密码
virtualHost: #链接的虚拟主机
addresses: 127.0.0.1:5672 #多个以逗号分隔,与host功能一样。
requestedHeartbeat: 60 #指定心跳超时,单位秒,0为不指定;默认60s
publisherConfirms: true #发布确认机制是否启用
publisherReturns: #发布返回是否启用
connectionTimeout: #链接超时。单位ms。0表示无穷大不超时
### ssl相关
ssl:
enabled: #是否支持ssl
keyStore: #指定持有SSL certificate的key store的路径
keyStoreType: #key store类型 默认PKCS12
keyStorePassword: #指定访问key store的密码
trustStore: #指定持有SSL certificates的Trust store
trustStoreType: #默认JKS
trustStorePassword: #访问密码
algorithm: #ssl使用的算法,例如,TLSv1.1
verifyHostname: #是否开启hostname验证
### cache相关
cache:
channel:
size: #缓存中保持的channel数量
checkoutTimeout: #当缓存数量被设置时,从缓存中获取一个channel的超时时间,单位毫秒;如果为0,则总是创建一个新channel
connection:
mode: #连接工厂缓存模式:CHANNEL 和 CONNECTION
size: #缓存的连接数,只有是CONNECTION模式时生效
### listener
listener:
type: #两种类型,SIMPLE,DIRECT
## simple类型
simple:
concurrency: #最小消费者数量
maxConcurrency: #最大的消费者数量
transactionSize: #指定一个事务处理的消息数量,最好是小于等于prefetch的数量
missingQueuesFatal: #是否停止容器当容器中的队列不可用
## 与direct相同配置部分
autoStartup: #是否自动启动容器
acknowledgeMode: #表示消息确认方式,其有三种配置方式,分别是none、manual和auto;默认auto
prefetch: #指定一个请求能处理多少个消息,如果有事务的话,必须大于等于transaction数量
defaultRequeueRejected: #决定被拒绝的消息是否重新入队;默认是true(与参数acknowledge-mode有关系)
idleEventInterval: #container events发布频率,单位ms
##重试机制
retry:
stateless: #有无状态
enabled: #是否开启
maxAttempts: #最大重试次数,默认3
initialInterval: #重试间隔
multiplier: #对于上一次重试的乘数
maxInterval: #最大重试时间间隔
direct:
consumersPerQueue: #每个队列消费者数量
missingQueuesFatal:
#...其余配置看上方公共配置
## template相关
template:
mandatory: #是否启用强制信息;默认false
receiveTimeout: #`receive()`接收方法超时时间
replyTimeout: #`sendAndReceive()`超时时间
exchange: #默认的交换机
routingKey: #默认的路由
defaultReceiveQueue: #默认的接收队列
## retry重试相关
retry:
enabled: #是否开启
maxAttempts: #最大重试次数
initialInterval: #重试间隔
multiplier: #失败间隔乘数
maxInterval: #最大间隔
常用的消息模型
Fanout Exchange:广播
生产者代码:
@Autowired
private RabbitTemplate rabbitTemplate;
@GetMapping("/fanout")
public Result fanout(){
rabbitTemplate.convertAndSend("fanoutExchange","","这里是广播生产者!");
System.out.println("发送广播成功!");
return Result.success("发送广播成功!");
}
消费者代码:
@Component
public class consumer1 {
@RabbitListener(bindings = {
@QueueBinding(value = @Queue(value = "fanout.a"),
exchange = @Exchange(value = "fanoutExchange"))
})
public void fanoutReceiverA(String msg){
System.out.println("接收者A = " + msg);
}
@RabbitListener(bindings = {
@QueueBinding(value = @Queue(value = "fanout.b"),
exchange = @Exchange(value = "fanoutExchange"))
})
public void fanoutReceiverB(String msg){
System.out.println("接收者B = " + msg);
}
}
Direct Exchange:路由
生产者:
rabbitTemplate.convertAndSend("fanoutExchange","yellow","这里是广播生产者!");
消费者:
@RabbitListener(bindings = {
@QueueBinding(value = @Queue(value = "fanout.a"),
exchange = @Exchange(value = "fanoutExchange",type = ExchangeTypes.DIRECT),
key = {"red","blue"})
})
public void fanoutReceiverA(String msg){
System.out.println("接收者A = " + msg);
}
@RabbitListener(bindings = {
@QueueBinding(value = @Queue(value = "fanout.b"),
exchange = @Exchange(value = "fanoutExchange", type = ExchangeTypes.DIRECT),
key = {"red","yellow"})
})
public void fanoutReceiverB(String msg){
System.out.println("接收者B = " + msg);
}
发布订阅-TopicExchange
TopicExchange与DirectExchange类似,区别在于routingKey必须是多个单词的列表,并且以 . 分割。
Queue与Exchange指定BindingKey时可以使用通配符:
#:代指0个或多个单词
*:代指一个单词
生产者:
rabbitTemplate.convertAndSend("fanoutExchange","aaa.news","这里是广播生产者!");
消费者:
@RabbitListener(bindings = {
@QueueBinding(value = @Queue(value = "fanout.a"),
exchange = @Exchange(value = "fanoutExchange",type = ExchangeTypes.TOPIC),
key = "china.#")
})
public void fanoutReceiverA(String msg){
System.out.println("接收者A = " + msg);
}
@RabbitListener(bindings = {
@QueueBinding(value = @Queue(value = "fanout.b"),
exchange = @Exchange(value = "fanoutExchange", type = ExchangeTypes.TOPIC),
key = "#.news")
})
public void fanoutReceiverB(String msg){
System.out.println("接收者B = " + msg);
}
注意:
描述下Direct交换机与Topic交换机的差异?
Topic交换机接收的消息RoutingKey必须是多个单词,以 . 分割
Topic交换机与队列绑定时的bindingKey可以指定通配符
#:代表0个或多个词
*:代表1个词