Maison >Opération et maintenance >Nginx >Comment configurer HTTP keepalive dans Nginx

Comment configurer HTTP keepalive dans Nginx

WBOY
WBOYavant
2023-05-12 11:28:131004parcourir

http keepalive
Au début de http, chaque requête http nécessitait l'ouverture d'une connexion socket tpc, et la connexion tcp était déconnectée après une utilisation. L'utilisation de keep-alive peut améliorer cette situation, c'est-à-dire que plusieurs copies de données peuvent être envoyées en continu dans une connexion TCP sans se déconnecter. En utilisant le mécanisme keep-alive, le nombre de temps d'établissement de connexion TCP peut être réduit, ce qui signifie également que la connexion à l'état time_wait peut être réduite, améliorant ainsi les performances et augmentant le débit du serveur httpd (moins de connexions TCP signifie moins de connexions système). appels du noyau, appels socket accept() et close()). Cependant, le maintien en vie n'est pas une gratuité. Les connexions TCP à long terme peuvent facilement conduire à une utilisation non valide des ressources système. Des keep-alives mal configurés peuvent parfois entraîner des pertes plus importantes que la réutilisation des connexions. Par conséquent, il est très important de définir correctement le délai de conservation.
keepalvie timeout
httpd le démon fournit généralement des paramètres de réglage du délai d'expiration de conservation. Par exemple, keepalive_timeout de nginx et keepalivetimeout d'Apache. Cette valeur de temps keepalive_timout signifie qu'après qu'une connexion TCP générée par http ait transmis la dernière réponse, elle doit conserver keepalive_timeout quelques secondes avant de commencer à fermer la connexion. Une fois que le démon httpd a envoyé une réponse, il doit immédiatement fermer activement la connexion TCP correspondante. Après avoir défini keepalive_timeout, le démon httpd voudra dire : "Attendez encore un peu et voyez si le navigateur a fait une autre requête, ce qui attend." est le temps keepalive_timeout. Si le processus démon ne reçoit pas de requête http du navigateur pendant ce temps d'attente, la connexion http sera fermée.
J'ai écrit un script pour faciliter les tests

<?php
sleep(60); //为了便于分析测试,会根据测试进行调整
echo "www.jb51.net";
?>

1 Lorsque le temps keepalive_timeout est 0, c'est-à-dire lorsque keep-alive n'est pas activé, le cycle de vie d'une connexion TCP#🎜🎜. ##🎜 🎜#

#tcpdump -n host 218.1.57.236 and port 80
rrree
Les lignes 1 à 3 établissent une poignée de main TCP à trois voies et établissent une connexion. Il faut 8898μs

Les lignes 4 à 5 envoient la première requête http via la connexion établie, et le serveur confirme la réception de la requête. Temps 5μs

Lignes 5~6, vous pouvez savoir que le temps d'exécution du script est de 60s1387μs, ce qui est cohérent avec le script PHP.
Le serveur envoie une réponse http aux lignes 6 et 8. Il a fallu 90 166 μs pour envoyer la réponse.
La ligne 7 indique que le démon du serveur ferme activement la connexion. Combiné avec les lignes 6 et 8, cela montre qu'une fois la réponse http envoyée, le serveur ferme immédiatement la connexion TCP
Les lignes 7, 9 et 10 montrent que la connexion TCP est fermée séquentiellement, prenant 90963μs. Il convient de noter que la ressource socket ici n'est pas libérée immédiatement. Elle doit attendre 2 msl (60 s) avant d'être réellement libérée.
On peut voir que lorsque keepalive_timeout n'est pas défini, le temps nécessaire pour qu'une ressource socket soit créée et libérée est : établissement d'une connexion TCP + transmission de la requête http + exécution du script php + transmission de la réponse http + fermeture de la connexion TCP + 2 ml. (Remarque : l'heure ici ne peut être utilisée qu'à titre de référence. L'heure spécifique est principalement déterminée par la bande passante du réseau et la taille de la réponse)
2 Lorsque le temps keepalive_timeout est supérieur à 0, c'est-à-dire lorsque le keep-alive est. activé, la durée de vie d'un cycle de connexion TCP. Afin de faciliter l'analyse, nous définissons keepalive_timeout sur 300s

