有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!


共 (2) 个答案

  1. # 1 楼答案

    连接超时: 这是与服务器建立连接之前的超时

    套接字超时: 这是等待数据包[数据]接收的非活动时间

    setConnectionRequestTimeout:

    但是,它是特定于配置连接管理器的。现在是从连接池获取连接的时间

    它返回从连接管理器请求连接时使用的超时(以毫秒为单位)。表示无限(0)超时

    setConnectionTimeToLive

    public final HttpClientBuilder setConnectionTimeToLive(long connTimeToLive, TimeUnit connTimeToLiveTimeUnit)

    Sets maximum time to live for persistent connections

    Please note this value can be overridden by the setConnectionManager(org.apache.http.conn.HttpClientConnectionManager) method.

    Since: 4.4

    示例:HttpClientStarter。爪哇

    @Override
    public boolean start() {
    
        RegistryBuilder<ConnectionSocketFactory> r = RegistryBuilder.<ConnectionSocketFactory> create();
    
        // Register http and his plain socket factory
        final SocketFactory ss = getLevel().find(SocketFactory.class);
        ConnectionSocketFactory plainsf = new PlainConnectionSocketFactory() {
            @Override
            public Socket createSocket(HttpContext context) throws IOException {
                return ss.createSocket();
            }
        };
        r.register("http", plainsf);
    
        // Register https
        ConnectionSocketFactory sslfactory = getSSLSocketFactory();
        if (sslfactory != null) {
            r.register("https", getSSLSocketFactory());
        } else {
            log(Level.WARN, "ssl factory not found, won't manage https");
        }
    
        HttpClientBuilder builder = HttpClientBuilder.create();
        builder.setUserAgent(USERAGENT);
        builder.setConnectionTimeToLive(timeout, TimeUnit.SECONDS);
        builder.evictIdleConnections((long) timeout, TimeUnit.SECONDS);
    
        PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(r.build());
        cm.setMaxTotal(maxConnect * 2);
        cm.setDefaultMaxPerRoute(2);
        cm.setValidateAfterInactivity(timeout * 1000);
        builder.setConnectionManager(cm);
    
        RequestConfig rc = RequestConfig.custom()
                .setConnectionRequestTimeout(timeout * 1000)
                .setConnectTimeout(timeout * 1000)
                .setSocketTimeout(timeout * 1000)
                .build();
        builder.setDefaultRequestConfig(rc);
    
        client = builder.build();
    
        return true;
    }
    

    资源链接:

    1. HttpClientStarter.java

    2. HttpClient 4.x Timeout

    HTTP规范不确定持续连接可以或应该保持活动状态的时间。一些HTTP服务器使用非标准头Keep-Alive告诉客户端他们希望在服务器端保持连接的秒数。如果此信息可用,HttClient将利用此功能。如果响应中不存在保持活动状态的标头信息,HttpClient将假定连接无限期保持活动状态。但是,许多真实世界的HTTP服务器被配置为在特定的非活动期后丢弃持久连接,以节省系统资源,通常不通知客户端

    这里你可以重写一个,这里设置为5秒

    ConnectionKeepAliveStrategy keepAliveStrategy = new DefaultConnectionKeepAliveStrategy() {
                @Override
                public long getKeepAliveDuration(final HttpResponse response, final HttpContext context) {
                    long keepAlive = super.getKeepAliveDuration(response, context);
                    if (keepAlive == -1) {
                        keepAlive = 5000;
                    }
                    return keepAlive;
                }
            };
    

    连接逐出策略

    The main disadvantage of a classic blocking I/O model is that network sockets respond to I/O events only when I/O operations are blocked. When a connection is released back to the manager, it can be kept alive without monitoring the status of the socket and responding to any I/O events. If the connection is closed on the server side, then the client connection can not detect changes in the connection status and shut down the local socket to respond properly.

    HttpClient试图通过测试连接是否过期来缓解此问题,该连接不再有效,因为在使用发出HTTP请求的连接之前,它已在服务器端关闭。过时的连接检查不是100%稳定的,而是每个请求执行需要10到30毫秒。由于每个线程的非活动性都被认为是可用的,所以监视套接字模型的每个线程的非活动性都被认为是不可用的,因为该线程的非活动性并不是只用于回收已过期的连接。监视线程可以定期调用ClientConnectionManager#closeExpiredConnections()方法来关闭所有过期的连接,从连接池中退出已关闭的连接。它还可以选择调用ClientConnectionManager#closeIdleConnections()方法来关闭所有空闲超过给定时间段的连接

    资源链接:

    http://dev.dafan.info/detail/513285

  2. # 2 楼答案

    AConnectTimeout确定在创建新连接时等待对方回答“是的,我在这里,让我们谈谈”的最长时间(ConnectTimeout最终调用socket.connect(address, timeout)。等待时间通常不到一秒钟,除非对方真的忙于接受新的传入连接,或者你必须通过中国的防火墙。在后一种情况下,可能需要一分钟(或更长时间)才能创建新连接。如果未在ConnectTimeout内建立连接,则会出现错误(1)

    setSocketTimeout最终调用^{},这在this answer中进行了解释

    ConnectionTimeToLive确定连接的最长使用期限(之后将关闭),而不管上次使用连接的时间是什么时候。通常,清理连接时会有一个“空闲超时”,即您或另一方将关闭一段时间未使用的连接。通常,您将在另一端关闭空闲连接之前关闭该连接,以防止出现错误。但我能想到的另外两种情况是,连接的最大年龄是有用的:

    • 糟糕的网络组件:如果你没有遇到它们,那你就算幸运了。一些坏的路由器、防火墙、代理等会在大约30分钟后中断(正在使用)连接。由于您和另一方甚至可能没有意识到连接已断开,因此在奇怪的时候,您可能会在没有明显原因的情况下出现“连接重置”错误
    • 缓存元数据:大多数系统在某种缓存中保留一些关于连接的元数据。有些系统对缓存的管理很糟糕——缓存大小只是随着连接的使用年限而增长

    关于ApacheHttpClient 4.5.4中的ConnectionTimeToLive实现的一个注意事项:我认为必须使用^{}选项才能工作(最终都归结为对this ^{}方法的调用)。如果您不使用此连接管理器,请测试该选项以确保它真正起作用

    (1)来自this related answerEJPuser207421的有趣评论