TCP / IP関連のインタビューの質問

最初のハンドシェイク:接続が確立され、クライアントはサーバにSYNパケット(SYN = X)を送信し、確認するためにサーバを待って、SYN_SENT状態になり、SYN:同期シーケンス番号(同期シーケンス番号)。

第ハンドシェーク:サーバー自体が(SYN = Y)SYNパケットを送信し、すなわち、SYN + ACKパケットを、サーバが状態SYN_RECVに入っている間、顧客にSYN(ACK = X + 1)を確認する必要があり、SYNパケットを受信します。

第三のハンドシェーク:クライアントがサーバにSYN + ACKパケットを受信し、サーバは受信確認パケットACK(ACK = Y + 1)を送信し、このパケットが送信され、ESTABLISHED(TCP接続が成功した)状態にクライアントとサーバは、3つ完了します握手。

 

最初のハンドシェイク:接続が確立され、クライアントはサーバにSYNパケット(SYN = X)を送信し、確認するためにサーバを待って、SYN_SENT状態になり、SYN:同期シーケンス番号(同期シーケンス番号)。

第ハンドシェーク:サーバー自体が(SYN = Y)SYNパケットを送信し、すなわち、SYN + ACKパケットを、サーバが状態SYN_RECVに入っている間、顧客にSYN(ACK = X + 1)を確認する必要があり、SYNパケットを受信します。

第三のハンドシェーク:クライアントがサーバにSYN + ACKパケットを受信し、サーバは受信確認パケットACK(ACK = Y + 1)を送信し、このパケットが送信され、ESTABLISHED(TCP接続が成功した)状態にクライアントとサーバは、3つ完了します握手。

 

 

 

 

すべてのアクティブ近いソケットがTIME_WAIT状態になります最後のACKを送信した後にパーティをシャットダウンするためのイニシアチブは、TIME_WAIT状態になります2MSL(最大セグメント寿命)時間のまま、これはTCP / IPの基本的な、である、「解決」へすることはできません。 

1。接続パッケージの防止、迷子に再出現した後、新しい接続のインパクト(2MSLては、重複パケットのすべての最後の接続が消えます) 
2。信頼性の高いTCP接続が閉じられている 
当事者がCLOSED状態にある場合は、最後のアクティブ近いではACK(フィン)が、そこに欠落している可能性があり、その後、パッシブ側はフィン再送信されます送信し、その後、率先して、その代わりに、ACK、RST応答します。したがって、TIME_WAIT状態にアクティブ側が、閉じることができません。

 

サーバがクライアントのアクティブではなく、オフを切断しようとするように設計したがって、大規模なプログラミング同時サーバー、。

 

可以在 /etc/sysctl.conf 设置一些内核参数,让内核尽快回收处理TIME_WAIT状态,以免因为这此占用端口过多(端口不够用就是文件描述符不够用了,因为文件描述符只有在从TIME_WAIT状态转换到CLOSE状态后才会真正被系统收回。还有一个是),影响正常的客户请求连接。

 