20:36:50.792731 ip 218.1.57.236.43052 > 222.73.211.215.http: s 1520902589:1520902589(0) win 65535
20:36:50.792798 ip 222.73.211.215.http > 218.1.57.236.43052: s 290378256:290378256(0) ack 1520902590 win 5840
20:36:50.801629 ip 218.1.57.236.43052 > 222.73.211.215.http: . ack 1 win 3276820:36:50.801838 ip 218.1.57.236.43052 > 222.73.211.215.http: p 1:797(796) ack 1 win 32768
20:36:50.801843 ip 222.73.211.215.http > 218.1.57.236.43052: . ack 797 win 5920:37:50.803230 ip 222.73.211.215.http > 218.1.57.236.43052: p 1:287(286) ack 797 win 59
20:37:50.803289 ip 222.73.211.215.http > 218.1.57.236.43052: f 287:287(0) ack 797 win 59
20:37:50.893396 ip 218.1.57.236.43052 > 222.73.211.215.http: . ack 288 win 32625
20:37:50.894249 ip 218.1.57.236.43052 > 222.73.211.215.http: f 797:797(0) ack 288 win 32625
20:37:50.894252 ip 222.73.211.215.http > 218.1.57.236.43052: . ack 798 win 59
rrree
Jetons d'abord un coup d'œil aux lignes 6 à 8. La différence avec le dernier exemple est que le démon httpd côté serveur a. envoi terminé Après la réponse, la connexion TCP n'a pas été activement fermée immédiatement.

Ligne 8, combinée avec la ligne 6, on peut voir qu'au bout de 5 minutes (300s), le serveur ferme activement la connexion TCP. Cette heure est exactement l’heure à laquelle nous avons défini keepalive_timeout.

On constate que lorsque le temps keepalive_timout est défini, le temps nécessaire entre l'établissement d'un socket et sa libération est plus long que le temps keepalive_timeout.
3. Lorsque le délai keepalive_timeout est supérieur à 0 et que plusieurs réponses http sont envoyées sur la même connexion TCP. Pour faciliter l'analyse ici, nous définissons keepalive_timeout sur 180s
Grâce à ce test, nous voulons déterminer si keepalive_timeout commence le chronométrage à partir de la fin de la première réponse ou commence le chronométrage à partir de la fin de la dernière réponse. Les résultats du test ont confirmé qu'il s'agit de cette dernière solution. Ici, nous avons envoyé une requête toutes les 120 secondes et envoyé 3 requêtes via une connexion TCP.

# tcpdump -n host 218.1.57.236 and port 80
22:43:57.102448 ip 218.1.57.236.49955 > 222.73.211.215.http: s 4009392741:4009392741(0) win 65535
22:43:57.102527 ip 222.73.211.215.http > 218.1.57.236.49955: s 4036426778:4036426778(0) ack 4009392742 win 5840
22:43:57.111337 ip 218.1.57.236.49955 > 222.73.211.215.http: . ack 1 win 3276822:43:57.111522 ip 218.1.57.236.49955 > 222.73.211.215.http: p 1:797(796) ack 1 win 32768
22:43:57.111530 ip 222.73.211.215.http > 218.1.57.236.49955: . ack 797 win 59
22:43:59.114663 ip 222.73.211.215.http > 218.1.57.236.49955: p 1:326(325) ack 797 win 59
22:43:59.350143 ip 218.1.57.236.49955 > 222.73.211.215.http: . ack 326 win 3260522:45:59.226102 ip 218.1.57.236.49955 > 222.73.211.215.http: p 1593:2389(796) ack 650 win 32443
22:45:59.226109 ip 222.73.211.215.http > 218.1.57.236.49955: . ack 2389 win 83
22:46:01.227187 ip 222.73.211.215.http > 218.1.57.236.49955: p 650:974(324) ack 2389 win 83
22:46:01.450364 ip 218.1.57.236.49955 > 222.73.211.215.http: . ack 974 win 3228122:47:57.377707 ip 218.1.57.236.49955 > 222.73.211.215.http: p 3185:3981(796) ack 1298 win 32119
22:47:57.377714 ip 222.73.211.215.http > 218.1.57.236.49955: . ack 3981 win 108
22:47:59.379496 ip 222.73.211.215.http > 218.1.57.236.49955: p 1298:1622(324) ack 3981 win 108
22:47:59.628964 ip 218.1.57.236.49955 > 222.73.211.215.http: . ack 1622 win 3276822:50:59.358537 ip 222.73.211.215.http > 218.1.57.236.49955: f 1622:1622(0) ack 3981 win 108
22:50:59.367911 ip 218.1.57.236.49955 > 222.73.211.215.http: . ack 1623 win 32768
22:50:59.686527 ip 218.1.57.236.49955 > 222.73.211.215.http: f 3981:3981(0) ack 1623 win 32768
22:50:59.686531 ip 222.73.211.215.http > 218.1.57.236.49955: . ack 3982 win 108

