zoukankan      html  css  js  c++  java
  • HttpClient

    1、每个连接任何时刻只能由一个线程在进行操作

    2、一般使用PoolingHttpClientConnectionManager 来管理连接池,默认每个route只创建两个connection,而且最大是20个连接,但是实际情况并不是。

         连接池管理器为我们管理了connection的创建和回收,生命周期的管理,connection的分配等。

    3、HttpClient是线程安全的

    4、HttpClient的定制化程度很高,可以写各种本地化代码。

    5、connection什么时候无效?keep-alive应该保持多长时间?

    5、无用连接的清除(服务端挂掉之后,客户端可能无法感知)

         此时最好的办法就是有一个监控线程不断的去清除连接池里面的无效连接

         If the connection gets closed on the server side, the client side connection is unable to detect the change in the connection state (and react appropriately by closing the socket on its end).

    The only feasible solution that does not involve a one thread per socket model for idle connections is a dedicated monitor thread used to evict connections that are considered expired due to a long period of inactivity. The monitor thread can periodically call ClientConnectionManager#closeExpiredConnections() method to close all expired connections and evict closed connections from the pool. It can also optionally call ClientConnectionManager#closeIdleConnections() method to close all connections that have been idle over a given period of time.

    public static class IdleConnectionMonitorThread extends Thread {
        
        private final HttpClientConnectionManager connMgr;
        private volatile boolean shutdown;
        
        public IdleConnectionMonitorThread(HttpClientConnectionManager connMgr) {
            super();
            this.connMgr = connMgr;
        }
    
        @Override
        public void run() {
            try {
                while (!shutdown) {
                    synchronized (this) {
                        wait(5000);
                        // Close expired connections
                        connMgr.closeExpiredConnections();
                        // Optionally, close connections
                        // that have been idle longer than 30 sec
                        connMgr.closeIdleConnections(30, TimeUnit.SECONDS);
                    }
                }
            } catch (InterruptedException ex) {
                // terminate
            }
        }
        
        public void shutdown() {
            shutdown = true;
            synchronized (this) {
                notifyAll();
            }
        }
        
    }

    6、keep-alive的时间

      如果服务端的响应头有keep-alive头时,客户端将响应头的keep-alive设置为保持连接的时间。如果响应没有该字段,则默认keep-alive是无限的。

          The HTTP specification does not specify how long a persistent connection may be and should be kept alive. Some HTTP servers use a non-standard Keep-Alive header to communicate to the client the period of time in seconds they intend to keep the connection alive on the server side. HttpClient makes use of this information if available. If the Keep-Alive header is not present in the response, HttpClient assumes the connection can be kept alive indefinitely. However, many HTTP servers in general use are configured to drop persistent connections after a certain period of inactivity in order to conserve system resources, quite often without informing the client. In case the default strategy turns out to be too optimistic, one may want to provide a custom keep-alive strategy.

    keep-alive时间是可以设置的:

    ConnectionKeepAliveStrategy myStrategy = new ConnectionKeepAliveStrategy() {
    
        public long getKeepAliveDuration(HttpResponse response, HttpContext context) {
            // Honor 'keep-alive' header
            HeaderElementIterator it = new BasicHeaderElementIterator(
                    response.headerIterator(HTTP.CONN_KEEP_ALIVE));
            while (it.hasNext()) {
                HeaderElement he = it.nextElement();
                String param = he.getName();
                String value = he.getValue();
                if (value != null && param.equalsIgnoreCase("timeout")) {
                    try {
                        return Long.parseLong(value) * 1000;
                    } catch(NumberFormatException ignore) {
                    }
                }
            }
            HttpHost target = (HttpHost) context.getAttribute(
                    HttpClientContext.HTTP_TARGET_HOST);
            if ("www.naughty-server.com".equalsIgnoreCase(target.getHostName())) {
                // Keep alive for 5 seconds only
                return 5 * 1000;
            } else {
                // otherwise keep alive for 30 seconds
                return 30 * 1000;
            }
        }
    
    };
    CloseableHttpClient client = HttpClients.custom()
            .setKeepAliveStrategy(myStrategy)
            .build();

     7、思考这个问题:connection的keep-alive应该设置多长?怎么能很好的清除无效的连接?

        

       

  • 相关阅读:
    Windows 和Linux 误删除后的恢复
    AWS 使用总结
    20180814 错误分析
    你必须知道的互联网协议详解
    linux常用命令和关闭防火墙
    Nginx之ngx_http_fastcgi_module模块详解
    nginx 限制ip
    nginx allow 多个ip & ipv4的网段表示方法解析
    从Nginx的Web请求处理机制中剖析多进程、多线程、异步IO
    剑指offer:二叉树的深度
  • 原文地址:https://www.cnblogs.com/YDDMAX/p/5361957.html
Copyright © 2011-2022 走看看