我将Apache Camel和Spring(而不是Spring Boot)与XML一起使用。
我有camel-context.xml配置文件,其中包含一个从MQTT服务器到JMS服务器和viceversa的路由示例,只是为了分派消息。
下面是我的camel-context.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:camel="http://camel.apache.org/schema/spring"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd
http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd">
<bean id="quadtreeProcessor" class="es.gateway.router.QuadtreeProcessor" />
<camelContext id="camelContext" xmlns="http://camel.apache.org/schema/spring">
<route id="quadTreeConsumerProducer">
<from uri="jms:topic:T_ETSI_PRODUCER"/>
<process ref="quadtreeProcessor"/>
<to uri="mqtt:quadtree?host=tcp://localhost:1883&publishTopicName=${header.publishTopicName}"/>
</route>
<route id="quadTreeConsumerRoute">
<from uri="mqtt:quadtree?host=tcp://localhost:1883&subscribeTopicName=CONSUMER/DENM/#"/>
<to uri="jms:topic:T_ETSI_CONSUMER"/>
</route>
</camelContext>
<bean id="jmsConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
<property name="brokerURL" value="tcp://localhost:10011"/>
</bean>
<bean id="activemq" class="org.apache.activemq.camel.component.ActiveMQComponent" />
package es.conncar.main;
import org.apache.camel.RuntimeCamelException;
import org.apache.camel.main.MainListener;
import org.apache.camel.main.MainListenerSupport;
import org.apache.camel.main.MainSupport;
import org.apache.log4j.Logger;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import es.gateway.config.Config;
public class Main {
final static Logger logger = Logger.getLogger(Main.class);
private static boolean exit = false;
private org.apache.camel.spring.Main camelMain;
public static void main(String[] args) throws Exception {
try {
ApplicationContext springContext = new ClassPathXmlApplicationContext("app-context.xml");
logger.info("Spring context initialized");
Config config = (Config) springContext.getBean("config");
Main main = new Main();
main.boot();
} catch (Exception e) {
logger.error("Unknown error in main", e);
}
}
public void boot() throws Exception {
camelMain = new org.apache.camel.spring.Main();
camelMain.addMainListener((MainListener) new Events());
camelMain.setApplicationContextUri("camel-context.xml");
logger.info("Starting Camel. Use ctrl + c to terminate the JVM.\n");
camelMain.run();
}
public static class Events extends MainListenerSupport {
@Override
public void afterStart(MainSupport main) {
logger.info("Camel is now started!");
}
@Override
public void beforeStop(MainSupport main) {
logger.info("Camel is now being stopped!");
}
}
}
当在我的主类中运行相同的路由和配置时,问题就会出现,由于RuntimeCamelException出现,几秒钟后问题就会消失。
异常跟踪是:
骆驼开始没问题
[30/11/2018 08:37:08][INFO ][es.gateway.main.Main] - Spring context initialized
[30/11/2018 08:37:08][INFO ][es.gateway.main.Main] - Starting Camel. Use ctrl + c to terminate the JVM.
10秒后
[30/11/2018 08:37:21][ERROR][es.gateway.main.Main] - Unknown error in Camel
org.apache.camel.RuntimeCamelException: java.util.concurrent.TimeoutException
at org.apache.camel.util.ObjectHelper.wrapRuntimeCamelException(ObjectHelper.java:1830)
at org.apache.camel.spring.SpringCamelContext.start(SpringCamelContext.java:136)
at org.apache.camel.spring.CamelContextFactoryBean.start(CamelContextFactoryBean.java:369)
at org.apache.camel.spring.CamelContextFactoryBean.onApplicationEvent(CamelContextFactoryBean.java:416)
at org.apache.camel.spring.CamelContextFactoryBean.onApplicationEvent(CamelContextFactoryBean.java:94)
at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:172)
at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:165)
at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:139)
at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:393)
at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:347)
at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:883)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:546)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)
at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:93)
at org.apache.camel.spring.Main.createDefaultApplicationContext(Main.java:222)
at org.apache.camel.spring.Main.doStart(Main.java:154)
at org.apache.camel.support.ServiceSupport.start(ServiceSupport.java:61)
at org.apache.camel.main.MainSupport.run(MainSupport.java:170)
at es.gateway.main.Main.boot(Main.java:105)
at es.gateway.main.Main.main(Main.java:77)
Caused by: java.util.concurrent.TimeoutException
at org.fusesource.mqtt.client.Promise.await(Promise.java:83)
at org.apache.camel.component.mqtt.MQTTEndpoint.connect(MQTTEndpoint.java:348)
at org.apache.camel.component.mqtt.MQTTConsumer.doStart(MQTTConsumer.java:38)
at org.apache.camel.support.ServiceSupport.start(ServiceSupport.java:61)
at org.apache.camel.impl.DefaultCamelContext.startService(DefaultCamelContext.java:3705)
at org.apache.camel.impl.DefaultCamelContext.doStartOrResumeRouteConsumers(DefaultCamelContext.java:4023)
at org.apache.camel.impl.DefaultCamelContext.doStartRouteConsumers(DefaultCamelContext.java:3958)
at org.apache.camel.impl.DefaultCamelContext.safelyStartRouteServices(DefaultCamelContext.java:3878)
at org.apache.camel.impl.DefaultCamelContext.doStartOrResumeRoutes(DefaultCamelContext.java:3642)
at org.apache.camel.impl.DefaultCamelContext.doStartCamel(DefaultCamelContext.java:3494)
at org.apache.camel.impl.DefaultCamelContext.access$000(DefaultCamelContext.java:209)
at org.apache.camel.impl.DefaultCamelContext$2.call(DefaultCamelContext.java:3253)
at org.apache.camel.impl.DefaultCamelContext$2.call(DefaultCamelContext.java:3249)
at org.apache.camel.impl.DefaultCamelContext.doWithDefinedClassLoader(DefaultCamelContext.java:3272)
at org.apache.camel.impl.DefaultCamelContext.doStart(DefaultCamelContext.java:3249)
at org.apache.camel.support.ServiceSupport.start(ServiceSupport.java:61)
at org.apache.camel.impl.DefaultCamelContext.start(DefaultCamelContext.java:3165)
at org.apache.camel.spring.SpringCamelContext.start(SpringCamelContext.java:133)
... 18 more
看起来,当无法连接到MQTT代理时,路由会引发超时(没关系),但是这个异常不是在路由中捕获的,而是在context-main类中捕获的(没关系)。
我遵循了这本食谱:
有人经历过吗?当RuntimeExceptions在路由中出现时,是否有一种方法可以保持路由的工作和主程序的活动?我希望如此!
Thansk提前!
编辑:我发现有几个话题在谈论这个。解决方案似乎是激活监督控制器,但我找不到没有Spring Boot的方法(我使用普通Spring混合xml和注释配置)。有人能帮忙吗?
我建议使用camel-paho,因为Eclipse Paho比camel-mqtt使用的旧的FuseSource MQTT客户机库维护得更活跃。
也就是说,camel-mqtt组件的问题是,它在启动时需要一个工作连接。您可以配置它的重新连接选项来设置各种延迟等。
还有一种替代的路由启动机制,它允许使用后台线程启动路由,后台线程可以监视路由并处理重试等。它的supervisoringRouteController
,请注意,围绕其JMX管理功能,还有一些事情需要实现,但除此之外应该没有问题。它缺乏更适当的文档。我们正在考虑将其作为Camel3中的一个更突出的或默认的内容。
问题内容: 我有一个, 并且需要根据外部数据在控制器和视图之间进行选择,因此我使用和。 如果我只有它,一切都很好,但是当我添加时,会出现此错误: 可能看起来有些像(它说有对象,但看起来像,但是我不太擅长调试) 这是我的代码: 编辑 基于RadimKöhlers答案的更改 新错误: 解 这至少需要版本的 问题答案: 问题是,这只是必须返回 对象 代表或 (它的名字) http://angular-u
单击关闭程序后,浏览器中出现另一个错误: 详细的编译器输出如下所示: C:\程序文件(x86)\IIS Express>D:_myurl\bin\roslyn\csc.exe/T:Library/utf8output/nostdlib+/R:“C:\Windows\Microsoft.NET\Framework\v4.0.30319\mscorlib.dll”/R:“C:\Windows\Micr
我正试图得到一个简单的搜索功能与我的烧瓶应用程序。我有以下启动搜索的代码 这与我的搜索/controllers.py脚本连接起来,看起来像这样 不幸的是,每当我实际搜索时,都会出现路由错误: FormDataRoutingRedirect:已向此URL发送请求(http://localhost:8080/search)但路由系统自动发出重定向到“http://localhost:8080/sear
我有一个在 Openshift Online 启动器中运行的应用程序,该应用程序在过去 5 个月内一直有效。服务后面的单个 Pod,定义了执行边缘 tls 终止的路由。 自星期六以来,当尝试访问该应用程序时,我收到错误消息 应用程序不可用应用程序当前未在此endpoint上为请求提供服务。它可能尚未启动或仍在启动。 您看到此页面的可能原因: 主机不存在。确保正确键入了主机名,并且存在与此主机名匹配
我有一个在Openshift 4.6中运行的应用程序。 pod正在运行,我可以执行它并检查它,我可以端口转发到它并访问它。 尝试访问应用程序时,我得到错误消息: 应用程序不可用应用程序当前未在此endpoint上为请求提供服务。它可能尚未启动或仍在启动。 您看到此页面的可能原因: 主机不存在。请确保键入的主机名正确,并且存在与该主机名匹配的路由。 主机存在,但没有匹配的路径。检查URL路径是否输入
任何关于下一步何去何从的帮助都将不胜感激。 下面是由Spring Bootinitializr生成的文件夹结构。我唯一改变的是使src成为源根。