Apache camel 多次使用同一URI返回空正文
我有两条路线。第一个路由使用轮询来检查文件是否存在。第二个路由使用同一uri上的轮询来读取和处理文件。第一条路线通过SEDA队列调用第二条路线,如下所示:Apache camel 多次使用同一URI返回空正文,apache-camel,Apache Camel,我有两条路线。第一个路由使用轮询来检查文件是否存在。第二个路由使用同一uri上的轮询来读取和处理文件。第一条路线通过SEDA队列调用第二条路线,如下所示: public void configure() throws Exception { String myFile = "file://myDir?fileName=MyFile.zip&delete=false&readLock=none"; from("direct:test") .pollE
public void configure() throws Exception {
String myFile = "file://myDir?fileName=MyFile.zip&delete=false&readLock=none";
from("direct:test")
.pollEnrich(myFile, 10000)
.to("seda:myQueue")
;
from("seda:myQueue")
.pollEnrich(myFile, 10000)
.log("Do something with the body")
;
}
目前,如果我执行第一个路由,poll-enrich会找到一个文件,但是当第二个路由中的poll-enrich执行时,它会返回一个null体。如果我只是单独执行第二个路由,它会正确地检索文件
为什么第二次轮询返回null,文件是否已锁定?(我希望结合使用noop、、和delete=false可以防止任何锁定)
《骆驼》认为第二次投票是重复的,因此过滤掉了吗?(我已经尝试实现自己的幂等存储库,在contains()上返回false,但第二个pollRich仍然返回null)
您可能想知道为什么我要尝试从两个路由进行充实,第一个路由必须检查是否存在大量文件,只有当所有文件都存在时(即PollRich不返回null),第二个路由才能开始处理它们
有没有其他我可以使用的方法?我在想,也许我需要创建一个bean,通过URI检索文件并将其作为主体返回
我使用的是骆驼2.11.0有什么具体的原因可以解释为什么你不使用一条路线
我不明白你为什么要用两条路线。文件组件可以检查文件是否存在,如果存在,则将其拉出。如果您担心要记住文件以避免重复,那么可以使用幂等存储库。至少,基于您的问题,我认为您不需要使用两条路由和content enricher EIP使逻辑复杂化。第二条路由返回空值,因为文件已在第一条路由中被使用……如果您只是在所有文件都存在的情况下查找信号消息,然后将文件使用者与和(可能是)一起使用,以避免在内存中携带大量有效负载等。我意识到这是一个老话题,但我也遇到了类似的问题。
我建议您尝试以下选项:
noop=true
你已经有了,而且
idempotent=false
要告诉驼峰Camel
处理同一文件两次是OK
测试后更新:
实际上,我使用上面建议的两种设置对此进行了测试,它有时会工作,但在中等负载下,它会失败,也就是说,对于某些交换返回null body,尽管不是全部
文档表明设置
noop=true
会自动设置幂等元=true
,因此我不确定在这种情况下是否遵守幂等元设置。请尝试使用strategyMethodAllowNull=“true”进行PollRich。默认情况下,此值为false。如果为false,聚合策略将查找现有的Exchange主体,以聚合从文件返回的内容。
当我们使strategyMethodAllowNull=“true”时,现有主体被视为null。因此,每次文件的内容都会被设置到当前的exchange正文中,正如您可能已经了解到的那样,这并不像预期的那样有效
noop=true&idempotent=false
我的猜测是,Camel忽略了idempotent=false
,并使用MemoryMessageIdRepository的实例。要解决此问题,可以将文件端点配置为使用自定义幂等元repo:
noop=true&idempotentRepository=#myRepo
并在注册表或spring上下文中注册自定义存储库:
@Component("myRepo")
public class MyRepo implements IdempotentRepository {
@Override
public boolean contains(Object o) {
return false;
}
...
}
正如我提到的,如果所有文件都存在,我只想执行第二个路由。这些文件很大(大约2gb),所以我不想复制其中的4个文件,然后发现第5个文件丢失了。我在第一个路由中有一些其他逻辑,报告丢失的文件等。第二个路由如何知道文件已被使用?邮件交换上是否设置了标题?我在文件://uri上使用noop=true,因此如果有某种方法可以告诉camel该文件尚未被使用,那么exchange有自己的ID以避免重复