Java面试-TCP连接及其优化
作为一个后端程序员,网络连接这块是一个绕不过的砍,当你在做服务器优化的时候,网络优化也是其中一环,那么作为网络连接中最基础的部分-TCP连接你了解吗?今天我们来仔细看看这个部分。
TCP建立连接-三次握手
详解

- 客户端和服务器还未建立连接,但服务器一般处于
listen状态 - 客户端主动建立连接,向服务器发送SYN报文,客户端变为
SYN_SENT状态 - 服务器收到客户端发送的报文,也回了一个SYN报文,包含了一个ack。此时,服务器变为
SYN_RCVD状态 - 客户端收到了服务器发送的SYN报文,确认了ack,它将向服务器发送一个ACK报文。此时,客户端变为
ESTABLISHED - 服务器收到客户端的ACK报文,确认了ack。此时,服务器也变为
ESTABLISHED - 服务器和客户端可以正常通信了
其中步骤2~4就是三次握手,那么为什么需要三次握手呢?为什么不是一次或者两次握手呢?
首先,我们需要知道,只有当服务器和客户端都能确保自己能够发消息和接收消息,这次网络通信才算成功的。
步骤2的作用是让服务器知道了自己是可以接收消息的。
步骤3的作用是让客户端知道自己发送消息和接收消息的功能是OK的,发送消息的能力是通过服务器返回的ack=x+1确认的,因为这个值基于当初客户端发送的消息seq=x。接收消息的能力是因为收到了服务器的返回。
步骤4的作用是让服务器端知道自己发送消息的能力是OK的(和步骤3类似)。
linux查看
linux服务器可以利用netstat -anp | grep tcp命令,查看服务器上各个端口和应用的连接状态。
你还可以通过修改linux的配置文件/etc/sysctl.conf,调整各个状态的数量
SYN_SENT状态相关
- 主动建立连接时,发SYN(步骤2)的重试次数
nct.ipv4.tcp_syn_rctries = 6
- 建立连接时的本地端口可用范围
net.ipv4.ip_local_port_range = 32768 60999
SYN_RCVD状态相关
SYN_RCVD状态连接的最大个数
net.ipv4.tcp_max_syn_backlog
- 被动建立连接时,发SYN/ACK(步骤3)重试次数
net.ipv4.tcp_synack_retries
说完了TCP建立连接,接下来,我们再来看看TCP正常断开连接的过程
TCP断开连接-四次挥手
详解

- 客户端与服务器端正常传输数据
- 客户端主动断开连接,向服务器端发送FIN报文,客户端变为
FIN_WAIT1状态 - 服务器收到客户端的FIN后,向客户端发送ACK报文,服务器变为
CLOSE_WAIT状态 - 客户端收到服务器的ACK报文后,客户端变为
FIN_WAIT2状态 - 服务器向客户端发送FIN报文,服务器变为
LAST_ACK状态 - 客户端收到服务器发送的FIN报文后,向服务器发送ACK报文,客户端变为
TIME_WAIT状态 - 服务器收到客户端的ACK报文后,服务器变为
CLOSED状态 - 客户端经过2MSL(max segment lifetime,报文最大生存时间)时间后,也变为
CLOSED状态
其中,步骤2、3、5、6即为4次挥手。
TIME_WAIT状态及其优化
看完之后,大家想必会有一个疑问,为什么TIME_WAIT状态需要保持2MSL?因为这可以保证至少一次报文的往返时间内,端口是不可复用的。
假设TIME_WAIT状态的持续时间很短,我们来模拟下面这种场景:

- 客户端向服务器端发送了三条报文,其中第3条报文卡在网络中,服务器只收到了前两条,向客户单发送ACK=2,客户端重新发送第三条报文。
- 服务器主动发送FIN报文,客户端收到后发送FIN、ACK,服务器端收到后发送ACK并进入
TIME_WAIT状态(假设这个状态很短)。 - 现在服务器又再次和客户端建立连接,三次握手之后开始发送正常数据,结果之前卡住的第三条报文,现在终于发送到服务器,但服务器也不知道该如何处理这条报文。
因此这也是TIME_WAIT状态需要保持2MSL的原因,如果这么长时间也没有收到报文,即使有正确的报文从客户端发出,也已经过期了,因此不会影响到之后的通信。
但这同样也会带来一个问题,TIME_WAIT状态保持的时间较长,假设服务器端有大量TIME_WAIT状态的TCP连接,就相当于白白浪费掉大量的服务器资源(端口)。此时,我们可以通过修改以下配置进行服务器调优:
net.ipv4.tcp_tw_reuse = 1
- 开启后,作为客户端时新连接可以使用仍然处于
TIME_WAIT状态的端口 - 由于timestamp的存在,操作系统可以拒绝迟到的报文(例如上面说的第三条报文),可以利用以下配置:
net.ipv4.tcp_timestamps = 1
其他状态的优化
CLOSE_WAIT状态
如果服务器端有大量CLOSE_WAIT状态的连接,很有可能是应用进程出现bug,没有及时关闭连接。
FIN_WAIT1状态
调整发送FIN报文的重试次数,0相当于8
net.ipv4.tcp_orphan_retries = 0
FIN_WAIT2状态
调整保持在FIN_WAIT2状态的时间
net.ipv4.tcp_fin_timeout = 60
总结
看到这里,想必你应该对TCP连接有了一个大致的了解。现在服务器大多都用了nginx做了负载均衡,因此,我们可能需要在此基础上了解一些nginx相关的配置原理,这样应该会对我们的服务器性能调优会有更大的帮助。有兴趣的同学不妨可以去了解一下,如果有什么新发现想和作者探讨的,欢迎在下方留言。
有兴趣的话可以关注我的公众号,说不定会有意外的惊喜。

