【问题标题】:Camel bean method run on another thread骆驼豆方法在另一个线程上运行
【发布时间】:2020-01-08 16:22:40
【问题描述】:

我有一个问题,我希望它很简单.. 我有一条骆驼路线,它会采取一些行动,有一个处理器,这个处理器用一个相关 id 填充一个 threadLocal 变量。 在此之后,它运行一个 .bean(mybean, "mymethod"),在这个方法中我尝试从 threadLocal 变量中获取我的值,但它是 null。

我理解的一件事是骆驼在另一个线程上运行 bean 方法?这是真的吗?

我添加了另一个bean方法调用.bean(myBean, "myMethodForCorrelationId(correlationId)"),这个方法设置了threadLocal变量,之后.bean(mybean, "mymethod")可以访问到threadLocal的正确值。

代码:

private void getRoute() {

    from(RouteConstant.INTERNAL)
    // id
    .routeId("myroute")
    .setHeader(ElkKeys.EVENT_TYPE.getElkKey(), constant(EventType.EXCHANGE_REQUEST_REPLAY))
    // extract header from query uri
    .process(filtersListProcessor).choice()
    // caching predicate
    .when(cachePrediate)
    // get from cache
    .to(RouteConstant.GET_FROM_CACHE_ROUTE).otherwise()

    .bean(mybean,"myMethodForCorrelationId(${header.correlationId})") // first call fill the threadLocal

    // second call, the method use the previous threadLocal variable and it works
    .bean(mybean,
            "myMethod( ${header."
                    + ElkKeys.QUERY_PARAMETERS.getElkKey() + "})") 

    .multicast()
    // put in cache
    .to(ExchangePattern.InOnly, RouteConstant.PUT_INTO_CACHE_ROUTE).endChoice()

    .setHeader(ElkKeys.REPONSE_TIMESTAMP.getElkKey(), simple(RESPONSE_DATE_TIME))

    // send trace
    .to(ExchangePattern.InOnly, RouteConstant.SEND_SUCCESS_TRACE_TO_ELK);
}

我在谷歌上搜索,但我找不到任何关于此的信息,第一个 bean 方法使用的线程是否与第二个方法相同(每次在任何情况下)?

如果有人知道答案,我希望你能帮助我..

谢谢大家,

【问题讨论】:

    标签: java apache-camel


    【解决方案1】:

    您在问题中描述了一个奇怪的情况。事实上我在你的路由中没有看到任何会强制执行多线程的东西

    Bean 调用在其他线程中处理。

    默认情况下,Camel 路由由 1 个线程处理。这意味着您的 from 端点通常使用线程池来并行处理多个请求(例如 HTTP 或 JMS 端点),但是每个单独的请求都由一个线程完成。该线程通过完整路由路由消息。

    我很快创建了这条路线,并给它发了一条消息:

    from("direct:input")
        .log("Camel Route: " + Thread.currentThread().getName())
        .process(new TestProcessor()) // writes Thread.currentThread().getName() to System.out
        .bean(new BeanThread()); // writes Thread.currentThread().getName() to System.out
    

    控制台输出如预期:

    Camel Route: main
    Processor: main
    Bean: main
    

    但是,有几个“有状态”组件,例如聚合器。一旦您使用其中之一,路线上的线程视图就会变得更加复杂。

    但是,正如我在开头所写的,我在您的路线中看不到其中之一。

    然而,最大的问题是:为什么要使用ThreadLocal 变量? Camel 为以后保存值的方法是将它们放入消息头中。像这样,您可以保证与给定消息相关的值稍后仍会出现在路由中

    【讨论】:

    • 嘿,谢谢你的回答,事实上,当我记录一些东西时,我需要记录一个相关 ID。我用骆驼MDC试了一下,但它不起作用。所以我尝试将我的相关 ID 放在处理器中的 threadLocal 变量中,并在我的 bean 中获取它,但它是 null 所以我的结论是:我的 bean 方法在另一个线程上运行:/ 但是你说的是我在想的一开始..我要看看我是否有强制多线程的东西
    • 顺便说一句:您可以将 Processor 重构为 Bean。 Processor 接口陈旧而笨拙,Bean 的测试更加优雅,因为您不需要传递Exchanges。看看this Camel Docs page about Parameter Binding Annotations将各种消息部分注入POJO方法。
    • 我不确定处理器并进行了快速路由测试。 Processor 和 Bean 都由主线程处理。请参阅我的更新答案。
    猜你喜欢
    • 2014-06-21
    • 2018-09-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-13
    • 2012-05-14
    • 2014-10-27
    • 1970-01-01
    相关资源
    最近更新 更多