2252

Tcp“长连接”实战中的总结

乐果   发表于   2017 年 11 月 02 日 标签:tcp

因开发公司“灯控中转服务”(穿透客户端网络限制)过程中,用了tcp长连接,持续的踩坑,慢慢的对这种 网络多变网络不稳定 环境下的Tcp服务通信,有了更加清晰的认识,现总结一下。

一、理解:tcp是面向链接的,http是无状态的

tcp是建立在ip链接上,没有链接就没有通信。

http当然也是建立在tcp的基础上,但因为常用的是短链接,即链即用,所谓无状态是指“身份标识”,tcp也无身份标志,这都要靠协议自身的约定来保证,比如http为了身份状态识别,client端有cookie,server端有session,client在每次请求的报文中,都带上了cookie让server端能识别。

二、tcp在静默状态下,对链路状态无感知

tcp是面向链接的,但是,链接依赖的链路断了(也就是ip层),tcp两端其实并不会知道,只有当他们之间有报文往来的时候,才会发现报文无法到达对方(所依赖的网络链路已经发生变化)

实验:

对链接上服务的两端,中途快速把网线拔掉,然后迅速插上,此时双方ip未发送变化,服务两端的链接依然能通信~

三、服务端自我保护机制—超时, 短链接与长链接的区别

短链接:比如http请求,mysql短链接,一般server为了保护服务端不至于因长时间的占用(浪费),导致可用的链接资源被耗尽,因此server在建立链接后会设置超时来保护。即超过设定的时间,链接即自动被断开释放。

长链接:即区别与短链接,根据实际情况设置不同的规则。当然,都需要有保护机制~

四、长链接如何保证,以“灯控服务”为例,需要解决的坑

1、close未有效送出,对方无感知:

a、client退出close未有效送达,server不知道,链接池map未更新。。。。

问题/解决:

1> 会出现管理后台发送的“指令”下发失败,因为链接池map中的链接(对方)实际上已经断开;

2> 会出现重复链接:之前在做灯控中转服务的时候,并未考虑重复链接的问题,因此采用了如有相同标识的链接请求,如发现链接池map中存在,会直接拒绝; 之后修改了策略,重复链接,新的链接会取代map中的旧链接,但在这个过程中,又因为旧链接资源并未有效释放,后来导致系统分配的资源耗尽而无法接收新的链接请求。。。

b、server主动close未有效送达,client不知道,它会傻等。。。。

问题/解决:

1> 链接处于断开状态,只能等待client再次发出链接请求,在这一段时间,处于无法控制的状态;

那么,对方如何有效感知?心跳机制、超时机制。。。
2、网络断开/ip地址发生改变

a、server/client在不发送通信前,都不知道,只有向对方发送指令(报文)时,才会报错。。。

问题/解决:

1> 不会事先知道,待用户发指令时会报错;

2> 如果事先知道,第一时间重新链接,以链接可用的状态等待用户的指令;

那么,如何事先知道?心跳机制。。。
3、心跳报文 与 用户指令报文 有序传达

1> 心跳由服务端定期发出:周期时长?

2> 心跳、用户指令 都属于报文,tcp的请求/应答是阻塞的,一般情况即一应一答,因此要保证每次请求有序进行:原子锁/阻塞,保证有效进行一应一答。

3> 客户端没有心跳机制,如何保护?超时重链:没有报文活跃的连续时间超过多少,就认为是网络断开了,重新发起链接请求。超时时长?

4> 上述1、3中,server端的心跳周期时长值 应小于 client超时时长值。

乐果   发表于   2017 年 11 月 02 日 标签:tcp

0

文章评论