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应该设置多长?怎么能很好的清除无效的连接?

        

       

  • 相关阅读:
    基于express框架的Token实现方案
    书籍整理
    openfire4.0.2开发环境搭建(windows)
    Express4.x动态的销毁或者替换中间件(app.unuse)
    mysql学习笔记(三)----函数
    mysql学习笔记(二)----数据类型
    mysql学习笔记(一)----建表操作
    Windows-mysql5.7安装
    JavaScript学习笔记–(new关键字)
    n枚硬币问题(找假币)
  • 原文地址:https://www.cnblogs.com/YDDMAX/p/5361957.html
Copyright © 2011-2022 走看看