• HttpClient 之 CLOSE_WAIT


    Using HttpClient Properly to Avoid CLOSE_WAIT TCP Connections

    Apache HttpClient is usually used like this in basic mode:

    HttpClient httpClient = new HttpClient();
    HttpMethod method = new GetMethod(uri);
    try {
    int statusCode = httpClient.executeMethod(method);
    byte[] responseBody = method.getResponseBody();
    // ...
    return stuff;
    } finally {
    method.releaseConnection();
    }
    

    But this is not enough.

    The issue is this: releasing the connection makes it available again to the HttpClient instance, but does not close it, because HTTP 1.1 is used and it can pipeline further requests to the same host:port in the same connection.

    Even though the server may have decided to close its end of the connection, the connection is still open on our client side and it will stay that way until an attempt to read from it is made (at which point the client will detect that the other end is closed). TCP works like that, there is the notion of a half-closed connection because close() actually just means I will not send any more data, but you can still receive data from a connection that you closed but that has not yet been closed on the other end.

    What happens next is that when the HttpClient instance goes out of scope, it becomes available to the GC, but it will not be garbage collected immediately. Until the GC collects it, the socket connection held internally will stay open and the socket will be stuck in the CLOSE_WAIT state.

    To fix this, the simplest way is to add: method.setRequestHeader("Connection", "close"); before executing the method. This will instruct HttpClient to close the connection by itself once the full response has been received.

    Another way is to do it in the finally block:

    httpClient.getHttpConnectionManager().closeIdleConnections(0);

    An even better way is to not use a new HttpClient object each time, but to reuse one that has been initialized with a MultiThreadedHttpConnectionManager sized appropriately.

    Of course in this case the connection manager must be shut down properly when the application shuts down:

    private MultiThreadedHttpConnectionManager connectionManager;
    private HttpClient httpClient;
    
    public void init() {
    connectionManager = new MultiThreadedHttpConnectionManager()
    // ... configure connectionManager ...
    httpClient = new HttpClient(connectionManager);
    }
    
    public void shutdown() {
    connectionManager.shutdown();
    }
    
    public String process(String uri) {
    HttpMethod method = new GetMethod(uri);
    try {
    int statusCode = httpClient.executeMethod(method);
    byte[] responseBody = method.getResponseBody();
    // ...
    return stuff;
    } finally {
    method.releaseConnection();
    }
    }
  • 相关阅读:
    用GDB调试程序(一)
    Linux编程基础——GDB(设置断点)
    滴滴快车奖励政策,高峰奖励,翻倍奖励,按成交率,指派单数分级(10月12日~10月18日)
    北京Uber优步司机奖励政策(10月19日~10月25日)
    借贷宝人脸识别无需绑卡,需合作者共同冲刺
    王璐首次详解借贷宝诞生历程 直面创业从0到1
    创造信用收入 借贷宝颠覆创新普惠金融
    php中,如何将编译后的代码,反编译回去。
    chrome调试ajax
    提示text还能输入多少字节
  • 原文地址:https://www.cnblogs.com/panpanwelcome/p/12144858.html
Copyright © 2020-2023  润新知