即使无法访问 MQTT 服务器如何启动骆驼
我想让我的 Apache Camel 应用程序更有弹性,即使在无法访问 MQTT 代理时也能启动.我们在互联网连接可能不稳定的 IoT 设备上使用 Camel,我希望即使没有互联网连接也能启动我们的应用程序.
I would like to make my Apache Camel application to be more resilient and start even when the MQTT broker is not reachable. We are using Camel on IoT devices with a possibly unstable internet connection and I want our application to start even without internet access.
示例路线如下所示:
from("timer:heartbeat?period=5000")
.routeId("send heartbeat")
.setBody(simple("Hello World!"))
.to("paho:myhostnome/heartbeat?brokerUrl={{broker.url}}")
只要 MQTT 服务器可用,它就可以正常工作.但是,当服务器无法访问时,上下文会在 PahoEndpoint 预热时失败.
This works fine as long as the MQTT server is available. However when the server is not reachable, the context fails while warming up the 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 也会启动.
My first idea was to disable auto startup on all routes involving Paho and start them manually. This does not work as the PahoEndpoint is started even when the route itself is not started.
我现在正在寻找解决此问题的替代方法.
I'm now looking for an alternative approach to handle this problem.
推荐答案
Apache Camel 2.20 及更高版本带有一个新功能,可以让启动过程使用 supervisor 控制器 来运行,该控制器从 CamelContext
本身.这允许设置更高级的配置,让控制器处理错误,并尝试重试启动失败的路由等.
Apache Camel 2.20 onwards comes with a new functionality to let the startup procedure run using a superviser controller that takes over starting up from CamelContext
itself. This allows to setup more advanced configuration to let the controller handle errors, and attempt to retry starting the failed routes etc.
有一个通过 Spring Boot 配置的示例,但您也可以从 Java API 配置它:https://github.com/apache/camel/tree/master/examples/camel-example-spring-boot-supervising-route-controller
There is an example where its configured via Spring Boot, but you can configure it from Java API as well: https://github.com/apache/camel/tree/master/examples/camel-example-spring-boot-supervising-route-controller
在即将发布的版本中,我们将改进这一新功能.对于较旧版本的 Camel,通常组件本身可能会或可能不会提供任何类型的重试机制,您需要进行配置,而不是快速失败.
In the upcoming releases we will improve on this new functionality. For older versions of Camel then its often the component itself that may or may not offer any kind of retry mechanism, you need to configure, instead of failing fast.
相关文章