Java面试-TCP连接及其优化的更多相关文章
- ubuntu系统TCP连接参数优化-TIME_WAIT过多解决办法
状态:描述CLOSED:无连接是活动的或正在进行LISTEN:服务器在等待进入呼叫SYN_RECV:一个连接请求已经到达,等待确认SYN_SENT:应用已经开始,打开一个连接ESTABLISHED:正 ...
- 可能会搞砸你的面试:你知道一个TCP连接上能发起多少个HTTP请求吗?
本文由原作者松若章原创发布,作者主页:zhihu.com/people/hrsonion/posts,感谢原作者的无私分享. 1.引言 一道经典的面试题是:从 URL 在浏览器被被输入到页面展现的过程 ...
- 面试官:一个 TCP 连接可以发多少个 HTTP 请求?
曾经有这么一道面试题:从 URL 在浏览器被被输入到页面展现的过程中发生了什么? 相信大多数准备过的同学都能回答出来,但是如果继续问:收到的 HTML 如果包含几十个图片标签,这些图片是以什么方式 ...
- 【Java面试】TCP协议为什么要设计三次握手?
一个工作5年的粉丝,最近去面试了很多公司,每次都被各种技术原理题问得语无伦次. 由于找了快1个月时间的工作,有点焦虑,来向我求助. 我能做的只是保证每天更新一个面试题,然后问他印象最深刻的一个面试题是 ...
- 初步探究java中程序退出、GC垃圾回收时,socket tcp连接的行为
初步探究java中程序退出.GC垃圾回收时,socket tcp连接的行为 今天在项目开发中需要用到socket tcp连接相关(作为tcp客户端),在思考中发觉需要理清socket主动.被动关闭时发 ...
- 关于Kafka java consumer管理TCP连接的讨论
本篇是<关于Kafka producer管理TCP连接的讨论>的续篇,主要讨论Kafka java consumer是如何管理TCP连接.实际上,这两篇大部分的内容是相同的,即consum ...
- 服务器tcp连接timewait过多优化及详细分析
[背景说明] 在7层负载均衡上,查询网络状态发现timewait太多,于是开始准备优化事宜 整体的拓扑结构,前面是lvs做dr模式的4层负载均衡,后端使用(nginx.or haproxy)做7层负载 ...
- Java面试准备十六:数据库——MySQL性能优化
2017年04月20日 13:09:43 阅读数:6837 这里只是为了记录,由于自身水平实在不怎么样,难免错误百出,有错的地方还望大家多多指出,谢谢. 来自MySQL性能优化的最佳20+经验 为查询 ...
- TCP协议(包括TCP的连接过程,数据分段,TCP有关服务器优化)
Transmission Control Protocol/Internet Protocol 传输控制协议/因特网互联协议 TCP/IP是一个Protocol Stack(协议栈),包括TCP.IP ...
随机推荐
- CTF挑战赛丨网络内生安全试验场第一季答题赛火热开启
前期回顾:挑战世界级“人机大战”,更有万元奖金等你来拿 网络内生安全试验场自上线以来,受到了业内的极大重视与关注. 自9月2日报名通道开启后,报名量更是持续高升,上百名精英白帽踊跃报名. 至此,网络内 ...
- AutoresizingMask 的使用
(1)先了解一下这几个枚举值的含义: (2)代码演说: 在viewcontroller 用代码创建一个红色的view,如下: UIView *redView = [[UIView alloc] ini ...
- flask uwsgi和nginx配置信息
1. 安装 pip3 install uwsgi 2. uwsgi配置信息 创建一个uwsgi.ini文件 [uwsgi] socket=/opt/script/uwsgi.sock #启动程序时所使 ...
- GCN
REFERENCE: https://www.jianshu.com/p/ad528c40a08f https://www.zhihu.com/question/54504471 图有两个基本的特性: ...
- Linux Kernel PANIC(三)--Soft Panic/Oops调试及实例分析【转】
转自:https://blog.csdn.net/gatieme/article/details/73715860 版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原 ...
- 5.3 RDD编程---数据读写
一.文件数据读写 1.本地文件系统的数据读写 可以采用多种方式创建Pair RDD,其中一种主要方式是使用map()函数来实现 惰性机制,即使输入了错误的语句spark-shell也不会马上报错. ( ...
- Linux---文件压缩与解压缩命令
压缩格式: zip.gz.bz2.tar .tar.gz.tar.bz2.tar.xz.xz.z 最常用的是.tar.gz格式和.tar.bz2格式 1.zip格式 命令 说明 zip 压缩文件名 ...
- Grafana中mysql作为数据源的配置方法
需求 近期在使用python写一套模拟API请求的监控项目,考虑数据可视化这方面就采用grafana来呈现,下面来看看怎么弄. 数据源准备 首先安装好mysql,将监控的日志数据写入到mysql之中. ...
- destoon漏洞修复关于 $do->add($post); SQL注入修改
在阿里云漏洞提示查看发现destoon有关于mobile/guestbook.php $do->add($post); SQL注入修改 漏洞名称:Destoon SQL注入 补丁文件:/mobi ...
- Genymotion模拟器上money测试
1.查看APK包名:sdk\build-tools\android-4.4W>aapt dump xmltree 123.apk AndroidManifest.xml 查看包名为:com.aa ...