Ошибка тайм-аута подключения в исходящей конечной точке Mule http при подключении к внешнему серверу

У меня есть 2 приложения-мула, работающие на одном компьютере, в котором приложение A отправляет запрос на получение в приложение B, а приложение B подключается к внешнему http-приложению для получения информации. По сути, приложение B является приложением перенаправления, и оно много раз в день выдает исключение с превышением времени ожидания подключения (java.net.SocketTimeoutException). По моему наблюдению, это происходит всякий раз, когда приложение (B) какое-то время простаивает, а затем, если оно получает запрос, оно прерывает время соединения для первого запроса при подключении к внешнему серверу на исходящей конечной точке http, и последующие запросы работают нормально. Это происходит только в одной среде, где у меня нет доступа к отладке, и я не сталкивался с этой проблемой ни в одной другой среде, хотя есть две другие среды с точно такой же настройкой.

Любая помощь/предложения/руководство приветствуется при отладке проблемы. Код

<flow name="Main" >
        <https:inbound-endpoint exchange-pattern="request-response"
            host="${http.listenHost}" port="${support-1.0.https.port}"
            path="${service.root}"  encoding="UTF-8"
             doc:name="HTTP" connector-ref="HTTPSConnector">
            <!-- NB: SECURITY TURNED OFF BY DEFAULT AS YOU WILL NEED TO ADD RECORDS 
                TO THE DATABASE IN ORDER TO USE THIS -->
            <!-- <mule-ss:http-security-filter realm="mule-realm"/> -->
        </https:inbound-endpoint>

        <custom-interceptor class="xyz.BasicLogger">
            <spring:property name="outermost" value="true" />
        </custom-interceptor>
        <set-session-variable variableName="operation" value="#[message.inboundProperties['http.method']]" doc:name="Operation"/>

        <set-variable variableName="_logging.text" value="Incoming Payload" doc:name="Logging" />
        <component doc:name="Payload Logger">
            <spring-object bean="idPayloadLogger" />
        </component>

        <set-session-variable variableName="http.status"
            value="200" doc:name="HTTP Status" />

        <flow-ref name="Cache" doc:name="Cache"/>

        <http:response-builder status="#[sessionVars['http.status']]" contentType="application/json" doc:name="HTTP Response Builder">
            <http:header name="consumerTransId" value="#[sessionVars['tx.id']]"/>
            <http:header name="http.status" value="#[sessionVars['http.status']]"/>
            <http:header name="Content-Type" value="application/json;charset=utf-8"/>
        </http:response-builder>

    </flow>
    <flow name="Cache">
        <expression-transformer expression="#[payload]" doc:name="Create key for cache"/>
        <custom-interceptor doc:name="PayloadCache"    class="xyz.ehcache.PayloadCache"/>
        <flow-ref name="GetResult" doc:name="GetResult"/>
    </flow>

    <sub-flow name="GetResult">
        <choice doc:name="Choice">
            <when expression="sessionVars.operation =='GET'">
                <processor-chain doc:name="GET">
                    <set-variable variableName="_logging.calloutName " value="Registry GET" doc:name="_logging.calloutName "/>
                    <component doc:name="Java"><spring-object bean="idTimerLogger"/></component>
                    <http:outbound-endpoint exchange-pattern="request-response" host="${registry.host}" port="${registry.port}"
                     path="${registry.path}/#[message.inboundProperties.'http.relative.path']?#[message.inboundProperties.'http.query.string']" method="GET" doc:name="HTTP" responseTimeout="10000"/>
                    <component doc:name="Java"><spring-object bean="idTimerLogger"/></component>
                </processor-chain>

            </when>
            <when expression="sessionVars.operation =='DELETE'">
                <processor-chain doc:name="DELETE">
                    <set-variable variableName="_logging.calloutName " value="Registry DELETE" doc:name="_logging.calloutName "/>
                    <component doc:name="Java"><spring-object bean="idTimerLogger"/></component>
                    <http:outbound-endpoint exchange-pattern="request-response" host="${registry.host}" port="${registry.port}" path="${registry.path}/#[message.inboundProperties.'http.relative.path']?#[message.inboundProperties.'http.query.string']"
                     method="DELETE" doc:name="HTTP"/>
                    <component doc:name="Java"><spring-object bean="idTimerLogger"/></component>
                </processor-chain>
            </when>
            <otherwise>
                <processor-chain doc:name="Unsupported Verb">
                    <set-variable variableName="_error.code" value="2" doc:name="Error code"/>
                    <custom-transformer class="xyz.eai.utility.transformation.ErrorMessageTransformer" doc:name="Java"/>
                    <json:object-to-json-transformer doc:name="Object to JSON"/>
                </processor-chain>
            </otherwise>
        </choice>
        <object-to-string-transformer doc:name="Object to String"/>
    </sub-flow>

