扫描二维码 上传二维码
选择防红平台类型,避免链接被拦截
选择允许访问的平台类型

新浪短链接请求超时问题的有效解决办法

在分布式系统里,超时怎么处理、请求怎么设计,直接决定了系统的性能和稳定性。无论是建立TCP连接,还是客户端和服务端一来一往地传数据,时间控制策略用得好不好,差别很大。



TCP连接中的超时与重复请求



先看一个典型的连接场景。客户端A给服务端发连接请求,结果网络一堵,请求超时了。TCP协议会触发超时重传,再发一个请求B。巧的是,请求B顺利到了服务端,数据也传完了,连接也关了,这时候请求A才慢悠悠地到达接收端。服务端一看,哟,新连接来了,进入ESTABLISHED状态等数据,结果客户端早就关闭了。服务端只能空等着,白白消耗资源。

数据传输中也会出这种幺蛾子。客户端发了第一个连接请求,没收到确认,于是又发了一个。等数据传输完、连接关掉之后,第一个“迟到”的请求才到服务器。服务端可不知道这请求已经过时了,照样为它建立连接,资源就这么浪费了。



为了解决这个问题,TCP协议引入了MSL机制。MSL就是报文段的最大生存时间。服务端重发FIN报文后,如果客户端在MSL时间内还没收到确认,服务端就继续重试,一直等到连接超时断开为止。这样一来,后面新建立的连接就不会被那些“幽灵请求”扰乱了。

轮询策略的演进



说完TCP,再来看看另一个常见场景:怎么实时获取数据。这时候轮询就派上用场了。



短轮询最简单,客户端每隔固定时间向服务端发个请求,服务端返回当前数据。实现起来确实方便,但问题也很明显:大部分请求发出去的时候数据其实没更新,等于白跑一趟,服务器资源浪费严重。而且用户看到的数据总有延迟,实时性不好。

长轮询是短轮询的改进版。客户端发了请求后,服务端不急着返回,把请求先挂着,等到数据真正更新了或者连接超时了才响应。客户端一收到回复,马上发起下一个请求。这样一来,无效请求确实少了很多。但每个请求还是得建立、关闭连接,频繁地创建和销毁连接同样是开销。

长连接更彻底一些。第一次请求时建立连接,之后的请求和响应直接在这个连接上传输,省掉了反复建连的过程。短连接适合请求不太频繁的场景,比如普通网页浏览;长连接则适合客户端和服务端需要频繁交互的情况,像实时聊天室、在线游戏这类。

超时配置的门道





说到底,超时该怎么设,这里头有几个关键点。

超时时间不能乱设。等待响应时别无限期死等,定个合理的超时阈值,超时了就直接返回错误,别让线程一直占着不放。

限流也得跟上。根据系统当前的负载能力限制请求数量,超过上限干脆利落地返回失败,别等到系统被压垮了才后悔。

熔断机制同样重要。盯着请求失败的概率,失败率一旦超过阈值,马上触发熔断,让请求快速失败,把系统从崩溃边缘拉回来。

还有一种情况特别容易被忽略。如果某个存储服务器因为网络问题导致成员资格请求经常超时,它实际上已经不可用了,但系统还在傻傻地向它发请求,形成恶性循环。这种情况下,超时后应该重新探测,确认服务器真的不能用,就把它从服务名单里剔除。

核心原则



处理超时,说到底就是在用户体验和系统资源之间找平衡。对延迟敏感的业务,超时时间设短一些,能更快触发重试;做重试策略时要小心,别重试没做成,反倒把应用线程给阻塞住了,一样是浪费。

还要分清超时的原因。网络抖动引起的临时超时,和服务器真的扛不住了的处理方式完全不同。前者可以重试试试,后者就应该赶紧切换到备用节点,别在一棵树上吊死。

把超时配置和重试策略设计好,既能保证系统可用,又能把无效的资源消耗降到最低,分布式系统才能真正稳得住。