Nginx的Keepalive的简单学习

nginx,keepalive,简单,学习 · 浏览次数 : 908

小编点评

**摘要** 本文介绍了长连接和Websocket的配置,以及如何设置keepalive时间等参数。 **长连接** 长连接是一种用于保持多个TCP连接的连接,即使没有任何数据传输,也保持连接的持续时间。 **Websocket** Websocket是一种用于双方向数据传输的通信技术,可以与长连接类似,但具有更高的效率和可靠性。 **keepalive参数** keepalive参数用于设置长连接的 keepalive时间,该参数指定在保持连接期间,服务器向客户端发送探测报文的时间长度。默认值是1小时。 **结论** 了解长连接和Websocket的配置,以及如何设置keepalive参数对于优化网站性能至关重要。

正文

摘要

最近发现某项目的Nginx负载服务器上面有很多Time_wait的TCP连接
可以使用命令
netstat -n |awk '/^tcp/ {++S[$NF]} END{for (a in S) print a , S[a]}'

当时反馈过来 time_wait的连接特别多. 
我比较菜, 没有进行过特别深入的研究. 
本来今天准备学习研究systemtap的. 
但是想能不能帮一下在乐不思蜀现场的栋哥就先看看这一块内容. 

结论可能不准确, 需要有实际压测进行支撑. 

关于长连接

keepalive 
长连接其实有两种 
第一种是TCP层的长连接, 第二种是http的长连接.
HTTP 的 Keep-Alive 也叫 HTTP 长连接,
该功能是由「应用程序」实现的,
可以使得用同一个 TCP 连接来发送和接收多个 HTTP 请求/应答,
减少了 HTTP 短连接带来的多次 TCP 连接建立和释放的开销。

TCP 的 Keepalive 也叫 TCP 保活机制,
该功能是由「内核」实现的,
当客户端和服务端长达一定时间没有进行数据交互时,
内核为了确保该连接是否还有效,就会发送探测报文,
来检测对方是否还在线,然后来决定是否要关闭该连接。
Study From :https://blog.csdn.net/ThinPikachu/article/details/128177194

Http 长连接的配置

Http 1.1 之后自动开启了长连接, 会在http头上面增加一个配置节:
Connection: Keep-Alive
一般默认的超时时间是 60s 是需要应用层来进行维护.
一般可以采用 keepalive_timeout的参数进行修改. 

注意虽然Http的长连接可以避免 建立连接时的资源损耗.
但是如果客户并发量特别高, 并且大部分人用完就不在处理了. 
应用服务器保留很多长连接会导致多余的性能开销. 
这一块时间还是需要有一定的业务含义, 不建议太过随意的处理. 

Tcp长连接

如果两端的 TCP 连接一直没有数据交互,
达到了触发 TCP 保活机制的条件,那么内核里的 TCP 协议栈就会发送探测报文。

1. 如果对端程序是正常工作的。当 TCP 保活的探测报文发送给对端, 
   对端会正常响应,这样 TCP 保活时间会被重置,等待下一个 TCP 保活时间的到来。
2. 如果对端主机崩溃,或对端由于其他原因导致报文不可达。
   当 TCP 保活的探测报文发送给对端后,石沉大海,没有响应,连续几次,
   达到保活探测次数后,TCP 会报告该 TCP 连接已经死亡。

注意TCP的保活机制是内核来提供的.他也有一些缺点:
因为TCP协议中的SO_KEEPALIVE有几个致命的缺陷:
1. keepalive只能检测连接是否存活,不能检测连接是否可用。
   比如服务器因为负载过高导致无法响应请求但是连接仍然存在,
   此时keepalive无法判断连接是否可用
2. 如果TCP连接中的另一方因为停电突然断网,我们并不知道连接断开,
   此时发送数据失败会进行重传,由于重传包的优先级要高于keepalive的数据包,
   因此keepalive的数据包无法发送出去。只有在长时间的重传失败之后我们才能判断此连接断开了。
Study From :https://www.zhihu.com/question/40602902/answer/209148428

注意长连接与Websocket的区别

websocket 实现的是 应用段端推送数据
长连接是websocket的实现基础. 
但是websocket有更广阔的用途.

proxy_pass模块的长连接.

官方文档里面有对应的描述:
http://nginx.org/en/docs/http/ngx_http_upstream_module.html

可以在upstream 模块里面添加keepalive的数量.
需要注意的是这个数量仅是定义idle的进程数量,而不是max的数量.
所以基本上没有特别大的风险. 
但是需要注意的是如果在upstream里面定义了 keepalive 需要在proxy_pass中增加定义配置.
第一个是 proxy_http_version  1.1 ; 第二个是 proxy_set_header Connection "" ;
因为proxy_pass 的默认 http version是1.0 需要增加配置节.

upstream http_backend {
    server 127.0.0.1:8080;

    keepalive 16;
}

server {
    ...

    location /http/ {
        proxy_pass http://http_backend;
        proxy_http_version 1.1;
        proxy_set_header Connection "";
        ...
    }
}

