专栏首页云霄雨霁Spring 异步消息

Spring 异步消息

异步消息简介

异步消息是一个应用程序向另一个应用程序间接发送消息的一种方式,这种方式无需等待对方的相应。

异步消息中有两个主要的概念:消息代理(message broker)和目的地(destination)。

当一个应用发送消息时,会将消息发送给一个消息代理。消息代理可以确保被投递到指定的目的地,同时解放发送者,使其能够继续进行其他的业务。

目的地只关注消息应该从哪里获得,而并不关心是谁取走了消息。有两种通用的目的地:队列(queue)和主题(topic),分别对应点对点模型和发布/订阅模型。

点对点模型:

在点对点模型中,每一条消息都只有一个发送者和接收者。可以理解为“生产者-消费者”模式。当消息代理得到消息时,它将消息放入一个队列中。当接收者请求队列中的下一条消息时,消息会从队列中取出,并投递给接收者。因为消息投递后会从队列中删除,这样就能保证每条消息只投递给一个接收者。

发布/订阅模型:

在发布/订阅消息模型中,消息会发送给一个主题。与队列相同,多个接收者都可以监视一个主题,但与队列不同的是,消息不再是只投递给一个接收者,而是所有的订阅者都会接收到此消息的副本。类似“观察者模式”。

异步消息的优点

同步消息

异步消息

同步通信意味着等待 客户端通过服务接口与远程服务相耦合 客户端与远程服务的位置相耦合 客户端与服务的可用性相耦合

无需等待 面向消息和解耦 位置独立 确保投递

  • 同步通信意味着等待
  • 客户端通过服务接口与远程服务相耦合
  • 客户端与远程服务的位置相耦合
  • 客户端与服务的可用性相耦合
  • 无需等待
  • 面向消息和解耦
  • 位置独立
  • 确保投递

Spring 中使用JMS发送异步消息

Java消息服务(JMS)是一个Java标准,定义了使用消息代理的通用API。类似与JDBC为数据库操作提供的通用接口一样。但JMS同样也和JDBC一样每次使用需要写大量版式代码。

JmsTemplate是Spring提供的一个模板,通过该模板为JMS提供支持。使用JmsTemplate能够非常容易地在消息圣蚕房发送队列和订阅消息,在消费消息的哪一方也能非常容易地接收这些消息。

1  Spring 搭建消息代理

选取ActiveMQ作为异步消息的消息代理,ActiveMQ是一个很好的开源消息代理产品,在Spring中使用Active之前必须下载并启动其服务。

1.1  创建连接工厂

第一步是配置JMS连接工厂,让JMS知道如何连接到ActiveMQ。ActiveMQConnectionFactory是ActiveMQ自带的连接工厂,在Spring中可以如下配置(p:brokerURL可选,用来指定代理的URL):

<bean id="connectionFactory"
      class="org.apache.activemq.spring.ActiveMQConnectionFactory"
      p:brokerURL="tcp://localhost:61616"/>

1.2  声明消息目的地

目的地可以是队列,也可以是主题。不论是队列还是主题,都必须使用特定的消息代理实现类在Spring中配置目的地Bean。

声明ActiveMQ队列:

<bean id="queue"
      class="org.apache.activemq.command.ActiveMQQueue"
      c:_="test.queue"/>

声明ActiveMQ主题:

<bean id="topic"
      class="org.apache.activemq.command.ActiveMQTopic"
      c:_="test.topic"/>

2  使用JMS

2.1  配置JmsTemplate

为了使用JmsTemplate,需要在Spring的配置文件中将它声明为一个bean。配置方法如下:

<bean id="jmsTemplate"
      class="org.springfarmework.jms.core.JmsTemplate"
      c:_-ref="connectionFactory" />

2.2  发送消息

配置好JmsTemplate后,使用JmsOperation(JmsTemplate所实现的接口)将目标对象发送给消息队列,队列会在稍后得到处理。

2.2.1  send()方法实现

首先需要一个JMS对象,然后调用JMS的send方法即可实现发送异步消息。

注意:send()方法的第一个参数是目的地,1.2配置过的。第二个参数是MessageCreator类型的匿名对象,需要实现createMessage方法。

public class AlterService{
    @Autowired
    private JmsOperations jmsOperations;    //注入JMS模板
 
    public void sendString(String str){
        jmsOperations.send(    //调用方法发送消息
            "test.queue",    //指定目的地
            new MessageCreator(){    //send方法需要一个MessageCreator作为参数,这里使用匿名类实现
                public Message createMessage(Session session) throws JMSException{    //需要实现该方法
                    return session.createObjectMessage(string);    //创建消息
                }
            }
        );
    }
}

2.2.2  设置默认目的地

2.2.1中send方法的第一个参数指定目的地,其实可以在配置JmsTemplate时指定默认目的地,这样就可以省去send的第一个参数。

<bean id="jmsTemplate"
      class="org.springfarmework.jms.core.JmsTemplate"
      c:_-ref="connectionFactory"
      p:defaultDestinationName="test.queue" />

2.2.3  convertAndSend()方法实现

convertAndSend()方法并不需要MessageCreator参数,这是因为该方法会使用内置的消息转换器创建消息。所以使用convertAndSend()方法时代码非常简洁:

public void sendString(String string){
    jmsOperations.converAndSend(string);
}

2.3  接收消息

接收消息比发送消息更为简单,只需要调用JmsTemplate的receice()方法即可。当调用该方法时。JmsTemplate会尝试从消息代理中获取一个消息。如果没有消息receice()方法会一直等待,知道获取方法为止。

public String receiceString(){
    try{
        return (String) jmsOperations.receive();
    }catch (JMSException jmsException){
        throw JmsUtils.convertJmsAccessException(jmsException);
    }
 }

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Spring Bean生命周期

    SuperHeroes
  • SpringMVC--拦截器笔记

    SuperHeroes
  • Java虚拟机--对象回收

    SuperHeroes
  • Spring消息之JMS.

    JMCui
  • 大型网站架构系列:消息队列(二)

    本文是大型网站架构系列:消息队列(二),主要分享JMS消息服务,常用消息中间件(Active MQ,Rabbit MQ,Zero MQ,Kafka)。 【第二篇...

    小小科
  • 如何利用RabbitMQ生产一个简单的消息

    最近业务中有有这样一个场景,就是用户在商城下单之后,如果30分钟没有付款,那么就需要将这个订单处理掉,要么直接删除,要么直接标识为失效状态,为什么要这么做?

    一个程序员的成长
  • 生产环境消息队列ActiveMQ的数据积压优化过程

    最近生产环境的消息通知队列发生了大量的数据积压问题,从而影响到整个平台商户的交易无法正常进行,最后只能通过临时关闭交易量较大的商户来缓解消息队列积压的问题,经线...

    Java架构师必看
  • RabbitMQ的消息确认ACK机制

      答:如果在处理消息的过程中,消费者的服务器在处理消息的时候出现异常,那么可能这条正在处理的消息就没有完成消息消费,数据就会丢失。为了确保数据不会丢失,Rab...

    别先生
  • 最全Kafka 设计与原理详解【2017.9全新】

    当今社会各种应用系统诸如商业、社交、搜索、浏览等像信息工厂一样不断的生产出各种信息,在大数据时代,我们面临如下几个挑战:

    sunsky
  • 读《图解密码技术》(二):认证

    原创文章,转载请注明:转载自Keegan小钢 并标明原文链接:http://keeganlee.me/post/reading/20160705 微信订阅号:k...

    Keegan小钢

扫码关注云+社区

领取腾讯云代金券