【问题标题】:How to stop camel http retry如何停止骆驼http重试
【发布时间】:2017-03-30 16:05:45
【问题描述】:

我们正在使用 camel 2.18.1 的 toD 组件将正文发布到 http Web 服务,但是当 url 无效时,camel 在内部重试 2-3 分钟,这是我不想要的。

我进一步探索发现camel在内部使用org.apache.commons.httpclient.HttpMethodDirector来执行重试操作。如何阻止骆驼这样做。

部分异常日志如下。

<2017-03-29 16:33:59,084>:<>:<>:<>:<org.apache.commons.httpclient.HttpMethodDirector>:<INFO >:[Camel (camel-1) thread #20 - Threads]::<I/O exception (java.net.ConnectException) caught when processing request: Connection timed out (Connection timed out)>
<2017-03-29 16:33:59,085>:<>:<>:<>:<org.apache.commons.httpclient.HttpMethodDirector>:<INFO >:[Camel (camel-1) thread #20 - Threads]::<Retrying request>
<2017-03-29 16:36:06,313>:<>:<>:<>:<org.apache.commons.httpclient.HttpMethodDirector>:<INFO >:[Camel (camel-1) thread #20 - Threads]::<I/O exception (java.net.ConnectException) caught when processing request: Connection timed out (Connection timed out)>
<2017-03-29 16:36:06,314>:<>:<>:<>:<org.apache.commons.httpclient.HttpMethodDirector>:<INFO >:[Camel (camel-1) thread #20 - Threads]::<Retrying request>
<2017-03-29 16:38:13,545>:<>:<>:<>:<org.apache.commons.httpclient.HttpMethodDirector>:<INFO >:[Camel (camel-1) thread #20 - Threads]::<I/O exception (java.net.ConnectException) caught when processing request: Connection timed out (Connection timed out)>
<2017-03-29 16:38:13,546>:<>:<>:<>:<org.apache.commons.httpclient.HttpMethodDirector>:<INFO >:[Camel (camel-1) thread #20 - Threads]::<Retrying request>

这是我得到的堆栈跟踪

java.net.ConnectException: Connection timed out (Connection timed out)
        at java.net.PlainSocketImpl.socketConnect(Native Method)
        at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350)
        at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
        at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
        at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
        at java.net.Socket.connect(Socket.java:589)
        at java.net.Socket.connect(Socket.java:538)
        at java.net.Socket.<init>(Socket.java:434)
        at java.net.Socket.<init>(Socket.java:286)
        at org.apache.commons.httpclient.protocol.DefaultProtocolSocketFactory.createSocket(DefaultProtocolSocketFactory.java:80)
        at org.apache.commons.httpclient.protocol.DefaultProtocolSocketFactory.createSocket(DefaultProtocolSocketFactory.java:122)
        at org.apache.commons.httpclient.HttpConnection.open(HttpConnection.java:707)
        at org.apache.commons.httpclient.MultiThreadedHttpConnectionManager$HttpConnectionAdapter.open(MultiThreadedHttpConnectionManager.java:1361)
        at org.apache.commons.httpclient.HttpMethodDirector.executeWithRetry(HttpMethodDirector.java:387)
        at org.apache.commons.httpclient.HttpMethodDirector.executeMethod(HttpMethodDirector.java:171)
        at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:397)
        at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:323)
        at org.apache.camel.component.http.HttpProducer.executeMethod(HttpProducer.java:257)
        at org.apache.camel.component.http.HttpProducer.process(HttpProducer.java:152)
        at org.apache.camel.util.AsyncProcessorConverterHelper$ProcessorToAsyncProcessorBridge.process(AsyncProcessorConverterHelper.java:61)
        at org.apache.camel.processor.SendDynamicProcessor$1.doInAsyncProducer(SendDynamicProcessor.java:124)
        at org.apache.camel.impl.ProducerCache.doInAsyncProducer(ProducerCache.java:436)
        at org.apache.camel.processor.SendDynamicProcessor.process(SendDynamicProcessor.java:119)
        at org.apache.camel.management.InstrumentationProcessor.process(InstrumentationProcessor.java:77)
        at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:197)
        at org.apache.camel.processor.Pipeline.process(Pipeline.java:120)
        at org.apache.camel.processor.Pipeline.process(Pipeline.java:83)
        at org.apache.camel.processor.TryProcessor.process(TryProcessor.java:113)
        at org.apache.camel.processor.TryProcessor.process(TryProcessor.java:84)
        at org.apache.camel.management.InstrumentationProcessor.process(InstrumentationProcessor.java:77)
        at org.apache.camel.processor.RedeliveryErrorHandler.process(RedeliveryErrorHandler.java:542)
        at org.apache.camel.processor.CamelInternalProcessor.process(CamelInternalProcessor.java:197)
        at org.apache.camel.processor.Pipeline.process(Pipeline.java:120)
        at org.apache.camel.processor.Pipeline.process(Pipeline.java:83)
        at org.apache.camel.processor.Pipeline.process(Pipeline.java:120)
        at org.apache.camel.processor.Pipeline.access$100(Pipeline.java:44)
        at org.apache.camel.processor.Pipeline$1.done(Pipeline.java:138)
        at org.apache.camel.processor.ThreadsProcessor$ProcessCall.run(ThreadsProcessor.java:88)
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
        at java.util.concurrent.FutureTask.run(FutureTask.java:266)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
        at java.lang.Thread.run(Thread.java:745)

最后是路由构建器中使用的代码

 from("disruptor:" + "CallAPostService")
                    .routeId("CallAPostService")
                    .threads()
                    .log(LoggingLevel.INFO, LOG, "Processing id ${id} disruptor")
                    .doTry()
                        .process(new populateRequestBody()) // this processor sets the request xml to excahnge body
                                    .log(LoggingLevel.INFO, LOG, "Request XML = ${body}")
                                    .setHeader(Exchange.HTTP_METHOD, simple("POST"))
                                    .setHeader(Exchange.HTTP_BASE_URI, constant(""))
                                    .setHeader(Exchange.HTTP_PATH, constant(""))
                                    .setHeader(Exchange.HTTP_URI, simple(""))
                                                                    .setHeader(Exchange.HTTP

_URL, simple(""))
                                                                .toD("http://172.0.0.0:7001/myapp/cosumemessage" + "?bridgeEndpoint=true")                                                                
 .doCatch(Exception.class)                            
 .log(LoggingLevel.ERROR, LOG, "Processing id ${id} disruptor, Unknown Exception")
.doFinally();

【问题讨论】:

  • 您是否尝试过将当前的异常处理替换为onException(ConnectException.class).handled(true).maximumRedeliveries(0)...; 之类的东西?在这里,您明确表示不应尝试重新投递。
  • @RomanVottner 我面临同样的问题。我尝试了解决方案,但它没有从 maximumRedeliveries 方法中选择重试,或者似乎覆盖了它。
  • 对我来说它似乎是由org.apache.commons.httpclient.HttpMethodDirector 类驱动的

标签: java apache-camel apache-httpcomponents


【解决方案1】:

实现一个 HttpClientConfigurer 并将其写入注册表。

@Bean(name = "httpConfigurer")
public HttpClientConfigurer createCustomConfigurer() {
    return new HttpClientConfigurer() {

        @Override
        public void configureHttpClient(HttpClient client) {
            client.getParams().setParameter(HttpConnectionParams.CONNECTION_TIMEOUT, 10000);
            client.getParams().setParameter("http.method.retry-handler", new DefaultHttpMethodRetryHandler(0, false));            }
    };
}

设置HttpComponent的httpClientConfigurer如下:

.toD("http://1.2.3.4/xyz?httpClientConfigurer=httpConfigurer")

【讨论】:

  • 每当我们使用无效的 URL 并尝试发布消息时,线程都会等待超过 2 分钟,直到超时。因此,其他线程被卡住了。那么我可以将骆驼路由生成器的连接超时配置为 10 秒吗?
  • 您在这里提到的示例是使用“to”组件,但我们使用的是 routebuilder 中的“toD”(使用 java DSL)。
  • client.getParams().setParameter(HttpConnectionParams.CONNECTION_TIMEOUT, 10000); 添加到configureHttpClient,您可以在我更新的答案中看到。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-15
  • 2018-12-26
  • 2020-10-21
  • 2017-05-31
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多