我定义了 10 条路线,其中列出了 2 条路线。其他 8 个是相同的,但 from 端点是不同的目录。每个路由选择一个位于目录中的文件,并由一个 groovy 类处理。当一个文件被放入其中一个目录时,它工作正常,但是当一个文件同时放入每个目录时,每个线程似乎都失控了。我确实收到了我已经拿起每个文件的日志消息,但是似乎每个线程都使用一个进程“beginProcess”,因为它就像我在 groovy 中定义的所有变量都随着每个文件被拾取而改变。我不确定这是否有意义,但是有人可以告诉我我在下面所做的事情是合法的吗?基本上多条路线可以调用一个类(class),如果是这样,我是否这样做正确?如果是这样,那么至少我会知道它必须在我的 groovy 类中(但看到它与一个文件一起工作表明它不在这里,但此时不假设)。非常感谢!
<camel:camelContext id="myId"
xmlns="http://camel.apache.org/schema/spring">
<route>
<from
uri="file://directoryStructure1/?move=archive&sortBy=ignoreCase:file:name&readLock=markerFile&readLockCheckInterval=5000&readLockTimeout=10m&maxMessagesPerPoll=1" />
<process ref="beginProcess"></process>
</route>
<route>
<from
uri="file://directoryStructure2/?move=archive&sortBy=ignoreCase:file:name&readLock=markerFile&readLockCheckInterval=5000&readLockTimeout=10m&maxMessagesPerPoll=1" />
<process ref="beginProcess"></process>
</route>
</camel:camelContext>
<bean id="beginProcess" class="package.groovy.class"> </bean>
最佳答案
似乎您正在使用类的单例(单个实例)对象,因为当您定义“beginProcess”时,这将是 spring 中的默认对象。
没关系,如果“package.groovy.class”的实现是线程安全的,似乎是这样,事实并非如此。
基本上,有几种方法可以解决这个问题。
1) 从不处理并发。使用 SEDA 传输很容易实现,它可以在处理另一个文件时将文件堆叠在队列中。
<route>
<from
uri="file://directoryStructure1/?move=archive&sortBy=ignoreCase:file:name&readLock=markerFile&readLockCheckInterval=5000&readLockTimeout=10m&maxMessagesPerPoll=1" />
<to uri="seda:process"/>
</route>
<route>
<from
uri="file://directoryStructure2/?move=archive&sortBy=ignoreCase:file:name&readLock=markerFile&readLockCheckInterval=5000&readLockTimeout=10m&maxMessagesPerPoll=1" />
<to uri="seda:process"/>
</route>
<route>
<from uri="seda:process"/>
<process ref="beginProcess"/>
</route>
2) 每次调用 beginProcess 时创建一个新 bean:
<bean id="beginProcess" class="package.groovy.class" scope="prototype"/>
找到了一个关于 spring bean 范围的好页面 here .
3) 使您的 package.groovy.class 线程安全。也就是说,不应将任何字段和变量保留为状态,或者状态应该可以在并发请求之间共享并同步。
关于spring - 多个 Camel 路线处理同一个文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11192743/