RabbitMQ是流行的开源消息队列系统,用erlang语言开发,RabbitMQ是AMQP的标准实现。写本篇文章之前,先了解下几个关于RabbitMQ重要的概念:
1、Exchange:交换机,决定了消息路由规则;
2、Queue:消息队列,每个消息都会被投入到一个或多个队列;
3、Channel:进行消息读写的通道,在客户端的每个连接里,可建立多个channel,每个channel代表一个会话任务;
4、Binding:绑定了Queue和Exchange,意即为符合什么样路由规则的消息,将会放置入哪一个消息对列;
5、Routing Key:路由关键字,exchange根据这个关键字进行消息投递;
6、vhost:虚拟主机,一个broker里可以开设多个vhost,用作不同用户的权限分离;
7、producer:消息生产者,就是投递消息的程序;
8、consumer:消息消费者,就是接受消息的程序;
RabbitMQ消息的核心思想是消息不直接发送到队列,而是发送到交换器中(exchange),实际上,一般的情况下,生产者可能不知道将消息发送到哪个队列上。交换器的作用就是将生产者发送的消息接收过来,然后推送到队列。至于交换器将接收到的消息怎么推送到对应的队列,或者按照什么规则将消息推送出去,这些规则则有交换器类型定义:交换器的类型常用有三种direct、topic,fanout。本文将讲解fanout类型的交换器,fanout 类型的交换器非常简单,它是将所有收到的消息广播到所有它所知道的队列。
下面是Spring整合RabbitMQ的示例:
一、消息发送者的application-mq.xml配置:
其中SpringAMQPJsonMessageConverter.java自定义用于封装消息转化,继承AbstractJsonMessageConverter:
public class SpringAMQPJsonMessageConverter extends AbstractJsonMessageConverter {
private String clzName;
public SpringAMQPJsonMessageConverter(String clzName) {
this.clzName = clzName;
}
@Override
protected Message createMessage(Object o, MessageProperties messageProperties) {
try {
String e = JSON.toJSONString(o);
byte[] bytes = e.getBytes(this.getDefaultCharset());
messageProperties.setContentType("application/json");
messageProperties.setContentEncoding(this.getDefaultCharset());
messageProperties.setContentLength((long)bytes.length);
return new Message(bytes, messageProperties);
} catch (Exception e) {
throw new MessageConversionException("error happened when create json message", e);
}
}
@Override
public Object fromMessage(Message message) throws MessageConversionException {
try {
byte[] body = message.getBody();
String bodyStr = new String(body, this.getDefaultCharset());
Class> clz = Class.forName(clzName);
return JSON.parseObject(bodyStr, clz);
} catch (Exception e) {
throw new MessageConversionException("error happened when parse json message", e);
}
}
}
TestMessageBO.java则封装了要发送消息的实体,内容略。
消息发送:
public class SpringAmqpTest {
@Autowired
private RabbitTemplate testTemplate;
@Test
public void testSend() {
TestMessageBO messageBO = new TestMessageBO();
messageBO.setXXX(id);
messageBO.setYYY("content")
testTemplate.convertAndSend(messageBO);//使用默认的路由键名:routingKey=""
}
}
至此完成了消息生产者的整合。下面是消息消费者的配置:
二、消息消费者的application-mq.xml配置:
消息消费consumer类:
public class TestMessageConsumer implements MessageConsumer {
private static final Logger LOGGER = LoggerFactory.getLogger(TestMessageConsumer.class);
@Override
public void onMessage(Object msg) {
try{
//接收的消息处理
} catch (Exception e) {
}
}
//其中MessageConsumer.java如下:
public interface MessageConsumer {
public void onMessage(Object msg);
}
至此完成了消息消费者的整合