Apache camel RecipientList中端点响应的排序

Apache camel RecipientList中端点响应的排序,apache-camel,jbossfuse,fuseesb,camel-ftp,Apache Camel,Jbossfuse,Fuseesb,Camel Ftp,我使用的是camel 2.17和Fuse 6.3。我有一个场景,其中我需要将消息发送到多个端点,每个端点都在做一些数据库日志记录 我使用“recipientList”将我的消息发送到这些端点,但这里我面临一个问题,我的DB条目并不是按照端点调用的顺序排列的 假设我有3个端点A、B、C,在处理MessageA、MessageB和MessageC之后,它们在DB中分别记录了1条消息,但当我运行路由RL(A、B、C)时,我看不到顺序相同的DB mesages,尽管它们是直接端点 我的路线是否有办法等待

我使用的是camel 2.17和Fuse 6.3。我有一个场景,其中我需要将消息发送到多个端点,每个端点都在做一些数据库日志记录

我使用“recipientList”将我的消息发送到这些端点,但这里我面临一个问题,我的DB条目并不是按照端点调用的顺序排列的

假设我有3个端点A、B、C,在处理MessageA、MessageB和MessageC之后,它们在DB中分别记录了1条消息,但当我运行路由RL(A、B、C)时,我看不到顺序相同的DB mesages,尽管它们是直接端点

我的路线是否有办法等待第一个端点完成,然后处理第二个端点

这是我的路线样本

