Camel in/out 消息和关联 ID 混乱

Camel in/out messages and correlation ID confusion

我对 Camel 在使用消息队列时如何自动形成消息和相关标识符感到困惑。

举个例子,我有两个服务,路线如下

<route id="cxfToJMSRoute">

        <from uri="cxf:bean:endpoint" />
        <convertBodyTo type="String" />

        <log message="..." />
        <log message="In message: ${in.body}" />
        <log message="In JMSMessageID: ${in.header.JMSMessageID}" />
        <log message="In JMSCorrelationID: ${in.header.JMSCorrelationID}" />

        <log message="Out message: ${out.body}" />
        <log message="Out JMSMessageID: ${out.header.JMSMessageID}" />
        <log message="Out JMSCorrelationID: ${out.header.JMSCorrelationID}" />

        <log message="Invoking service A by sending InOut message to api queue" />
        <to uri="activemq:queue:api?replyTo=result&amp;replyToType=Exclusive"
            pattern="InOut" />

        <log message="..." />
        <log message="Got message from Service A" />
        <log message="In message: ${in.body}" />
        <log message="In JMSMessageID: ${in.header.JMSMessageID}" />
        <log message="In JMSCorrelationID: ${in.header.JMSCorrelationID}" />

        <log message="Out message: ${out.body}" />
        <log message="Out JMSMessageID: ${out.header.JMSMessageID}" />
        <log message="Out JMSCorrelationID: ${out.header.JMSCorrelationID}" />

        <!-- Correlation ID? -->
        <pollEnrich>
            <constant>activemq:queue:reply</constant>
        </pollEnrich>

        <log message="..." />
        <log message="Got message from Service B" />
        <log message="In message: ${in.body}" />
        <log message="In JMSMessageID: ${in.header.JMSMessageID}" />
        <log message="In JMSCorrelationID: ${in.header.JMSCorrelationID}" />

        <log message="Out message: ${out.body}" />
        <log message="Out JMSMessageID: ${out.header.JMSMessageID}" />
        <log message="Out JMSCorrelationID: ${out.header.JMSCorrelationID}" />

        <transform>
            <simple>${in.body}</simple>
        </transform>

        <log message="After transform:" />
        <log message="In message: ${in.body}" />
        <log message="In JMSMessageID: ${in.header.JMSMessageID}" />
        <log message="In JMSCorrelationID: ${in.header.JMSCorrelationID}" />

        <log message="Out message: ${out.body}" />
        <log message="Out JMSMessageID: ${out.header.JMSMessageID}" />
        <log message="Out JMSCorrelationID: ${out.header.JMSCorrelationID}" />
        <log message="..." />
    </route>

--

<route id="apiToServiceARoute">
      <from uri="activemq:queue:api"/>

      <log message="..." />
      <log message="In message: ${in.body}" />
      <log message="In JMSMessageID: ${in.header.JMSMessageID}" />
      <log message="In JMSCorrelationID: ${in.header.JMSCorrelationID}" />

      <log message="Out message: ${out.body}" />
      <log message="Out JMSMessageID: ${out.header.JMSMessageID}" />
      <log message="Out JMSCorrelationID: ${out.header.JMSCorrelationID}" />

      <log message="Mocking service B by sending InOnly message to reply queue" />
      <to uri="activemq:queue:reply?exchangePattern=InOnly" pattern="InOnly" />

      <transform>
        <simple>Delegated</simple>
      </transform>

      <log message="..." />
      <log message="After transform:" />
      <log message="In message: ${in.body}" />
      <log message="In JMSMessageID: ${in.header.JMSMessageID}" />
      <log message="In JMSCorrelationID: ${in.header.JMSCorrelationID}" />

      <log message="Out message: ${out.body}" />
      <log message="Out JMSMessageID: ${out.header.JMSMessageID}" />
      <log message="Out JMSCorrelationID: ${out.header.JMSCorrelationID}" />
      <log message="..." />
  </route>

这是我根据日志消息的观察结果

  1. OUT 消息总是空的。默认情况下,Camel 是否总是使用 IN,直到 OUT 被某些处理器明确创建?
  2. JMSMessageIDJMSCorrelationID好像没有什么联系。 Camel 使用 JMSCorrelationID 关联消息吗?
  3. Camel 在将 InOnly 消息发送到发出请求的另一个队列(回复)时设法保留了 JMSCorrelationID。这是可取的,但它实际上是如何做到的呢?保留JMSCorrelationID具体规则是什么?

这里是两个示例路由的实际日志