net.ipv4.tcp_syncookies = 1 表示开启SYN Cookies。当出现SYN等待队列溢出时,启用cookies来处理,可防范少量SYN攻击,默认为0,表示关闭; 
net.ipv4.tcp_tw_reuse = 1 表示开启重用。允许将TIME-WAIT sockets重新用于新的TCP连接,默认为0,表示关闭; 
net.ipv4.tcp_tw_recycle = 1 表示开启TCP连接中TIME-WAIT sockets的快速回收,默认为0,表示关闭。 
net.ipv4.tcp_fin_timeout = 30 表示如果套接字由本端要求关闭,这个参数决定了它保持在FIN-WAIT-2状态的时间。 
net.ipv4.tcp_keepalive_time = 1200 表示当keepalive起用的时候,TCP发送keepalive消息的频度。缺省是2小时,改为20分钟。 
net.ipv4.ip_local_port_range = 1024 65000 表示用于向外连接的端口范围。缺省情况下很小:32768到61000,改为1024到65000。 
net.ipv4.tcp_max_syn_backlog = 8192 表示SYN队列的长度,默认为1024,加大队列长度为8192,可以容纳更多等待连接的网络连接数。 
net.ipv4.tcp_max_tw_buckets = 5000表示系统同时保持TIME_WAIT套接字的最大数量,如果超过这个数字,TIME_WAIT套接字将立刻被清除并打印警告信息。默认为 180000,改为5000。对于Apache、Nginx等服务器,上几行的参数可以很好地减少TIME_WAIT套接字数量,但是对于Squid,效 果却不大。此项参数可以控制TIME_WAIT套接字的最大数量,避免Squid服务器被大量的TIME_WAIT套接字拖死。 
执行以下命令使配置生效: 
/sbin/sysctl -p

 

 

 

