origin

I looked at the server yesterday afternoon, and there were 500 response codes. Scrutinize it.

throwable:org.apache.http.ConnectionClosedException: Premature end of Content-Length delimited message body (expected: 146256; received: 139121) at org. Apache. HTTP. Impl. IO. ContentLengthInputStream. Read the at (ContentLengthInputStream. Java: 178) org.apache.http.conn.EofSensorInputStream.read(EofSensorInputStream.java:135) at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:284) at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:326) at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178) at java.io.InputStreamReader.read(InputStreamReader.java:184) at java.io.Reader.read(Reader.java:140) at org.apache.http.util.EntityUtils.toString(EntityUtils.java:227) at org.apache.http.util.EntityUtils.toString(EntityUtils.java:308) at com.zuhao.uhaozutool.base.CommonHttpClient.getHttpClientResult(CommonHttpClient.java:524) at com.zuhao.uhaozutool.base.CommonHttpClient.doPost(CommonHttpClient.java:390) at com.zuhao.uhaozutool.base.CommonHttpClient.doJsonPost(CommonHttpClient.java:216)Copy the code

A common error is that the client/server is disconnected while the Httpclient is reading the response. Expected: 146,256; Received: 139121).

Solution of flange

Check your code for premature closing of connections, both on the client and the server.

Found in the code, there is no dominant at closing of the connection, but with the PoolingHttpClientConnectionManager unified management.

PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(1, TimeUnit.MINUTES);
cm.setMaxTotal(200);
cm.setDefaultMaxPerRoute(20);

defaultHttpClient = HttpClients.custom()
        .setConnectionManager(cm).build();
Copy the code

So find PoolingHttpClientConnectionManager related configuration. Only three common Settings were found.

  1. new PoolingHttpClientConnectionManager(1, TimeUnit.MINUTES)In the constructor, set the maximum available time for a single connection.
  2. cm.setMaxTotal(200);To set the maximum number of connections in the connection pool.
  3. cm.setDefaultMaxPerRoute(20);To set the maximum number of connections for a host/ domain name.

The server code is just the most basic springboot project, and it is impossible to disconnect. Then I tried a series of parameter Settings, but none of them worked.

Looking back at the log, I noticed something suspicious.

Expected: 146,256; Received: 139,121) and received 139,121. This is ridiculous, how to receive the same size data each time?

So I turned to thinking, is that where I set the maximum response acceptance size? I looked around, but I couldn’t find the configuration.

On second thought, no, httpClient. excute works, only fails with Entityutils. toString. If the request was successfully executed, why would it fail to read? Check the source code to find that the actual read response content in entityutils.tostring. Of course, this is just a small episode.

private static String toString(
        final HttpEntity entity,
        final ContentType contentType) throws IOException {
    final InputStream inStream = entity.getContent();
    if (inStream == null) {
        return null;
    }
    try {
        Args.check(entity.getContentLength() <= Integer.MAX_VALUE,
                "HTTP entity too large to be buffered in memory");
        int capacity = (int)entity.getContentLength();
        if (capacity < 0) {
            capacity = DEFAULT_BUFFER_SIZE;
        }
        Charset charset = null;
        if(contentType ! =null) {
            charset = contentType.getCharset();
            if (charset == null) {
                finalContentType defaultContentType = ContentType.getByMimeType(contentType.getMimeType()); charset = defaultContentType ! =null ? defaultContentType.getCharset() : null; }}if (charset == null) {
            charset = HTTP.DEF_CONTENT_CHARSET;
        }
        final Reader reader = new InputStreamReader(inStream, charset);
        final CharArrayBuffer buffer = new CharArrayBuffer(capacity);
        final char[] tmp = new char[1024];
        int l;
        while((l = reader.read(tmp)) ! = -1) {
            buffer.append(tmp, 0, l);
        }
        return buffer.toString();
    } finally{ inStream.close(); }}Copy the code

Nginx-enabled users do not have write permission to the directory. As a result, only the body of the response size will be returned each time the body exceeds the size of the cache.

I got it, but I was blown away.

Good luck.

Quickly locate the O&M and view the cache configuration of the server domain name.

Quick check each configuration meaning. www.cnblogs.com/wshenjin/p/…

139121/1024 = 128, 128k = 128, 128k = 128, 128k = 128, 128k = 128

Complex bugs often require only simple configuration.

To sum up, this kind of problem solving approach:

  1. Check whether the client closes the connection in advance
  2. Check whether the server timed out due to a long execution time
  3. Check nginx configuration