第一组,三个ip包表示tcp三次握手建立连接,由浏览器建立。
第二组,发送第一次http请求并且得到响应,服务端守护进程输出响应之后,并没马上主动关闭tcp连接。而是启动keepalive_timout计时。
第三组,2分钟后,发送第二次http请求并且得到响应,同样服务端守护进程也没有马上主动关闭tcp连接,重新启动keepalive_timout计时。
第四组,又2分钟后,发送了第三次http请求并且得到响应。服务器守护进程依然没有主动关地闭tcp连接(距第一次http响应有4分钟了,大于keepalive_timeout值),而是重新启动了keepalive_timout计时。
第五组,跟最后一个响应keepalive_timeout(180s)内,守护进程再没有收到请求。计时结束,服务端守护进程主动关闭连接。4次挥手后,服务端进入time_wait状态。
这说明,当设定了keepalive_timeout,一个socket由建立到释放,需要时间是:tcp建立 + (最后一个响应时间 – 第一个请求时间) + tcp关闭 + 2msl。红色加粗表示每一次请求发送时间、每一次请求脚本执行时间、每一次响应发送时间,还有两两请求相隔时间。进一步测试,正在关闭或者 time_wait状态的tcp连接,不能传输http请求和响应。即,当一个连接结束keepalive_timeout计时,服务端守护进程发送第一 个fin标志ip包后,该连接不能再使用了。
http keep-alive与tcp keep-alive
http keep-alive与tcp keep-alive,不是同一回事,意图不一样。http keep-alive是为了让tcp活得更久一点,以便在同一个连接上传送多个http,提高socket的效率。而tcp keep-alive是tcp的一种检测tcp连接状况的保鲜机制。tcp keep-alive保鲜定时器,支持三个系统内核配置参数:

echo 1800 > /proc/sys/net/ipv4/tcp_keepalive_time
echo 15 > /proc/sys/net/ipv4/tcp_keepalive_intvl
echo 5 > /proc/sys/net/ipv4/tcp_keepalive_probes

keepalive是tcp保鲜定时器,当网络两端建立了tcp连接之后,闲置idle(双方没有任何数据流发送往来)了 tcp_keepalive_time后,服务器内核就会尝试向客户端发 送侦测包,来判断tcp连接状况(有可能客户端崩溃、强制关闭了应用、主机不可达等等)。如果没有收到对方的回答(ack包),则会在 tcp_keepalive_intvl后再次尝试发送侦测包,直到收到对对方的ack,如果一直没有收到对方的ack,一共会尝试 tcp_keepalive_probes次,每次的间隔时间在这里分别是15s, 30s, 45s, 60s, 75s。如果尝试tcp_keepalive_probes,依然没有收到对方的ack包,则会丢弃该tcp连接。tcp连接默认闲置时间是2小时,一般 设置为30分钟足够了。也就是说,仅当nginx的keepalive_timeout值设置高于tcp_keepalive_time,并且距此tcp连接传输的最后一 个http响应,经过了tcp_keepalive_time时间之后,操作系统才会发送侦测包来决定是否要丢弃这个tcp连接。一般不会出现这种情况, 除非你需要这样做。
keep-alive与time_wait
使用http keep-alvie,可以减少服务端time_wait数量(因为由服务端httpd守护进程主动关闭连接)。道理很简单,相较而言,启用keep-alive,建立的tcp连接更少了,自然要被关闭的tcp连接也相应更少了。

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer