代码之家  ›  专栏  ›  技术社区  ›  Genaut

ApacheHTTP客户端4.5.x的死锁线程

  •  0
  • Genaut  · 技术社区  · 6 年前

    在我的WebLogic中,很多线程都是这样的,但我无法找出原因。这是stacktrace。我设置了连接的所有超时:

    • 设置连接请求超时
    • 设置连接超时
    • 设置锁定超时

    这是堆栈跟踪,我看不到代码(在post的末尾)有任何可能导致此stucks线程的问题。你知道吗?

    <22-May-2018 11.48.46 CEST> <Error> <WebLogicServer> <BEA-000337> <[STUCK] ExecuteThread: '36' for queue: 'weblogic.kernel.Default (self-tuning)' has been busy for "616" seconds working on the request "Http Request Information: weblogic.servlet.internal.ServletRequestImpl@7567f23c[POST /aca/rest/servicesupport]
    ", which is more than the configured time (StuckThreadMaxTime) of "600" seconds in "server-failure-trigger". Stack trace:
        java.net.SocketInputStream.socketRead0(Native Method)
        java.net.SocketInputStream.socketRead(SocketInputStream.java:116)
        java.net.SocketInputStream.read(SocketInputStream.java:170)
        java.net.SocketInputStream.read(SocketInputStream.java:141)
        org.apache.http.impl.io.SessionInputBufferImpl.streamRead(SessionInputBufferImpl.java:137)
        org.apache.http.impl.io.SessionInputBufferImpl.fillBuffer(SessionInputBufferImpl.java:153)
        org.apache.http.impl.io.SessionInputBufferImpl.readLine(SessionInputBufferImpl.java:282)
        org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:138)
        org.apache.http.impl.conn.DefaultHttpResponseParser.parseHead(DefaultHttpResponseParser.java:56)
        org.apache.http.impl.io.AbstractMessageParser.parse(AbstractMessageParser.java:259)
        org.apache.http.impl.DefaultBHttpClientConnection.receiveResponseHeader(DefaultBHttpClientConnection.java:163)
        org.apache.http.impl.conn.CPoolProxy.receiveResponseHeader(CPoolProxy.java:165)
        org.apache.http.protocol.HttpRequestExecutor.doReceiveResponse(HttpRequestExecutor.java:273)
        org.apache.http.protocol.HttpRequestExecutor.execute(HttpRequestExecutor.java:125)
        org.apache.http.impl.execchain.MainClientExec.createTunnelToTarget(MainClientExec.java:473)
        org.apache.http.impl.execchain.MainClientExec.establishRoute(MainClientExec.java:398)
        org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:237)
        org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:185)
        org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:89)
        org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:111)
        org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:185)
        org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:83)
        org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:108)
        com.iberia.es.integration.FacadeSFIntegrationImpl.requestToken(FacadeSFIntegrationImpl.java:71)
    

    这是带有连接方法的类。我正在使用 Apache HTTP客户端4.5.3 :

    public class FacadeSFIntegrationImpl implements FacadeSFIntegration {
    
    
        @Autowired
        @Qualifier("confResolver")
        ConfigurationResolver config;
    
        @Override
        public String requestToken(List<IbEsNameAndValueDTO> params, String url, Boolean proxyEnabled,
                Integer connectionRequestTimeout, Integer connectTimeout, Integer socketTimeout) {
    
            if (params != null && !params.isEmpty() && url != null) {
    
                try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
                    // Preparamos los parámetros
                    List<NameValuePair> httpParams = convertParams(params);
    
                    // Configuramos la llamada
                    RequestConfig httpConfig = configHttpRequest(proxyEnabled, connectionRequestTimeout, connectTimeout,
                            socketTimeout);
    
                    // Realizamos la llamada post
                    HttpPost post = new HttpPost(url);
                    post.setConfig(httpConfig);
                    post.setEntity(new UrlEncodedFormEntity(httpParams, "UTF-8"));
    
                    // Controlamos la respuesta
                    HttpResponse response = httpClient.execute(post);
                    int status = response.getStatusLine().getStatusCode();
                    if (status >= 200 && status < 300) {
                        HttpEntity entity = response.getEntity();
                        return EntityUtils.toString(entity);
                    }
    
                } catch (UnsupportedEncodingException e) {
                    //LOG
                } catch (ClientProtocolException e) {
                    //LOG
                } catch (IOException e) {
                    //LOG
                }
            }
    
            return null;
        }
    
    
        private RequestConfig configHttpRequest(Boolean proxyEnabled, Integer connectionRequestTimeout,
                Integer connectTimeout, Integer socketTimeout) {
    
            Builder httpConfigBuilder = RequestConfig.custom();
    
            if (proxyEnabled) {
                String proxyUrl = config.getValue("proxy.host");
                String proxyPort = config.getValue("proxy.puerto");
    
                HttpHost proxy = new HttpHost(proxyUrl, Integer.valueOf(proxyPort));
                httpConfigBuilder.setProxy(proxy);
            }
    
            String connectionRequestTimeoutDefaultS = config.getValue("proxy.timeout.connectionRequest");
            httpConfigBuilder.setConnectionRequestTimeout((connectionRequestTimeout != null) ? connectionRequestTimeout
                    : Integer.valueOf(connectionRequestTimeoutDefaultS));
    
            String connectTimeoutDefaultS = config.getValue("proxy.timeout.connect");
            httpConfigBuilder.setConnectTimeout((connectTimeout != null) ? connectTimeout : Integer
                    .valueOf(connectTimeoutDefaultS));
    
            String socketTimeoutDefaultS = config.getValue("proxy.timeout.socket");
            httpConfigBuilder.setSocketTimeout((socketTimeout != null) ? socketTimeout : Integer
                    .valueOf(socketTimeoutDefaultS));
    
            return httpConfigBuilder.build();
        }
    
        private List<NameValuePair> convertParams(List<IbEsNameAndValueDTO> params) {
    
            List<NameValuePair> result = new ArrayList<>();
            for (IbEsNameAndValueDTO nameValue : params) {
                result.add(new BasicNameValuePair(nameValue.getName(), nameValue.getValue()));
            }
            return result;
    
        }
    
    }
    
    1 回复  |  直到 6 年前
        1
  •  1
  •   ok2c    6 年前

    在通过代理建立到目标的通道时,请求执行被卡住。请注意,请求级套接字超时设置仅适用于完全建立的连接。为了避免这种情况,您可能希望在连接管理器级别将默认超时设置为正值 SocketConfig 使用 #setDefaultSocketConfig 客户端生成器或直接在连接管理器上的方法

    RequestConfig requestConfig = RequestConfig.custom()
            .setConnectTimeout(5000)
            .setSocketTimeout(5000)
            .build();
    SocketConfig socketConfig = SocketConfig.custom()
            .setSoTimeout(5000)
            .build();
    CloseableHttpClient client = HttpClients.custom()
            .setDefaultRequestConfig(requestConfig)
            .setDefaultSocketConfig(socketConfig)
            .build();