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 ...
随机推荐
- MySql学习笔记三
MySql学习笔记三 4.DML(数据操作语言) 插入:insert 修改:update 删除:delete 4.1.插入语句 语法: insert into 表名 (列名1,列名2,...) val ...
- PHP扩展使用-GD
一.相关函数 1. 获取信息 gd_info() #查看当前系统环境gd库支持的图片格式 getimagesize(imagefile) #获取图像大小,非GD库函数 imagex(imagefile ...
- Unity检视面板的继承方法研究 (二)
之前做了普通对象的可继承的检视面板类, 现在想要实现对Unity自带的检视面板的继承的话, 要怎样写呢? 万变不离其宗, 仍然是围绕UnityEditor.Editor.CreateEditor 这 ...
- 便宜的回文 (USACO 2007)(c++)
2019-08-21便宜的回文(USACO 2007) 内存限制:128 MiB 时间限制:1000 ms 标准输入输出 题目类型:传统 评测方式:文本比较 题目描述 追踪每头奶牛的去向是一件棘手的任 ...
- 01day-微信小程序 表单组件 动态绑定变量 导航组件 地图组件 view text button 上下滚动组件
04-开发者环境搭建(下载安装开发者工具) 01==>微信开发工具的下载 安装 微信小程序的工具是 下载稳定版本的 安装的时候 直接下一步就可以了 02==>项目名陈随便输入 目录 App ...
- E07【餐厅】What would you recommend?
核心句型 What would you recommend? 你有什么推荐吗? 场景对话: A:What do you want to eat? 你想吃点什么? B:I don't know. ...
- spark写入空值到Oracle
转自:https://blog.csdn.net/qq_33792843/article/details/83750025 val nullStr = org.apache.spark.sql.fun ...
- TCP/IP协议族(五)
目前实际使用的网络模型是 TCP/IP 模型,它对 OSI 模型进行了简化,只包含了四层,从上到下分别是应用层.传输层.网络层和链路层(网络接口层),每一层都包含了若干协议. 协议(Protocol) ...
- Netty线程模型(五)
Netty支持单线程.主线程模型.主从多线程模型. 我们在创建线程组的时候,如果不传递参数,则默认构建的线程组线程是CPU核心数量. 一.单线程模型 在ServerBootstrap调用方法group ...
- pycharm写好的python项目怎么上传到github?
话不多说,直接抛链接 Pycharm项目上传到Github