<route id="RouteStart">
        <from id="_from1" uri="file:.../>
        <bean id="_bean1" method="hasReadWriteAccess" ref="fileAccessValidator"/>
        <log id="_log1" message=${body}"/>
        <recipientList id="_recipientList1">
            <simple>FirstStepInsert, MessageDirQueue, Step1Queue</simple>
        </recipientList>
    </route>
    <!-- This route picks the file from queue, encodes the file in to UTF-8 BOM and validates file against XSD -->
    <route id="Step1Route">
        <from id="_from2" uri="Step1Queue"/>
        <log id="_log2" message=${body}"/>
         <setProperty id="_setProperty4" propertyName="stepName">
            <simple>File Validation</simple>
        </setProperty>
        <doTry id="_doTry1">
            <to id="_to1" uri="Step2Queue"/>
            <doCatch id="_doCatch1">
                <exception>org.apache.camel.ValidationException</exception>
                <to id="_to2" uri="file:..?autoCreate=true"/>
                <log id="_log7" message="Moved Invalid file ${file:name}"/>
            </doCatch>
            <doCatch id="_doCatch2">
                <exception>java.io.IOException</exception>
                <to id="_to3" uri="file:..?autoCreate=true"/>
                <log id="_log8" message="Moved XML file ${file:name} with Incorrect access"/>
            </doCatch>
            <doFinally id="_doFinally1">
                <to id="_to4" uri="direct:stepInsertLogging"/>
            </doFinally>
        </doTry>
    </route>
    <route id="Step2Route">
        <from id="_from3" uri="Step2Queue"/>
        <log id="_log9" message="${body}"/>
        <setProperty id="_setProperty12" propertyName="stepName">
            <simple>Data Transformation</simple>
        </setProperty>
        <recipientList id="_recipientList2">
            <simple>direct:stepInsertLogging, ReceiveDirQueue, Step3Queue</simple>
        </recipientList>
    </route>
    <route id="Step3Route">
        <from id="_from4" uri="Step3Queue"/>
        <setProperty id="_setProperty19" propertyName="stepName">
            <simple>File Delivered</simple>
        </setProperty>
        <to id="_to5" uri="file:..."/>
        <onException id="_onException1">
            <exception>java.io.IOException</exception>
            <redeliveryPolicy maximumRedeliveries="2" redeliveryDelay="0"/>
        <recipientList id="_recipientList3">
            <simple>direct:stepInsertLogging, direct:flowUpdateLogging</simple>
        </recipientList>
    </route>
    <!-- This route sends a copy of source file to Message Archive folder -->
    <route id="MessageDirRoute">
        <from id="_from9" uri="MessageDirQueue"/>
        <log id="_log23" message="${body}"/>
        <setProperty id="_setProperty63" propertyName="stepName">
            <simple>Data SourceFile Logging</simple>
        </setProperty>
        <to id="_to13" uri="file:.."/>
        <onException id="_onException4">
            <exception>java.io.IOException</exception>
            <handled>
                <constant>true</constant>
            </handled>
        <to id="_to14" uri="direct:stepInsertLogging"/>
    </route>

    <!-- This route sends a copy of destination file to Message Archive folder -->
    <route id="receiveDirectory-route">
        <from id="_from10" uri="ReceiveDirQueue"/>
        <setProperty id="_setProperty77" propertyName="stepName">
            <simple>Data DestinationFile Logging</simple>
        </setProperty>
        <to id="_to15" uri="file:.."/>
        <onException id="_onException5">
            <exception>java.io.IOException</exception>
            <redeliveryPolicy maximumRedeliveries="2" redeliveryDelay="0"/>
            <handled>
                <constant>true</constant>
            </handled>
        <to id="_to16" uri="direct:stepInsertLogging"/>
    </route>
    <!-- Event Logging Routes -->
    <route id="startMainLogRoute">
        <from id="_from11" uri="FirstStepInsert"/>
        <log id="_log25" message="Received File ${file:name} : ${body}"/>
        <setProperty id="_setProperty92" propertyName="stepName">
            <simple>File Received</simple>
        </setProperty>
        <log id="_log26" message="${property.flowId}"/>
        <recipientList id="_recipientList7" streaming="false">
            <simple>direct:flowInsertLogging, direct:stepInsertLogging</simple>
        </recipientList>
    </route>
    <route id="flowInsertLogRoute">
        <from id="_from12" uri="direct:flowInsertLogging"/>
        <log id="_log27" message="[flowInsertLogRoute]  Flow Id is ${property.flowId}"/>
        <process id="_process8" ref="flowProcessor"/>
        <transform id="_transform1">
            <method method="getFlowMap" ref="flowMapper"/>
        </transform>
        <log id="_log28" message="Executing the query {{sql.insertFlowDetail}}"/>
        <to id="_to17" uri="sql:{{sql.insertFlowDetail}}"/>
    </route>
    <route id="stepInsertLogRoute">
        <from id="_from13" uri="direct:stepInsertLogging"/>
        <log id="_log29" message="[stepInsertLogRoute] Flow Id is ${property.flowId}"/>
        <process id="_process9" ref="stepProcessor"/>
        <transform id="_transform2">
            <method method="getStepMap" ref="stepMapper"/>
        </transform>
        <log id="_log30" message="Executing the query {{sql.insertStepDetail}}"/>
        <to id="_to18" uri="sql:{{sql.insertStepDetail}}"/>
    </route>
    <route id="flowUpdateLogRoute">
        <from id="_from14" uri="direct:flowUpdateLogging"/>
        <log id="_log31" message="[flowUpdateLogRoute] Flow Id is ${property.flowId}"/>
        <transform id="_transform3">
            <method method="getFlowUpdateMap" ref="flowUpdateMapper"/>
        </transform>
        <log id="_log32" message="Executing the query {{sql.updateFlowDetail}}"/>
        <to id="_to19" uri="sql:{{sql.updateFlowDetail}}"/>
    </route>
</camelContext>

FirstStepInsert、MessageDirQueue、Step1Queue

Themis和NoMad17已经在评论中说过:

收件人将收到同一交换的副本,Camel将按顺序执行它们

我在你的路线中看到你在链接其他收件人列表。也许你错过了一些东西,因为它有很多路线。为了验证收件人列表中的序列,以此单元测试为例:

public class RecipientListSequenceAggregateRouteTest extends CamelTestSupport {

    EmbeddedDatabase db;

    @Before
    public void setUp() throws Exception {
        db = new EmbeddedDatabaseBuilder()
            .setType(EmbeddedDatabaseType.DERBY).addScript("sql/test.sql").build();

        super.setUp();
    }

