当我使用 netstat 命令时,它显示..
tcp 0 0 本地主机:18056 本地主机:mysql TIME_WAIT
tcp 0 0 本地主机:16683 本地主机:mysql TIME_WAIT
tcp 0 0 本地主机:16701 本地主机:mysql TIME_WAIT
tcp 0 0 本地主机:16888 本地主机:mysql TIME_WAIT
本地主机WAIT2TIME_WAIT 本地主机WAIT2TIME
tcp 0 0 本地主机:17725 本地主机:mysql TIME_WAIT
tcp 0 0 本地主机:17682 本地主机:mysql TIME_WAIT
tcp 0 0 本地主机:17414 本地主机:mysql TIME_WAIT
tcp 0 0 本地主机:17606 本地主机:mysql TIME_WAIT
tcp 0 0 本地主机:17737 本地主机:mysql TIME_WAIT
tcp 0 0 本地主机:16632 本地主机:mysql TIME_WAIT
tcp 0 0 本地主机:16825 本地主机:mysql TIME_WAIT 本地主机WAIT 时域主机WAIT 0 0 0 本地主机:mysql TIME_WAIT
本地主机时
tcp …
我从我的客户端 PC 连接到网络服务器,它仅使用 HTTPS。
当我连接时,我在 TCPView(替代 netstat 的 sysinternals 工具)中看到了很多到 https 端点的 TIME_WAIT 连接。很多时候我看到 11 个连接在 TIME_WAIT 中停留了 2 分钟。这就是每次我提出请求时。2-4 个连接在 ESTABLISHED 中保持打开状态无论我设置服务器的时间有多长Keep-Alive: timeout=xx
后面的连接是可以的,它们被适当地重用。之前的连接建立并需要整整 2 分钟。
我使用 WireShark 捕获了流量,并在延迟连接的源端口上看到了正常的 FIN、ACK 等传递。我经常看到 Chrome 和 IE(它们都使用 Windows HTTP 堆栈)在任何带有真实数据的请求出现之前发出 6 个 TCP 请求。有效载荷很小(大约 2000 字节)。
Firefox 根本不发出这些请求......
还值得一提的是,该证书是自签名的,并且不会在浏览器中进行验证(Firefox 的处理方式与 chrome 完全不同)。
为什么我的浏览器会发出这些请求?为什么 Firefox 不发出这些 tcp 连接?
编辑,这是 Chrome 建立的第一个连接的转储(使用wireshark 捕获):
"https","0.000000",local-ip,dest-ip,"443","TCP","53890 > https [SYN] Seq=0 Win=8192 Len=0 MSS=1460 WS=8 SACK_PERM=1"
"53890","0.012749",dest-ip,local-ip,"53890","TCP","https > 53890 [SYN, ACK] Seq=0 Ack=1 Win=65535 Len=0 MSS=1400 …
Run Code Online (Sandbox Code Playgroud) 据我所知,'time_wait' stat 中的 tcp 端口无法使用。但是,在我的实验中,服务器重用了“time_wait”端口?为什么?
首先,在客户端机器中,输入 command ehco 40000 40001 > /proc/sys/net/ipv4/ip_local_port_range
。因此,TCP 端口的最大数量为 2。
服务器代码
while (1) {
int len = sizeof(struct sockaddr);
fd = accept(sfd, &remote, &len);
read(fd, buf, sizeof(buf));
close(fd);
}
Run Code Online (Sandbox Code Playgroud)
客户代码
for (i = 0; i < 3; i++)
{
sleep(1);
pid_t pid = fork();
if (pid == 0)
{
handler();
exit(0);
}
}
void handler()
{
* ............. */
res = connect(sfd, result->ai_addr, result->ai_addrlen);
if (res == -1) {
perror("error");
exit(1);
}
printf("connect\n");
}
Run Code Online (Sandbox Code Playgroud)
展示 …
我们目前在消息中遇到了很多 Redis 错误
无法连接:连接时读取错误,尝试下一个服务器
我们使用 PHP Redis 在 FreeBSD 上运行 Redis,我们很难在 Ubuntu 上重现该错误,因此这可能是一个提示。在 github 上有一个关于该主题的长期问题。
基本上我们通过调用connect(host, port, timeout)
phpredis从操作系统获得一个套接字,但是当我们select(db_index)
之后执行 a 时,我们得到一个异常。持久化会不会有问题?我假设 connect 在后台不执行任何操作,而 select 尝试访问实际上已关闭的连接。
我们不会遇到超时。我们尝试调整 TIME_WAIT 没有成功。
关于问题可能来自哪里的任何其他想法?跟踪问题的最佳方法是什么?dtrace 也许?
更新
我们目前正在研究我们的 BGSAVE 设置。有趣的是,为定期将数据写入磁盘(持久性)的进程创建一个 fork 需要半秒甚至更多的时间,并且可能 redisconnect()
在该时间段内无法响应请求。
tcp_rfc1337 设置似乎有解决 TIME-WAIT 暗杀的方法。
第一个问题是新连接中可能会错误地接受旧的重复数据,导致发送的数据损坏。
第二个问题是连接可能会变得不同步并进入 ACK 循环,因为旧的重复数据包进入新连接,这将变得不同步。
第三个也是最后一个问题是旧的重复数据包可能会错误地进入新建立的连接并杀死新连接。
从我读到的内容来看,为了解决问题,设置的作用是在套接字处于 TIME-WAIT 状态时忽略 RST(重置)数据包。
那么,为什么默认情况下不启用此设置?使用这个有什么缺点?
当我研究如何阻止 SYN 泛洪攻击时,我实际上了解了这个变量。您认为此设置有助于阻止它们吗?
上周我们的一台图像服务器出现了一些问题,需要一些帮助。查看我们的 munin 监控图:
我们正在运行 debian 挤压,我们有很多请求,因为这是我们的图像服务器之一。我们不使用 keep-alive(也许我们应该,但那是另一个话题)
这些数字是我们日志文件中每分钟的请求数:
所以你看,我们每分钟有很多请求,但由于大多数请求在 0-1 毫秒内提供服务,所以通常一切正常。
现在,正如您在我们的 munin 图形中看到的,munin 无法通过 munin 端口连接到此服务器并询问相关号码。连接失败了。由于服务器不会以任何方式(CPU、内存、网络)过载。它一定与我们的防火墙/tcp 堆栈有关。在 munin 插件连接失败时,我们在 100MBit 连接上只有 17MBit 的传入和传出流量。
您经常在这里限制 65k 的 tcp 连接,但这通常会产生误导,因为它指的是 16 位 tcp 标头并且属于每个 ip/端口组合 65k。
我们的 time_wait 超时设置为
net.ipv4.tcp_fin_timeout = 60
Run Code Online (Sandbox Code Playgroud)
我们可以降低它以更早地删除更多 TIME_WAIT 连接,但首先我想知道是什么限制了网络的可达性。
我们正在使用带有状态模块的 iptables。但是我们已经提高了 max_conntrack 参数。
net.ipv4.netfilter.ip_conntrack_max = 524288
Run Code Online (Sandbox Code Playgroud)
有没有人知道下周要查看哪些内核参数或如何诊断这个问题?
是否可以恢复处于 TIME_WAIT 状态的连接?
如果没有,我使用原始数据包(伪造来源),这可能吗?
(请理解我无意做坏事,只是好奇而已)
HTTP 请求上的 keep-alive 和 TIME_WAIT 中的 tcp 套接字之间有什么关系 - 它们应该相关吗?
此外,系统和网络服务器设置是否应该保持一致,例如server.max-keep-alive-idle = 60
?根据如何减少 TIME_WAIT 中的套接字数量?在 Linux 中,TIME_WAIT 状态被硬编码为 60 秒(至少对于 Linux 的 Ubuntu/Debain 值)。
在 lighttpd 中是默认值server.max-keep-alive-idle = 5
,他们建议在高负载时甚至更低。如果 tcp 套接字可用,则在 5 秒后关闭 http 请求似乎是一种浪费——当然,假设设置按照net.ipv4.tcp_tw_reuse = 1
它在锡上所说的进行。
这个相关的问题 - tcp 如何保持连接有效?[关闭]触及了这个问题,但没有为我完全回答。