为什么我们要关注这个高并发短连接呢?有两个方面需要注意:
1. 高并发可以让服务器在短时间范围内同时占用大量端口,而端口有个0~65535的范围,并不是很多,刨除系统和其他服务要用的,剩下的就更少了。
2. 在这个场景中,短连接表示“业务处理+传输数据的时间 远远小于 TIMEWAIT超时的时间”的连接

      这里有个相对长短的概念,比如取一个web页面,1秒钟的http短连接处理完业务,在关闭连接之后,这个业务用过的端口会停留在TIMEWAIT状态几分钟,而这几分钟,其他HTTP请求来临的时候是无法占用此端口的(占着茅坑不拉翔)。单用这个业务计算服务器的利用率会发现,服务器干正经事的时间和端口(资源)被挂着无法被使用的时间的比例是 1:几百,服务器资源严重浪费。(说个题外话,从这个意义出发来考虑服务器性能调优的话,长连接业务的服务就不需要考虑TIMEWAIT状态。同时,假如你对服务器业务场景非常熟悉,你会发现,在实际业务场景中,一般长连接对应的业务的并发量并不会很高
     综合这两个方面,持续的到达一定量的高并发短连接,会使服务器因端口资源不足而拒绝为一部分客户服务。同时,这些端口都是服务器临时分配,无法用SO_REUSEADDR选项解决这个问题。

 

大量的TIMEWAIT状态影响服务器后续的连接请求服务,目前按我理解应该只在有中间代理中转服务器时才会出现这种情况,因为中转中间层的服务器IP地址有限(一般只有1~10台),这样很容易出现客户端下次连接的请求与处于TIMEWAIT状态的客户端IP和端口号一样,导致不能正常响应客户端的连接请求。在TIMEWAIT状态同样的客户端IP和端口号连接过来时,服务器可能直接发送RST报文拒绝连接服务。

 

 

所有执行主动关闭的socket都会进入TIME_WAIT状态,主动关闭的一方在发送最后一个 ack 后就会进入 TIME_WAIT 状态 停留2MSL(max segment lifetime)时间,这个是TCP/IP必不可少的,也就是“解决”不了的。 

1。防止上一次连接中的包,迷路后重新出现,影响新连接(经过2MSL,上一次连接中所有的重复包都会消失) 
2。可靠的关闭TCP连接 
在主动关闭方发送的最后一个 ack(fin) ,有可能丢失,这时被动方会重新发fin, 如果这时主动方处于 CLOSED 状态 ,就会响应 rst 而不是 ack。所以主动方要处于 TIME_WAIT 状态,而不能是 CLOSED 。

 

所以在大并发服务器编程中,尽量设计成客户端主动断开连接,而不是由服务器端断开。

 

可以在 /etc/sysctl.conf 设置一些内核参数,让内核尽快回收处理TIME_WAIT状态,以免因为这此占用端口过多(端口不够用就是文件描述符不够用了,因为文件描述符只有在从TIME_WAIT状态转换到CLOSE状态后才会真正被系统收回。还有一个是),影响正常的客户请求连接。

 

net.ipv4.tcp_syncookies = 1 表示开启SYN Cookies。当出现SYN等待队列溢出时,启用cookies来处理,可防范少量SYN攻击,默认为0,表示关闭; 
net.ipv4.tcp_tw_reuse = 1 表示开启重用。允许将TIME-WAIT sockets重新用于新的TCP连接,默认为0,表示关闭; 
net.ipv4.tcp_tw_recycle = 1 表示开启TCP连接中TIME-WAIT sockets的快速回收,默认为0,表示关闭。 
net.ipv4.tcp_fin_timeout = 30 表示如果套接字由本端要求关闭,这个参数决定了它保持在FIN-WAIT-2状态的时间。 
net.ipv4.tcp_keepalive_time = 1200 表示当keepalive起用的时候,TCP发送keepalive消息的频度。缺省是2小时,改为20分钟。 
net.ipv4.ip_local_port_range = 1024 65000 表示用于向外连接的端口范围。缺省情况下很小:32768到61000,改为1024到65000。 
net.ipv4.tcp_max_syn_backlog = 8192 表示SYN队列的长度,默认为1024,加大队列长度为8192,可以容纳更多等待连接的网络连接数。 
net.ipv4.tcp_max_tw_buckets = 5000表示系统同时保持TIME_WAIT套接字的最大数量,如果超过这个数字,TIME_WAIT套接字将立刻被清除并打印警告信息。默认为 180000,改为5000。对于Apache、Nginx等服务器,上几行的参数可以很好地减少TIME_WAIT套接字数量,但是对于Squid,效 果却不大。此项参数可以控制TIME_WAIT套接字的最大数量,避免Squid服务器被大量的TIME_WAIT套接字拖死。 
执行以下命令使配置生效: 
/sbin/sysctl -p

 

 

 

为什么我们要关注这个高并发短连接呢?有两个方面需要注意:
1. 高并发可以让服务器在短时间范围内同时占用大量端口,而端口有个0~65535的范围,并不是很多,刨除系统和其他服务要用的,剩下的就更少了。
2. 在这个场景中,短连接表示“业务处理+传输数据的时间 远远小于 TIMEWAIT超时的时间”的连接

      这里有个相对长短的概念,比如取一个web页面,1秒钟的http短连接处理完业务,在关闭连接之后,这个业务用过的端口会停留在TIMEWAIT状态几分钟,而这几分钟,其他HTTP请求来临的时候是无法占用此端口的(占着茅坑不拉翔)。单用这个业务计算服务器的利用率会发现,服务器干正经事的时间和端口(资源)被挂着无法被使用的时间的比例是 1:几百,服务器资源严重浪费。(说个题外话,从这个意义出发来考虑服务器性能调优的话,长连接业务的服务就不需要考虑TIMEWAIT状态。同时,假如你对服务器业务场景非常熟悉,你会发现,在实际业务场景中,一般长连接对应的业务的并发量并不会很高
     综合这两个方面,持续的到达一定量的高并发短连接,会使服务器因端口资源不足而拒绝为一部分客户服务。同时,这些端口都是服务器临时分配,无法用SO_REUSEADDR选项解决这个问题。

 

大量的TIMEWAIT状态影响服务器后续的连接请求服务,目前按我理解应该只在有中间代理中转服务器时才会出现这种情况,因为中转中间层的服务器IP地址有限(一般只有1~10台),这样很容易出现客户端下次连接的请求与处于TIMEWAIT状态的客户端IP和端口号一样,导致不能正常响应客户端的连接请求。在TIMEWAIT状态同样的客户端IP和端口号连接过来时,服务器可能直接发送RST报文拒绝连接服务。

发布了20 篇原创文章 · 获赞 1 · 访问量 1万+

おすすめ

転載: blog.csdn.net/zhjixi495/article/details/104518859