WEBKT

不同编程语言中 HTTP Keepalive 的使用和优化

8 0 0 0

Node.js 中的 Keepalive

Python 中的 Keepalive

Java 中的 Keepalive

Keepalive 的最佳实践

哥们,今天咱来聊聊 HTTP Keepalive 这个事儿。你平时写代码,发 HTTP 请求的时候,有没有想过,这连接是怎么建立的,又是怎么断开的?

HTTP Keepalive,也叫 HTTP 长连接,HTTP 持久连接。它可不是什么新鲜玩意儿,HTTP/1.1 默认就开启了。简单来说,就是让客户端和服务器之间的 TCP 连接在一次请求/响应之后,先别急着断开,留着下次还能用。这样就省去了反复建立连接的时间,效率自然就提高了。

想想看,你要是每次请求都新建一个连接,那三次握手、四次挥手,一来一回,多浪费时间啊!特别是对于那些频繁请求小资源的场景,Keepalive 简直就是救星。

不过,Keepalive 也不是万能的。连接一直占着,服务器的资源也会被占用。所以,怎么用好 Keepalive,这里面还是有点学问的。

接下来,咱就分别看看,在 Node.js、Python 和 Java 这三种常用的编程语言里,怎么玩转 HTTP Keepalive。

Node.js 中的 Keepalive

Node.js 的 httphttps 模块,默认情况下是开启 Keepalive 的。也就是说,你用 http.get() 或者 https.request() 发请求,如果不特别设置,连接是会被复用的。

但是!Node.js 的默认行为有点坑。它虽然默认开启 Keepalive,但是并没有限制每个主机(host)的最大连接数。这意味着,如果你的程序向同一个主机发送大量的并发请求,可能会导致服务器的连接数爆炸!

所以,在 Node.js 里,咱们最好还是手动创建一个 http.Agent 或者 https.Agent,并设置 keepAlive: truemaxSockets 属性。

const http = require('http');
const agent = new http.Agent({
keepAlive: true,
maxSockets: 10 // 根据实际情况调整
});
const options = {
hostname: 'example.com',
port: 80,
path: '/',
method: 'GET',
agent: agent
};
const req = http.request(options, (res) => {
// ... 处理响应
});
req.end();

这样,咱们就可以控制连接的数量,避免把服务器搞崩了。

另外,Node.js 还提供了 keepAliveMsecs 属性,可以设置 Keepalive 连接的超时时间(毫秒)。如果连接空闲超过这个时间,就会被自动关闭。

Python 中的 Keepalive

Python 里,咱们常用的 HTTP 客户端库,比如 requests,也是默认开启 Keepalive 的。

requests 库的底层,其实是用 urllib3 这个库来处理连接的。urllib3 会自动维护一个连接池,复用 Keepalive 连接。

import requests
session = requests.Session()
response1 = session.get('https://example.com')
response2 = session.get('https://example.com') # 这次请求会复用之前的连接

在上面的代码里,我们创建了一个 requests.Session 对象。同一个 Session 对象发起的多次请求,会尽可能地复用连接。

如果你想更细粒度地控制 Keepalive,可以配置 urllib3PoolManager

import requests
from urllib3.poolmanager import PoolManager
from requests.adapters import HTTPAdapter
manager = PoolManager(maxsize=10, block=True) #maxsize 根据实际情况调整
adapter = HTTPAdapter(pool_connections=10, pool_maxsize=10, pool_block=True) # 根据实际情况调整
session = requests.Session()
session.mount('http://', adapter)
session.mount('https://', adapter)
response = session.get('https://www.example.com')

Java 中的 Keepalive

Java 里,咱们可以用 HttpURLConnection 或者 Apache HttpClient 来发 HTTP 请求。

HttpURLConnection 默认也是开启 Keepalive 的。不过,它的行为也比较迷。在某些情况下,它可能不会复用连接,或者复用的方式不太符合预期。所以有些时候你明明觉得应该复用,但实际上并没有。

如果想更可靠地使用 Keepalive,推荐使用 Apache HttpClient。

import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.HttpResponse;
// 创建连接池管理器
PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager();
cm.setMaxTotal(100); // 设置最大连接数
cm.setDefaultMaxPerRoute(10); // 设置每个主机的最大连接数
// 创建 HttpClient
CloseableHttpClient httpClient = HttpClients.custom()
.setConnectionManager(cm)
.build();
// 发送请求
HttpGet httpGet = new HttpGet("https://www.example.com");
HttpResponse response = httpClient.execute(httpGet);
// ... 处理响应
// 关闭 HttpClient (注意:这并不会立即关闭所有连接,连接池会根据配置来管理连接的生命周期)
// httpClient.close();

在上面的代码里,我们创建了一个 PoolingHttpClientConnectionManager 来管理连接池,并设置了最大连接数和每个主机的最大连接数。

Keepalive 的最佳实践

说了这么多,咱们来总结一下 Keepalive 的最佳实践:

  1. 了解你的 HTTP 客户端:不同的编程语言,不同的 HTTP 客户端库,对 Keepalive 的支持和默认行为可能都不一样。所以,一定要仔细阅读文档,了解你用的客户端是怎么处理 Keepalive 的。
  2. 控制连接数量:不管是 Node.js、Python 还是 Java,都要注意控制连接的数量,避免创建过多的连接,把服务器搞崩。通常的做法是,设置一个连接池,限制最大连接数和每个主机的最大连接数。
  3. 设置合理的超时时间:Keepalive 连接不能一直占着,要设置一个合理的超时时间。如果连接空闲超过这个时间,就把它关掉。超时时间太长会浪费服务器的资源,太短又会导致连接频繁地建立和关闭。这需要你根据实际情况来调整。
  4. 监控连接状态:定期监控你的程序的连接状态,看看有多少个连接是活跃的,有多少个是空闲的,有多少个是 Keepalive 的。这样可以帮助你发现问题,及时调整配置。
  5. 服务端也要配置: 客户端开启了keepalive, 服务端也要进行相应的配置才能实现真正的长连接,例如nginx, apache等。不同的web服务器的配置方法不同。
  6. 短连接也可能很有用:某些情况下,比如你知道接下来的请求不会复用连接,那么主动关闭连接也是一个好的选择。避免浪费资源。

HTTP Keepalive 是一个很有用的技术,用好了可以显著提高程序的性能。但是,它也不是银弹,需要你根据实际情况来配置和优化。希望今天这番唠叨,能让你对 Keepalive 有更深入的理解。下次你再写代码的时候,记得想想 Keepalive,别让你的程序输在起跑线上!

哎,对了,你平时用什么编程语言比较多?有没有遇到过 Keepalive 相关的问题?欢迎来一起交流交流!

赛博老铁 HTTPKeepalive性能优化

评论点评

打赏赞助
sponsor

感谢您的支持让我们更好的前行

分享

QRcode

https://www.webkt.com/article/8514