    @Override
    protected RoutesBuilder createRouteBuilder() throws Exception {
        return new RouteBuilder() {

            @Override
            public void configure() throws Exception {
                getContext().getComponent("sql", SqlComponent.class).setDataSource(db);

                from("direct:start")
                    .recipientList(constant("direct:a1, direct:a2, direct:a3, direct:select"));

                from("direct:a1")
                    .log("got message in a1: waiting 3s")
                    .process(new Processor() {
                        @Override
                        public void process(Exchange exchange) throws Exception {
                            Thread.sleep(3000);
                        }
                    })
                    .setBody(constant("a1"))
                    .recipientList(constant("direct:db, direct:flow"));

                from("direct:a2")
                    .log("got message in a2: waiting 5s")
                    .process(new Processor() {
                        @Override
                        public void process(Exchange exchange) throws Exception {
                            Thread.sleep(5000);
                        }                   
                    })
                    .setBody(constant("a2"))
                    .recipientList(constant("direct:db, direct:flow"));

                from("direct:a3")
                    .log("got message in a3: waiting 1s")
                    .process(new Processor() {
                        @Override
                        public void process(Exchange exchange) throws Exception {
                            Thread.sleep(1000);
                        }
                    });

                from("direct:db")
                    .log("got message in db from ${body}")
                    .setBody(simple("db_${in.body}"))
                    .to("sql:insert into log (body_in) values (:#${in.body})");
                    ;

                from("direct:flow")
                    .log("got message in flow from ${body}")
                    .setBody(simple("flow_${in.body}"))
                    .to("sql:insert into log (body_in) values (:#${in.body})");
                    ;

                from("direct:select")
                    .to("sql:select * from log order by time_in")
                    .log("results:\n ${body}")
                    .to("mock:result");
            }
        };
    }

    @Test
    public void test() throws InterruptedException {
        getMockEndpoint("mock:result").expectedMessageCount(1);
        Object results = template.requestBody("direct:start", "");
        assertNotNull(results);
        assertMockEndpointsSatisfied();
    }
}
结果是:

19:23:47.090 [main] INFO route2 - got message in a1: waiting 3s
19:23:50.093 [main] INFO route5 - got message in db from a1
19:23:50.315 [main] INFO route6 - got message in flow from a1
19:23:50.337 [main] INFO route3 - got message in a2: waiting 5s
19:23:55.343 [main] INFO route5 - got message in db from a2
19:23:55.351 [main] INFO route6 - got message in flow from a2
19:23:55.359 [main] INFO route4 - got message in a3: waiting 1s
19:23:56.428 [main] INFO route7 - results:
[{BODY_IN=db_a1, TIME_IN=2017-12-22 19:23:50.301}, {BODY_IN=flow_a1, TIME_IN=2017-12-22 19:23:50.334}, {BODY_IN=db_a2, TIME_IN=2017-12-22 19:23:55.348}, {BODY_IN=flow_a2, TIME_IN=2017-12-22 19:23:55.356}]
如您所见,即使链接到其他收件人列表,邮件也是按顺序传递的。你能从你的路线上取些样品看看日志吗?试着一步一步地分析。看到你的DSL,我看不出有什么问题

如果需要处理收件人列表中的回复,可能需要自定义:

一种聚合策略,可将收件人的回复组合成收件人列表中的单个传出邮件默认情况下,骆驼将使用最后一次回复作为传出消息。从Camel 2.12开始,您还可以使用POJO作为聚合策略,有关更多详细信息,请参阅聚合器页面。如果从AggregationStrategy中的聚合方法引发异常,则默认情况下,该异常不由错误处理程序处理。如果启用shareUnitOfWork选项,则可以启用错误处理程序进行反应


你能告诉我们你的路线吗?默认情况下,RecipientList应该按顺序处理每个端点。它确实按顺序处理请求,但响应的处理方式是否相同?如果端点A需要2秒钟来处理请求,而端点B会更早地处理请求,那么它会等待端点A完成执行吗?您使用的是流式处理还是并行处理选项?两者都没有,我的流式处理设置为false(默认),并且我没有进行任何并行处理。因此@noMad17所说的处理是按顺序进行的!