【问题标题】:Does JMSTemplate producer open a thread for each message?JMSTemplate 生产者是否为每条消息打开一个线程?
【发布时间】:2019-12-09 09:56:11
【问题描述】:

我正在使用 Spring Boot 2.1.6 构建一个 REST API 应用程序。我想在我的应用程序中通过 Active MQ 包 (org.apache.activemq) 使用 JMS 消息传递。我有MyEventController 类,它通过http 请求接收各种事件。然后,我想将有关事件的信息作为 JMS 消息发送到主题,以便消息使用者使用来自事件的信息更新数据库。

我想在这里使用 JMS 的原因是不保留处理 http 请求的 Spring 线程,并让使用者打开一个单独的线程来对数据库进行可能大量耗时的更新。但是我想知道JMSTemplate 是否始终保持一个线程。因为如果为每个 http 请求打开一个新线程,那么解决方案的可扩展性就不是那么高了。

这是我的生产者代码:

@RestController
public class MyEventController {
    @Autowired
    private DBHandler db;

    @Autowired
    private JmsTemplate jmsTemplate;

    @RequestMapping(method=GET, path=trackingEventPath)
    public ResponseEntity<Object> handleTrackingEvent(
            @RequestParam(name = Routes.pubId) String pubId,
            @RequestParam(name = Routes.event) String event) {

        jmsTemplate.convertAndSend("topic1", "info@example.com");
        return new ResponseEntity<>(null, new HttpHeaders(), HttpStatus.OK);
}

消费者:

@Component
public class JSMListener {
    @JmsListener(destination = "topic1", containerFactory = "topicListenerFactory")
    public void receiveTopicMessage(String event) {
        // do something...
    }
}

【问题讨论】:

    标签: java spring-boot spring-jms jmstemplate


    【解决方案1】:

    JmsTemplate 没有后台线程或异步发送的概念。这是一个类设计,用于简化 java.jms.Session 的使用并将其嵌入到常见的 Spring 概念中,例如使用@Transactional 进行声明式事务管理。

    在您的示例中,convertAndSend() 将作为请求处理线程的一部分执行。该方法将阻塞,直到 JMS 代理响应应用程序将消息添加到目标队列,或者如果出现问题则抛出异常,例如队列已满。

    【讨论】:

    • 但是,出于性能原因,您应该使用带有缓存生产者的CachingConnectionFactory(默认)。 (除非您有其他一些池连接工厂)。否则,每次发送都会创建并丢弃一个新的连接/生产者;这是非常低效的。
    • 如果我想在 Spring 中发送 JMS 消息,最佳实践是什么?是否有允许在单独的线程中发送消息的 Spring/JMS API?
    猜你喜欢
    • 2023-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-24
    • 2017-02-01
    • 2012-04-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多