2017-09-04 31 views
0

我使用Spring Integration 4.3.9.RELEASE和Apache HTTP組件HttpClient(4.5.2)將包含300k上傳文件的請求中繼到後端服務。有時整個配置工作正常。但有時它表現不佳,而且它將需要將近10分鐘才能發送請求並獲得迴應。我使用純Java編寫了一些測試(請參閱Sending HTTP POST Request In Java),結果如下。如何使用大緩衝區設置HTTP出站網關發送請求

+------------------------------+------------------------+ 
| Data block size | Pause  | Totally time consuming | 
+------------------------------+------------------------+ 
| 2k    | 1 second | ~6 minutes    | 
| 2k    | 0.1 seocnd | ~33 seconds   | 
| 4k    | 0.1 second | ~16 seconds   | 
| 0.2k   | 0.1 second | ~6 minutes    | 
+------------------------------+------------------------+ 

每2k暫停1s和每0.2k暫停0.1s的情景都具有關閉時間流逝值。我想最可能發生的事情是發送數據的小塊(0.2k),但更少的停頓間隔(0.1s)。顯然不令人滿意的是,需要10分鐘才能得到迴應。 那麼如何設置緩衝區有點大以保證性能?

我的配置如下。

<bean id="restTemplate" class="org.springframework.web.client.RestTemplate"> 
    <constructor-arg> 
     <bean class="org.springframework.http.client.HttpComponentsClientHttpRequestFactory"> 
     <constructor-arg> 
      <bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean"> 
      <property name="targetClass" value="org.apache.http.impl.client.HttpClients"/> 
      <property name="targetMethod" value="createMinimal"/> 
      </bean> 
     </constructor-arg> 
     <property name="connectTimeout" value="${wonders.cloud.api.request.timeout}" /> 
     <property name="readTimeout" value="${wonders.cloud.api.request.timeout}" /> 
     </bean> 
    </constructor-arg> 
    <property name="messageConverters"> 
     <list> 
     <bean class="org.springframework.http.converter.StringHttpMessageConverter" /> 
     <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter" /> 
     <bean class="org.springframework.http.converter.FormHttpMessageConverter"> 
     </bean> 
     </list> 
    </property> 
    </bean> 

    <bean id="objectMapper" class="org.springframework.integration.support.json.Jackson2JsonObjectMapper"> 
    <constructor-arg ref="jacksonObjectMapper" /> 
    </bean> 
    <bean id="jacksonObjectMapper" class="com.fasterxml.jackson.databind.ObjectMapper" > 
    <property name="dateFormat"> 
     <bean class="java.text.SimpleDateFormat"> 
     <constructor-arg index="0" type="java.lang.String" value="yyyy-MM-dd'T'HH:mm:ss" /> 
     </bean> 
    </property> 
    <property name="serializationInclusion" value="#{ T(com.fasterxml.jackson.annotation.JsonInclude.Include).NON_NULL }" /> 
    </bean> 
    <bean class="org.springframework.beans.factory.config.MethodInvokingBean"> 
    <property name="targetObject" ref="jacksonObjectMapper"/> 
    <property name="targetMethod" value="disable"/> 
    <property name="arguments" value="#{ T(com.fasterxml.jackson.databind.DeserializationFeature).FAIL_ON_UNKNOWN_PROPERTIES }"/> 
    </bean> 
    <bean class="org.springframework.beans.factory.config.MethodInvokingBean"> 
    <property name="targetObject" ref="jacksonObjectMapper"/> 
    <property name="targetMethod" value="enable"/> 
    <property name="arguments" value="#{ T(com.fasterxml.jackson.databind.DeserializationFeature).READ_UNKNOWN_ENUM_VALUES_AS_NULL }"/> 
    </bean> 

    <int-http:inbound-gateway id="certificateInboundGateway" 
          path="/{uuid}/certificate" 
          supported-methods="POST" 
          request-channel="certificateRequestChannel" 
          reply-channel="certificateResponseChannel" 
          reply-key="fullway" 
          view-name="index"> 
    <int-http:header name="uuid" expression="#pathVariables.uuid" /> 
    </int-http:inbound-gateway> 

    <int:channel id="certificateRequestChannel" /> 
    <int:channel id="certificateResponseChannel" /> 

    <int:chain id="certificateProcessChain" 
      input-channel="certificateRequestChannel" 
      output-channel="certificateResponseChannel"> 
    <int:header-enricher> 
     <int:header name="multipartForm" expression="payload"/> 
    </int:header-enricher> 
    <int:transformer expression="headers.uuid" /> 
    <int:gateway request-channel="crmMemberInfoRetrieveChannel" /> 
    <int:filter expression="payload != null" /> 
    <int:transformer expression=" T(com.wd.fw.business.facade.huayan.transformer.WondersCloudObjectTransformer).buildCertificateForm(headers.multipartForm, payload.get('userid'), '${wonders.cloud.api.token}') " /> 
    <int:transformer ref="commonHeaderEnricher" method="transform" /> 
    <int:header-enricher> 
     <int:header name="octopus_sid" expression="'${wonders.cloud.api.octopus.sid}'" overwrite="true" /> 
     <int:header name="Content-Type" expression="'multipart/form-data'" overwrite="true" /> 
     <int:header name="octopus_apiid" expression="'${wonders.cloud.api.certificate.octopus.apiid}'" /> 
    </int:header-enricher> 
    <int-http:outbound-gateway url="${wonders.cloud.api.protocol}://${wonders.cloud.api.host}/${wonders.cloud.api.context.path}" 
           http-method="POST" 
           header-mapper="headerMapper" 
           rest-template="restTemplate" 
           charset="UTF-8" 
           expected-response-type="java.lang.String"> 
     <int-http:request-handler-advice-chain> 
     <ref bean="retrier" /> 
     </int-http:request-handler-advice-chain> 
    </int-http:outbound-gateway> 
    <int:gateway request-channel="dataEncryptChannel" /> 
    </int:chain> 

非常感謝。

回答

0

你可以嘗試這樣的事情:

ConnectionConfig connConfig = ConnectionConfig.custom() 
    .setBufferSize(DESIRED_BUFFER_SIZE) 
    .build(); 

CloseableHttpClient client = HttpClients.custom() 
     .setDefaultConnectionConfig(connConfig) 
     .build(); 

Setting socket buffer size in Apache HttpClient

Is there a way to see what the current value and change it for the socket buffer size used by Apache Http Client?

但是,爲什麼你認爲這個問題是不是在服務器端?

+0

非常感謝@ArtemBilan的回答。我認爲它確實增加了緩衝區大小。但是,緩衝區大小並不是性能的關鍵,任何其他謎團都需要探索。 –

+0

我試過兩種方法來測試這個問題,HttpClient和純Java,在服務器端收到的請求沒有區別。所以很難說,服務器有一些問題。 –

0

增加緩衝區大小無助於提高性能。 最後,我必須創建一個服務激活器,它將通過我的問題中提到的純java方法向遠程發送請求。

我在純Java中編寫了一些測試(參考發送Java POST中的HTTP POST請求),結果如下。

我也比較發送給服務器的請求,並且找不到任何區別。這很奇怪。

相關問題