</mule>

и ошибка `

Exception stack is:
1. connect timed out (java.net.SocketTimeoutException)
  java.net.PlainSocketImpl:-2 (null)
2. The host did not accept the connection within timeout of 2000 ms (org.apache.commons.httpclient.ConnectTimeoutException)
  org.apache.commons.httpclient.protocol.ReflectionSocketFactory:155 (null)
3. Failed to route event via endpoint: DefaultOutboundEndpoint{endpointUri=http://xyz.ca.com:8080/search?param1=xyz&param2=true, connector=HttpConnector
{
  name=connector.http.mule.default
  lifecycle=start
  this=59c02565
  numberOfConcurrentTransactedReceivers=4
  createMultipleTransactedReceivers=true
  connected=true
  supportedProtocols=[http]
  serviceOverrides=<none>
}
,  name='endpoint.http.xyz.com.8080.search.param1.xyz.param2.true', mep=REQUEST_RESPONSE, properties={isActive=true, http.method=GET, exceptionOnMessageError=true, param1=xyz}, transactionConfig=Transaction{factory=null, action=INDIFFERENT, timeout=0}, deleteUnacceptedMessages=false, initialState=started, responseTimeout=10000, endpointEncoding=UTF-8, disableTransportTransformer=false}. Message payload is of type: GetMethod (org.mule.api.transport.DispatchException)
  org.mule.transport.http.HttpClientMessageDispatcher:151 (http://www.mulesoft.org/docs/site/current3/apidocs/org/mule/api/transport/DispatchException.html)`
################3

Добавлен цикл «до успешного завершения» для исходящей конечной точки http в моем приложении B, и он работает, если я обращаюсь к нему отдельно. Но когда приложение A пытается связаться с приложением B, даже до того, как приложение B попытается подключиться к внешнему серверу и вернет ответ, исходящая конечная точка HTTP в приложении A выдает org.mule.api.transport.DispatchException with message : Failed to route event via endpoint: DefaultOutboundEndpoint{endpointUri=https://application-b/xyz, connector=HttpsConnector, и когда приложение B завершает свои повторные попытки и пытается отправьте ответ приложению A, получив ошибку: org.mule.transport.http.HttpsMessageProcessTemplate: Exception sending http response after error: Connection has been shutdown: javax.net.ssl.SSLException: java.net.SocketException: Software caused connection abort: socket write error


person KBSri    schedule 03.03.2017    source источник


Ответы (1)


Вам нужно использовать untilSuccess на вашем коннекторе HTTP/HTTPS.

<until-successful maxRetries="5" synchronous="true" doc:name="Until Successful">
            <http:request config-ref="HTTP_Request_Configuration" path="/test" method="POST" doc:name="HTTP"/>
        </until-successful>
person Satheesh Kumar    schedule 03.03.2017
comment
Привет, Сатиш, я реализовал твое предложение, но столкнулся с другой проблемой. Я добавил детали. Пожалуйста, посмотрите. - person KBSri; 11.03.2017
comment
Привет, KBsri, время ожидания соединения истекло, когда вы отправляете ответ обратно, увеличьте время ожидания в запросчике приложения A. - person Satheesh Kumar; 11.03.2017
comment
Спасибо за ваш вклад. но проблема в том, что еще до завершения обработки в приложении B приложение A уже переслало исключение отправки (в котором говорится, что оно не может перенаправить событие в приложение B) запрашивающей стороне. Я не могу понять, почему приложение A получает исключение маршрутизации, когда сообщение фактически достигло приложения B и обрабатывается там. - person KBSri; 11.03.2017