SpringInAction 第八章 发送异步消息
第八章 发送异步消息
8.1 使用JMX发送消息
JMX是一个标准,定义了消息代理(message broker)的通用API,就想JDBC为数据库访问提供了通用接口一样。
JMX长期以来一直是异步消息首选方案。
8.1.1 搭建JMX环境
启动器可以使用ActiveMQ或者ActiveMQ Artemis(重新实现的下一代ActiveMQ)。
- Artemis:默认情况下运行在61616端口
8.1.2 使用JmsTemplate发送消息
JmsTemplate是Spring对JMS集成支持功能的核心,与其他模块类似,消除了大量传统使用方式的样板代码
public void send(MessageCreator messageCreator);
public void send(Destination destination, MessageCreator messageCreator);
public void send(String destinationName, MessageCreator messageCreator);
public void convertAndSend(Object message);
public void convertAndSend(Destination destination, Object message);
public void convertAndSend(String destinationName, Object message);
public void convertAndSend(Object message, MessagePostProcessor postProcessor);
public void convertAndSend(Destination destination, Object message, MessagePostProcessor postProcessor);
public void convertAndSend(String destinationName, Object message, MessagePostProcessor postProcessor);
三种发送
-
send()需要MessageCreator生成Message对象
-
covertAndSend()接受Object对象,自动转为Message
这个自动转换的操作是通过MessageConverter实现的,Spring定义了接口
Message toMessage(Object var1, Session var2) Object fromMessage(Message var1)
默认有四种实现类。
- MappingJackson2MessageConverter 与JSon的转换
- MarshallingMessageConverter 与XML的转换
- MessagingMessageConverter
- SimpleMessageConverter(默认)
-
covertAndSend()自动Object->Message,并且接受一个MessagePostProcessor对象,用来发送前对Message进行定义
可以对消息进行后期处理,比如可以统一加上便于区分的头信息
jmsTemplate.convertAndSend(message, new MessagePostProcessor() { @Override public Message postProcessMessage(Message message) throws JMSException { message.setStringProperty("X_SOURCE", "MASTER"); return message; } });
三个重载方法
- 一个方法不接受目的地参数,会发送至默认目的地
- 一个方法接受Destination对象,该对象指定了目的地
- 接受String,他通过名字指定消息目的地
默认目的地spring.jms.template.default-destination=taco.queue
8.1.3 接收JMS消息
一半有两种消费模式
- 拉取模式
一直等待消息到达。比如说后厨准备好做下一道菜,点击接收。
如果消息少,会导致等待阻塞。 - 推送模式 @JmsListener
在消息可用时自动执行,通常被视为最佳选择,因为不会导致阻塞。
如果消息太快处理不完,监听器可能过载。
JmsTemplate都是拉取模式,如果消息能够快速得到处理,那么他们是非常适合的方案。
但是,如果消息处理器需要根据自己的时间请求更多信息,拉取模式更适合。
JMS作为JAVA规范只能运行在Java应用中,RabbitMQ和Kafka等较新的消息传递方案克服了这类问题。
8.2 使用RabbitMQ和AMQP
RabbitMq可以说是AMQP(Advanced Message Queuing Protocol, 高级消息队列协议)最杰出的实现,提供了比JMS更高级的消息路由策略。
消息抵达MQ代理时,会进入设置的Exchange上,Exchange负责将它路由到一个或多个队列中去。
这个过程会根据exchange的类型、exchange和队列之前的binding以及消息的routing Key进行路由。
具体可以参考《RabbitMQ in Action》Alvaro Videla、Jason J.W.Williams。使用方法和JmsTemplate类似。
8.3 使用Kafka的消息
详情可以阅读《Kafka in Action》-Dylan Scott。