2017-12-03 12:16:06.197  INFO 13780 --- [qtp335580595-36] cxfToJMSRoute                            : ...
2017-12-03 12:16:06.197  INFO 13780 --- [qtp335580595-36] cxfToJMSRoute                            : In message: testi2
2017-12-03 12:16:06.198  INFO 13780 --- [qtp335580595-36] cxfToJMSRoute                            : In JMSMessageID:
2017-12-03 12:16:06.198  INFO 13780 --- [qtp335580595-36] cxfToJMSRoute                            : In JMSCorrelationID:
2017-12-03 12:16:06.198  INFO 13780 --- [qtp335580595-36] cxfToJMSRoute                            : Out message:
2017-12-03 12:16:06.198  INFO 13780 --- [qtp335580595-36] cxfToJMSRoute                            : Out JMSMessageID:
2017-12-03 12:16:06.198  INFO 13780 --- [qtp335580595-36] cxfToJMSRoute                            : Out JMSCorrelationID:
2017-12-03 12:16:06.198  INFO 13780 --- [qtp335580595-36] cxfToJMSRoute                            : Invoking service A by sending InOut message to api queue
2017-12-03 12:16:06.569  INFO 13780 --- [Manager[result]] cxfToJMSRoute                            : ...
2017-12-03 12:16:06.570  INFO 13780 --- [Manager[result]] cxfToJMSRoute                            : Got message from Service A
2017-12-03 12:16:06.570  INFO 13780 --- [Manager[result]] cxfToJMSRoute                            : In message: Delegated
2017-12-03 12:16:06.582  INFO 13780 --- [Manager[result]] cxfToJMSRoute                            : In JMSMessageID: ID:DESKTOP-LI5P50P-54036-1512296151920-1:1:1:1:1
2017-12-03 12:16:06.582  INFO 13780 --- [Manager[result]] cxfToJMSRoute                            : In JMSCorrelationID: Camel-ID-DESKTOP-LI5P50P-1512296077166-0-2
2017-12-03 12:16:06.582  INFO 13780 --- [Manager[result]] cxfToJMSRoute                            : Out message:
2017-12-03 12:16:06.582  INFO 13780 --- [Manager[result]] cxfToJMSRoute                            : Out JMSMessageID:
2017-12-03 12:16:06.583  INFO 13780 --- [Manager[result]] cxfToJMSRoute                            : Out JMSCorrelationID:
2017-12-03 12:16:06.596  INFO 13780 --- [Manager[result]] cxfToJMSRoute                            : ...
2017-12-03 12:16:06.596  INFO 13780 --- [Manager[result]] cxfToJMSRoute                            : Got message from Service B
2017-12-03 12:16:06.596  INFO 13780 --- [Manager[result]] cxfToJMSRoute                            : In message: testi2
2017-12-03 12:16:06.597  INFO 13780 --- [Manager[result]] cxfToJMSRoute                            : In JMSMessageID: ID:DESKTOP-LI5P50P-54036-1512296151920-3:1:1:1:1
2017-12-03 12:16:06.597  INFO 13780 --- [Manager[result]] cxfToJMSRoute                            : In JMSCorrelationID: Camel-ID-DESKTOP-LI5P50P-1512296077166-0-2
2017-12-03 12:16:06.597  INFO 13780 --- [Manager[result]] cxfToJMSRoute                            : Out message:
2017-12-03 12:16:06.597  INFO 13780 --- [Manager[result]] cxfToJMSRoute                            : Out JMSMessageID:
2017-12-03 12:16:06.597  INFO 13780 --- [Manager[result]] cxfToJMSRoute                            : Out JMSCorrelationID:
2017-12-03 12:16:06.598  INFO 13780 --- [Manager[result]] cxfToJMSRoute                            : After transform:
2017-12-03 12:16:06.598  INFO 13780 --- [Manager[result]] cxfToJMSRoute                            : In message: testi2
2017-12-03 12:16:06.598  INFO 13780 --- [Manager[result]] cxfToJMSRoute                            : In JMSMessageID: ID:DESKTOP-LI5P50P-54036-1512296151920-3:1:1:1:1
2017-12-03 12:16:06.598  INFO 13780 --- [Manager[result]] cxfToJMSRoute                            : In JMSCorrelationID: Camel-ID-DESKTOP-LI5P50P-1512296077166-0-2
2017-12-03 12:16:06.598  INFO 13780 --- [Manager[result]] cxfToJMSRoute                            : Out message:
2017-12-03 12:16:06.598  INFO 13780 --- [Manager[result]] cxfToJMSRoute                            : Out JMSMessageID:
2017-12-03 12:16:06.598  INFO 13780 --- [Manager[result]] cxfToJMSRoute                            : Out JMSCorrelationID:
2017-12-03 12:16:06.598  INFO 13780 --- [Manager[result]] cxfToJMSRoute                            : ...

