栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > .Net

Websocket系列 -- Http Keep-Alive实现之sun.net.www.protocol.http.HttpURLConnection

.Net 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Websocket系列 -- Http Keep-Alive实现之sun.net.www.protocol.http.HttpURLConnection

系列文章目录

Websocket系列 --前世今生

Websocket系列 – 协议详解


前言

此文以Java中sun.net.www.protocol.http.HttpURLConnection为例,描述Http Keep-Alive的具体实现方式。
环境:

  • Java11
  • springboot2 + undertow

HttpURLConnection类图+Http链接建立流程

在Websocket系列 --前世今生 中已经描述了Http的Keep-Alive,实际上就是利用了TCP的keep-alive机制,在http建立链接时,尽量利用已经建立好的TCP链接,这里需要强调一下,TCP链接的保活机制是由操作系统(网络分层结构的TCP层)完成的,应用(例如Java应用)只需要设置对应的Keep-Alive参数(例如:keepAliveTimeout和keepAliveConnections)即可。
下图以sun.net.www.protocol.http.HttpURLConnection为例,列出类图和对应的Http链接建立流程。
* 第一步,创建HttpURLConnection连接,上代码:

// url为String类型的url地址,此处只支持HTTP,如果要支持HTTPS,参见sun.net.www.protocol.https.HttpsURLConnectionImpl,此类继承自javax.net.ssl.HttpsURLConnection
URL url = new URL(uri);
// 此处如果需要支持HTTPS,只需把HttpURLConnection类型,换为HttpsURLConnection即可
HttpURLConnection httpConn = (HttpURLConnection) url.openConnection();

  • 第二步,创建或重用已有HttpClient
    上代码(sun.net.www.http.HttpClient):
    1, 创建HttpClient的逻辑
public static HttpClient New(URL url, Proxy p, int to, boolean useCache, HttpURLConnection httpuc) throws IOException
{
	........
 	HttpClient ret = null;
 
 if (useCache) {
 		// 从KeepAliveCache读取,Key是URL类
     ret = kac.get(url, null);
     ......
  }
  ......
}

2, HttpClent使用结束后,将其放入KeepAliveCache中


    public void finished() {
        if (reuse) 
            return;
        keepAliveConnections--;
        poster = null;
        if (keepAliveConnections > 0 && isKeepingAlive() &&
               !(serverOutput.checkError())) {
            
            putInKeepAliveCache();
        } else {
            closeServer();
        }
    }
  • Response Header设置
    默认HttpURLConnection的Keep-Alive时间为5秒,参见下述代码
// 此代码来自sun.net.www.http.HttpClient.parseHTTPHeader方法
HeaderParser p = new HeaderParser(responses.findValue("Keep-Alive"));

keepAliveConnections = p.findInt("max", usingProxy?50:5);
keepAliveTimeout = p.findInt("timeout", usingProxy?60:5);

所以,如果想控制HttpClient(或HttpsClient)的链接保活时长,需要依赖于服务响应头的属性(Keep-Alive)设置。以Undertow为例:

factory.addDeploymentInfoCustomizers(deploymentInfo -> {
	deploymentInfo.addInitialHandlerChainWrapper(handler -> {
		// 在响应头中,添加:Keep-Alive: timeout=60
		// 时间单位为秒,同时也可以再添加max属性,设置最大保活个数
		// 具体协议定义,参见https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Keep-Alive
  	return new SetHeaderHandler(handler, "Keep-Alive", "timeout=60");
  });
});

总结

sun.net.www.protocol.http.HttpURLConnection(或sun.net.www.protocol.https.HttpsURLConnectionImpl)依赖于服务端响应头中属性的设置,考虑到nginx等代理可能重置一些响应头的属性,所以HttpURLConnection保活机制的可配置性并不能得到保证。后续会介绍一下okhttp3的Keep-Alive的实现方式。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/983856.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号