如何在MQTT服务器不可访问的情况下启动camel

dzjeubhm  于 2023-03-02  发布在  Apache
关注(0)|答案(2)|浏览(106)

我想让我的Apache Camel应用程序更具弹性,即使在MQTT代理不可访问时也能启动。我们在互联网连接可能不稳定的物联网设备上使用Camel,我希望我们的应用程序即使在没有互联网连接的情况下也能启动。
示例性路由如下所示:

from("timer:heartbeat?period=5000")
    .routeId("send heartbeat")
    .setBody(simple("Hello World!"))
    .to("paho:myhostnome/heartbeat?brokerUrl={{broker.url}}")

只要MQTT服务器可用,这就可以正常工作,但是当服务器不可访问时,上下文在预热PahoEndpoint时会失败。

Caused by: org.apache.camel.FailedToCreateRouteException: Failed to create route send heartbeat: Route(send heartbeat)[[From[timer:heartbeat?period={{heartbe... because of Unable to connect to server
at org.apache.camel.impl.RouteService.warmUp(RouteService.java:147) ~[camel-core-2.19.3.jar:2.19.3]
at org.apache.camel.impl.DefaultCamelContext.doWarmUpRoutes(DefaultCamelContext.java:3758) ~[camel-core-2.19.3.jar:2.19.3]
at org.apache.camel.impl.DefaultCamelContext.safelyStartRouteServices(DefaultCamelContext.java:3665) ~[camel-core-2.19.3.jar:2.19.3]
at org.apache.camel.impl.DefaultCamelContext.doStartOrResumeRoutes(DefaultCamelContext.java:3451) ~[camel-core-2.19.3.jar:2.19.3]
at org.apache.camel.impl.DefaultCamelContext.doStartCamel(DefaultCamelContext.java:3305) ~[camel-core-2.19.3.jar:2.19.3]
at org.apache.camel.impl.DefaultCamelContext.access$000(DefaultCamelContext.java:202) ~[camel-core-2.19.3.jar:2.19.3]
at org.apache.camel.impl.DefaultCamelContext$2.call(DefaultCamelContext.java:3089) ~[camel-core-2.19.3.jar:2.19.3]
at org.apache.camel.impl.DefaultCamelContext$2.call(DefaultCamelContext.java:3085) ~[camel-core-2.19.3.jar:2.19.3]
at org.apache.camel.impl.DefaultCamelContext.doWithDefinedClassLoader(DefaultCamelContext.java:3108) ~[camel-core-2.19.3.jar:2.19.3]
at org.apache.camel.impl.DefaultCamelContext.doStart(DefaultCamelContext.java:3085) ~[camel-core-2.19.3.jar:2.19.3]
at org.apache.camel.support.ServiceSupport.start(ServiceSupport.java:61) ~[camel-core-2.19.3.jar:2.19.3]
at org.apache.camel.impl.DefaultCamelContext.start(DefaultCamelContext.java:3022) ~[camel-core-2.19.3.jar:2.19.3]
at org.apache.camel.spring.boot.RoutesCollector.maybeStart(RoutesCollector.java:242) ~[camel-spring-boot-2.19.3.jar:2.19.3]
at org.apache.camel.spring.boot.RoutesCollector.onApplicationEvent(RoutesCollector.java:217) ~[camel-spring-boot-2.19.3.jar:2.19.3]
... 13 common frames omitted
Caused by: org.eclipse.paho.client.mqttv3.MqttException: Unable to connect to server
at org.eclipse.paho.client.mqttv3.internal.TCPNetworkModule.start(TCPNetworkModule.java:79) ~[org.eclipse.paho.client.mqttv3-1.1.0.jar:na]
at org.eclipse.paho.client.mqttv3.internal.ClientComms$ConnectBG.run(ClientComms.java:650) ~[org.eclipse.paho.client.mqttv3-1.1.0.jar:na]
at java.lang.Thread.run(Thread.java:745) ~[na:1.8.0_121]
Caused by: java.net.ConnectException: Connection refused (Connection refused)
at java.net.PlainSocketImpl.socketConnect(Native Method) ~[na:1.8.0_121]
at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350) ~[na:1.8.0_121]
at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206) ~[na:1.8.0_121]
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188) ~[na:1.8.0_121]
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392) ~[na:1.8.0_121]
at java.net.Socket.connect(Socket.java:589) ~[na:1.8.0_121]
at org.eclipse.paho.client.mqttv3.internal.TCPNetworkModule.start(TCPNetworkModule.java:70) ~[org.eclipse.paho.client.mqttv3-1.1.0.jar:na]

我的第一个想法是在所有涉及Paho的路线上禁用自动启动,并手动启动它们。这不起作用,因为即使路线本身没有启动,PahoEndpoint也会启动。
我现在正在寻找另一种方法来处理这个问题。

ukxgm1gy

ukxgm1gy1#

Apache Camel 2.20以上版本提供了一个新的功能,让启动过程使用一个 * 管理控制器 * 来运行,该控制器从CamelContext本身接管启动过程。这允许设置更高级的配置,让控制器处理错误,并尝试重新启动失败的路由等。
有一个示例,它通过Sping Boot 配置,但您也可以从Java API配置它:https://github.com/apache/camel-spring-boot-examples/tree/main/supervising-route-controller
在即将发布的版本中,我们将改进这个新功能。对于旧版本的Camel,通常是组件本身提供或不提供任何重试机制,您需要配置,而不是快速失败。

46scxncf

46scxncf2#

Camel有一个try()catch()函数。
为什么不在调用to()之前添加一个try(),捕获异常,然后记录它呢?类似于:

from("timer:heartbeat?period=5000")
    .routeId("send heartbeat")
    .setBody(simple("Hello World!"))
    .doTry()
    .to("paho:myhostnome/heartbeat?brokerUrl={{broker.url}}")
     .doCatch( java.net.ConnectException.class).log("failed")
    .end()

相关问题