--

2017-12-03 12:16:06.528  INFO 16972 --- [msConsumer[api]] apiToServiceARoute                       : ...
2017-12-03 12:16:06.531  INFO 16972 --- [msConsumer[api]] apiToServiceARoute                       : In message: testi2
2017-12-03 12:16:06.534  INFO 16972 --- [msConsumer[api]] apiToServiceARoute                       : In JMSMessageID: ID:DESKTOP-LI5P50P-54046-1512296166309-1:1:2:1:1
2017-12-03 12:16:06.534  INFO 16972 --- [msConsumer[api]] apiToServiceARoute                       : In JMSCorrelationID: Camel-ID-DESKTOP-LI5P50P-1512296077166-0-2
2017-12-03 12:16:06.534  INFO 16972 --- [msConsumer[api]] apiToServiceARoute                       : Out message:
2017-12-03 12:16:06.535  INFO 16972 --- [msConsumer[api]] apiToServiceARoute                       : Out JMSMessageID:
2017-12-03 12:16:06.535  INFO 16972 --- [msConsumer[api]] apiToServiceARoute                       : Out JMSCorrelationID:
2017-12-03 12:16:06.535  INFO 16972 --- [msConsumer[api]] apiToServiceARoute                       : Mocking service B by sending InOnly message to reply queue
2017-12-03 12:16:06.558  INFO 16972 --- [msConsumer[api]] apiToServiceARoute                       : ...
2017-12-03 12:16:06.558  INFO 16972 --- [msConsumer[api]] apiToServiceARoute                       : After transform:
2017-12-03 12:16:06.558  INFO 16972 --- [msConsumer[api]] apiToServiceARoute                       : In message: Delegated
2017-12-03 12:16:06.558  INFO 16972 --- [msConsumer[api]] apiToServiceARoute                       : In JMSMessageID: ID:DESKTOP-LI5P50P-54046-1512296166309-1:1:2:1:1
2017-12-03 12:16:06.559  INFO 16972 --- [msConsumer[api]] apiToServiceARoute                       : In JMSCorrelationID: Camel-ID-DESKTOP-LI5P50P-1512296077166-0-2
2017-12-03 12:16:06.559  INFO 16972 --- [msConsumer[api]] apiToServiceARoute                       : Out message:
2017-12-03 12:16:06.559  INFO 16972 --- [msConsumer[api]] apiToServiceARoute                       : Out JMSMessageID:
2017-12-03 12:16:06.559  INFO 16972 --- [msConsumer[api]] apiToServiceARoute                       : Out JMSCorrelationID:
2017-12-03 12:16:06.559  INFO 16972 --- [msConsumer[api]] apiToServiceARoute                       : ...
  1. OUT message is always empty. Does Camel always use IN by default, until OUT is created by some processor explicitly?

是的。整个 org.apache.camel.Message 的克隆非常昂贵。 OUT 是在第一次调用 Exchange#getOut

期间按需创建的

Apache Camel: Message exchange patterns and the Exchange object


  1. JMSMessageID and JMSCorrelationID doesn't seem to have any connection. Does Camel only use JMSCorrelationID for correlating messages?

不完全是。 camel-jms(和扩展它的 camel-activemq)组件将 header JMSCorrelationID 复制到 header CamelCorrelationId

pollEnrich 中的相关性再次与 CamelCorrelationId 一起使用,camel-jms 将此 header 翻译为消息选择器 JMSCorrelationID=CamelCorrelationId

所以是的,在 camel-jms(和继承的组件)端点和 exchangePattern=InOnly 之间进行通信时,关联将在 header JMSCorrelationID 上有效完成。

Apache Camel: Correlation Identifier


  1. Camel manages to retain the JMSCorrelationID when sending InOnly message to another queue (reply) where the request originates from. This is desirable, but how does it actually do it? What are the specific rules of retaining the JMSCorrelationID?

Camel 在使用 exchangePattern=InOnly 转换 JMSCorrelationID

在输入路由上,Camel 从输入 javax.jms.Message 获取关联 ID 并将其保存到 org.apache.camel.Message#headers.JMSCorrelationId

在输出路径上,Camel 从 org.apache.camel.Message#headers.JMSCorrelationId 获取关联 ID 并将其设置为 javax.jms.Message.setJMSCorrelationID()

注:我不是 Apache Camel 的开发者。我在这个答案中写的每一个字都是基于使用这个框架时的用户体验。答案可能存在细微差异。