公司的后台服务使用了Rabbitmq,在开发过程中,发现可能存在消息丢失问题,于是只能去盘RabbitMq-_-。使用RabbitMq不仅仅是向其发消息,收消息就完事,还要关注它的状态,在使用过程中,发现RabbitMq使用方式很像Mysql。
首先,我们使用RabbitMq不是发消息,收消息就完事,我们得查看RabbitMq的运行情况,看消息的生产和消费情况,这就得依赖其Manage UI和rabbitmqctl,这个就类似与mysql workbench或者Navicat。使用好这Manage UI,可以解决90%以上的问题。并且从这个ManageUI可以学习RabbitMQ的很多概念,比如virtual-host的概念,就像DB中的逻辑数据库,实现了逻辑隔离,并且其有一个默认的名字"/"。同时在Exchange页面,可以看到Exchange的四种类型:direct,topic,faout,headers。
exhange主要是方遍了我们向多个队列发消息的方式,就像以前我们自己寄信(queue),现在通过邮局寄信一样。对于4种exhange,我们通常会用到前三种。在使用exchange中,我们都是把数据放到exchange中,他们的差别主要在routing key的使用上。
direct:路由精确匹配
topic: 路由模糊匹配
faout: 向绑定的全部队列发消息
headers:通过匹配AMQP消息的header而非路由键, 不常用
而对于Queue,我们比较关心的就是其ack机制,即怎么保证消息不丢失。
看一下RabbitMQ常见的报错及其原因:
在ManageUI上,就可以测试收发消息,不过需要使用在Properties中加入"content_type":"application/json",否则是字节数据,如下
-30,-128,-100,-25,-126,-71,-27,-81,-71,-25,-126,-71,-30,-128,-99
使用了jackson的converter后,报了如下的错。
o.s.a.s.c.Jackson2JsonMessageConverter : Could not convert incoming message with content-type [text/plain], 'json' keyword missing.
如果在使用RabbitMq中,没有配置converter,则会报错:
org.springframework.messaging.converter.MessageConversionException:
Cannot convert from [[B] to [com.jms.entity.MaterialOrder]
for GenericMessage
如下两句,可以配置好converter,运行正常:
MessageConverter messageConverer = new ContentTypeDelegatingMessageConverter(new Jackson2JsonMessageConverter()) rabbitTemplate.setMessageConverter(messageConverter);
RabbitListener最好写在方法上,然后就可以用该方法接受参数,而不是在类上,否则会报错
No method found for class [B at org.springframework.amqp.rabbit.listener.adapter.DelegatingInvocableHandler
.getHandlerForPayload(...
参考资料: