【问题标题】:Same ThreadLocal in Spring JMS producer and consumerSpring JMS 生产者和消费者中的相同 ThreadLocal
【发布时间】:2024-01-19 10:01:01
【问题描述】:

我正在使用 SpringBoot 和 Spring JMS 在后端处理购物车(商业网络应用程序)。 JMS 生产者将发送订单消息,消费者将接收并处理。

由于应用程序应该配置为多租户,我将租户 ID 保留在 ThreadLocal 中。在生产者方面,一切都很好,并且租户 ID 在 ThreadLocal 中可用,但它不在消费者方面。我怎样才能让它在消费者端也可用?

【问题讨论】:

    标签: java multithreading spring-boot multi-tenant spring-jms


    【解决方案1】:

    不保证 JMS 生产者和消费者将由同一个线程处理。说实话不太可能。哎呀,它们可以在不同的 JVM 中,这使得它不可能。因此,您将无法使用线程本地将信息从生产者传递给消费者。

    您必须将此信息添加到消息正文或将其添加为属性。

    每条消息都包含一个内置工具,用于支持应用程序定义的属性值。属性为支持应用程序定义的消息过滤提供了一种有效的机制。

    来源:Message Javadoc

    编写和读取该属性很简单:

    // Producer side
    msg.setStringProperty("tenant", "tenant-1");
    // Consumer side
    String tenant = msg.getStringProperty("tenant");
    

    在消费者端提取租户信息后,您可以将其放入线程局部变量中以供进一步使用。

    【讨论】:

    • 当然,我知道生产者和消费者不会使用同一个线程,这就是为什么我想知道如何将线程本地信息从生产者动态传输到消费者。手动在 JMS 消息中设置这些信息将破坏消息的基于域的干净 DTO 对象。
    • 您不必在 DTO 中包含这些信息。您是否控制 JMS 消息的序列化/反序列化?如果是,那么您可以将线程本地租户信息添加到生产者的消息中,您可以阅读它并添加到消费者端的线程本地。你也可以使用 Spring JMS 的 MessagePostProcessor 来做到这一点:javadoc
    • 我认为这会奏效。使用 setStringProperty 和 getStringProperty 如果我把它放在 JMS messageConverter 配置中,我可以让它在全局范围内工作,即 toMessage 和 fromMessage 方法。
    最近更新 更多