作者回复: 你回复的很全面,给你点赞! 如你所述,NAT一般会维护一个连接映射表,而这个表里的表项是有有效期的,也就是过了一定的时间就从表里删除,那么后续两端在这个连接上的报文经过NAT的时候,因为找不到表项,就被判定为无效报文,就会被丢弃。
作者回复: 您好,这几个问题质量很高,我说下自己的理解: 1. TCP是全双工的协议,所以两个方向都可以自己选择是否要做keep-alive。如果客户端setsockopt()启用了Keep-alive,那客户端会定时发送保活报文,服务端会回复ack(这个是必做的,跟服务端是否启用保活没有关系)。如果服务端也开启了TCP keep-alive,那就相互发送保活报文。但是,考虑一方的idle timeout会随着另一方发送的保活报文而被刷新,所以是相互有影响的。 比如,客户端10分钟发一次保活,服务端是15分钟发一次保活。那么在第10分钟时,客户端发送了报文,对服务端来说,因为此时接收到了报文,所以idle timeout就被刷新为0了,服务端计划等到第25分钟再发它自己的保活报文。实际上在第20分钟,客户度再次发送保活报文,服务端的idle timeout再次被刷新,所以服务端就不再发送它这端的保活报文了,因为没有机会等满15分钟空闲。 2. 跟1类似,因为是两个方向上自己的选择,所以双方依然可以各自设置保活参数。但实际上我们只会看到间隔更小的那个保活报文。 3. HTTP Keep-alive是告知对方:“我想这次用TCP长连接”,它本身不是定时周期性发送的保活报文。如果HTTP请求耗时超过了TCP保活的时长,那TCP保活报文会按时发送TCP保活报文并得到服务端的ack,这跟HTTP响应什么时候回复出来不矛盾,也无关。 我们还发现,有些web服务器会选择在一个长连接服务了一定数量的HTTP请求之后(比如1000个),选择发送一次Connection:close给客户端,让客户端结束这次连接,这给了客户端一次重新选择服务端的机会(比如LB会新选一个后端服务器给它)。
作者回复: 没错,状态机在两端是有可能不一致的,比如一端认为这条连接已经销毁,另外一端可能认为仍有效。心跳机制的作用之一就是解决这种不一致的情况,类似“校对”的作用。
作者回复: 你的疑问是为什么有PSH标志位吗?按照TCP协议(参考RFC793)规定,操作系统收到有PSH标志位的报文后,这些报文不会被驻留在接收缓冲区,而是要立即通知用户空间程序来接收。这样对于用户空间程序及时收发处理心跳报文是有利的。
作者回复: 你说的断开,有没有抓到过TCP报文?是收到了RST还是什么呢?RST报文的TTL跟正常连接的TTL有什么不一样吗? 有一个可能性你路径上有防火墙或者NAT,它们会对TCP连接信息进行一定时间的缓存,如果你的长连接中的报文隔了很久才传送,此时可能防火墙/NAT上这个连接的信息已经没有了。 一直跑着ping,虽然跟TCP连接没有直接关系,但不排除这个中间设备会因为持续ping的存在,也把这个源IP相关的TCP连接做了维持。这只是我的一个猜测,供参考~
作者回复: 正确:)
作者回复: 谢谢您的意见。总的来说,“在下一次 HTTP 请求的时候,客户端就会遵循“DNS 解析 -> 发起新连接 -> 发送 HTTP 请求”这一句没有太大问题。这里说的“DNS解析”可以是从本地解析缓存中获取,也可以到DNS服务器上获取,这都属于解析行为。 不同的操作系统行为不完全一样。windows默认启用dns client service,它会缓存DNS解析记录。linux默认没有dns缓存,但是可以通过安装nscd或者dnsmasq来实现类似的解析缓存。 在ebay的环境里,启用和未启用本地解析缓存的情况都存在。对于没有解析缓存的情况,Connection:close起效快;如果有缓存,起效会慢一点,但最差情况也能在DNS record TTL时间后发起新的解析请求。 当然,这里的讨论没有考虑应用程序做解析缓存的情况(包括jvm也有相关的dns解析缓存的配置),否则可能文章写不完:)
作者回复: 1. 意思对了:) 表达式是tcp.payload contains "abc" 2. 你说的情况我们经常遇到,我估计你说的就是客户端自己的超时设置,也就是如果http响应无法在限定时间内完成(比如1秒内),那么客户端应用程序自己会报timeout错误。这应该不是中间设备做了reset,因为如果是那样,这个中间设备应该会给客户端和服务端都发TCP RST,然后客户端报错会变成ECONNRESET这种(ECONNRESET是linux的网络协议栈报给用户空间程序的报错)
作者回复: 负载均衡(有时候叫做应用网关、反向代理,其实都是差不多的)一般都带有设置第七层规则的能力。在这里,就是需要插入一个HTTP header,其键是Connection,值是Close。 Connection: Close 具体做法取决于你用的是哪一种产品,查阅相应的产品文档即可。
作者回复: 跟你另外一个问题类似,参考那个的答案:)