Proxy_pass 对应的时间和超时时间

第一个是keepavlie的默认时间
默认是一个小时. 

Syntax:	keepalive_time time;
Default:	
keepalive_time 1h;
Context:	upstream
This directive appeared in version 1.19.10.
Limits the maximum time during which requests can be processed through one keepalive connection. 
After this time is reached, the connection is closed following the subsequent request processing.

第二个是空闲的keepalive的默认超时时间.
默认是60秒, 我理解超过了 keepalive的数量时就利用他来进行关闭idle进程.
Syntax:	keepalive_timeout timeout;
Default:	
keepalive_timeout 60s;
Context:	upstream
This directive appeared in version 1.15.3.
Sets a timeout during which an idle keepalive connection to an upstream server will stay open.

Nginx的其他超时时间设置

http 下面的
#每个 TCP 连接最多可以保持多长时间
keepalive_timeout  60;
#客户端向服务端发送一个完整的 request header
client_header_timeout 10;
#客户端发送服务端发送一个完整的 request bod
client_body_timeout 20;
#服务端向客户端传输数据的超时时间。
send_timeout 30;

location下面的
proxy_connect_timeout 4;
# 没有接收数据关闭    等候后端服务器响应时间 这个可以响应的时间
proxy_read_timeout 4;  # 秒
# 没有发送数据关闭    后端服务器数据回传时间
proxy_send_timeout  60;

Study From: https://www.cnblogs.com/sunxun/p/15476377.html

与Nginx的Keepalive的简单学习相似的内容:

Nginx的Keepalive的简单学习

摘要 最近发现某项目的Nginx负载服务器上面有很多Time_wait的TCP连接 可以使用命令 netstat -n |awk '/^tcp/ {++S[$NF]} END{for (a in S) print a , S[a]}' 当时反馈过来 time_wait的连接特别多. 我比较菜, 没有

keepalived的简单使用

### 原理简述 本篇主要学习`keepalived`配合`nginx`实现nginx的高可用, 也就是需要keepalived检测到nginx宕机时停用keepalived, 备用keepalived会自动接收过来. 简单的原理(如下图), 主备服务器会配置相同的vip(虚拟ip), 谁的优先级高

[转帖]聊一聊nginx中KeepAlive的设置

文章目录 问题分析为什么要有KeepAlive?TCP KeepAlive和HTTP的Keep-Alive是一样的吗?Nginx的TCP KeepAlive如何设置Apache中KeepAlive和KeepAliveTimeOut参考资料 问题 之前工作中遇到一个KeepAlive的问题,现在把它记

[转帖]关于nginx 反向代理upstream中的 keepalive配置

一、关于nginx upstream 在nginx的模块中,分为3种类型,分别是handler,filter和upstream,其中upstream可以看做一种特殊的handler,它主要用来实现和后端另外的服务器进行通信,由于在nginx中全部都是使用非阻塞,并且是一个流式的处理,所以upstre

[转帖]Nginx Http 模块中 Upstream 的 keepalive 参数配置注意事项

Nginx Http 模块中 Upstream 的 keepalive 参数配置注意事项 摘要 在高并发环境下 keepalive 参数配置不当容易产生大量 TIME_WAIT,导致端口耗尽,服务异常。 keepalive 值应该大于等于 upstream 中 server 的数量。(建议是 ser

[转帖]使用 nginx 作反向代理,启用 keepalive 时,遇到 502 错误的调查过程

https://www.cnblogs.com/lizexiong/p/15358894.html 1.现象 结论见 《kubernetes ingress-nginx 启用 upstream 长连接,需要注意,否则容易 502》。nginx 的访问日志间歇性出现 502 响应,查看 nginx 的

[转帖]Nginx优化之keepalive

一、nginx之tcp_nopush、tcp_nodelay、sendfile 1、TCP_NODELAY 你怎么可以强制 socket 在它的缓冲区里发送数据? 一个解决方案是 TCP 堆栈的 TCP_NODELAY选项。这样就可以使缓冲区中的数据立即发送出去。 Nginx的 TCP_NODELA

[转帖]Nginx超时timeout 设置

Nginx 超时配置,连接时间过长直接关闭连接,显示timeout http { #每个 TCP 连接最多可以保持多长时间 keepalive_timeout 60; #客户端向服务端发送一个完整的 request header client_header_timeout 10; #客户端发送服务端

[转帖]超时时间connectTimeout,socketTimeout,proxy_read_timeout,proxy_connect_timeout笔记

1、一般的的情况 客户端(connectTimeout,socketTimeout) -- 七层接入proxy (connect timeout, read timeout, keepalive timeout, send timeout)-- nginx (proxy_read_timeout,p

[转帖]Kubernetes的Nginx Ingress 0.20之前的版本,upstream的keep-alive不生效

https://www.cnblogs.com/lizexiong/p/15358923.html 1说明 Kubernetes使用nginx-ingress-controller代理到集群内服务的请求,nginx所在的机器上上有大量的time-wait连接。 抓包发现nginx发起的到upstre