我试图了解Camel中的工作单元概念。我有一个简单的问题,希望这里有人可以提供帮助。
例如,如果路由Excachange涉及多个路由
from("aws-sqs:Q1").to("direct:processMe");//route1
from("direct:processMe").to("direct:aws-post");//route2
from("direct:aws-post").to("htt4:myservice");//route3
是否在每条路线的末尾调用工作单元?还是仅在路线3的尽头?在我的示例中,一旦route1完成,是否将从SQS中删除SQS消息?还是等到我的消息到达“ myservice”?
谢谢。
跟进:
我已经稍微修改了路线:
from("aws-sqs:Q1").to("direct:processMe");//route1
from("direct:processMe").process(
new Processor(){
public void process(Exchange exchange) throws Exception {
throw new RuntimeException("fail on purpose");
}
}
).to("direct:aws-post");//route2
from("direct:aws-post").to("http4:myservice");//route3
思考过程是这样的: 如果在每个路由的末尾调用工作单元,则一旦从SQS队列中读取了消息,SQS组件便会将其确认为已读取。另一方面,如果仅在Exchange完成了所有路由的路由后才调用工作单元,则路由2中的异常将导致该消息未被确认,并且在可见性期限到期后可以重新发送。
测试表明,尽管被第一条路线读取,但消息仍保留在Q上。它被一遍又一遍地捡起(直到它以死字母q结尾)。因此,我坚信单元边界是由要路由的Exchange末端定义的。
答案 0 :(得分:0)
unit of work基本上是一笔交易。
默认情况下,一条路由消息(骆驼Exchange
)在单个UnitOfWork
上下文中运行。
在您的示例中,设置了3个UnitOfWork
,从每个from
开始,到最后的to
结束。
我希望从SQS发送的消息在第一条路由完成后会被使用。为了进行测试,您可以添加一个睡眠以允许您检查队列。
from("direct:processMe").process(new Processor()
{ void process() { try { Thread.sleep(60000L) } catch (Exception e) { } }
}).to("direct:aws-post")
如果您希望消息在myservice
收到之前一直保留在队列中,那么您需要将处理放在一条路径上。
答案 1 :(得分:0)
我对工作单位边界有了很好的解释:
“ OnCompletion DSL名称用于定义工作单元完成时要执行的操作。
工作单元是一种骆驼概念,涵盖了整个交流过程。请参见第43.1节“交换”。 onCompletion命令具有以下功能:
OnCompletion命令的范围可以是全局的或每个路由的。路由范围将覆盖全局范围。 可以将OnCompletion配置为在失败时成功触发。
onWhen谓词只能在某些情况下触发onCompletion。 您可以定义是否使用线程池,尽管默认值为无线程池。“
在进行SQS处理的情况下,使用者在交换机上定义onCompletion
。因此,仅在交换完成路由后才调用它。
完整的答案可以在这里找到:Apache Camel Development Guide2.11. OnCompletion