Yihui’s Blog

建立连接后,若客户端突然出现故障,服务端会如何处理?

日期:2026-09-27
标签:#面试 #场景设计 #计算机网络
难度:中等
来源:牛面场景题
答案说明:独立整理(站内题目标记为 VIP,未读取会员答案)

一句话答案

客户端故障不等于服务端立刻收到断开通知;服务端依赖 FIN/RST、后续读写失败、TCP 保活或应用心跳与超时发现连接失效,再清理连接和业务状态。

面试口语版(约 60 秒)

“我会先区分故障类型。如果客户端正常关闭,服务端读到 FIN,read 返回 EOF,可以按协议收尾;如果进程崩溃且操作系统仍能处理连接,可能收到 RST。若机器断电或网络黑洞,服务端可能长期保留一个看似已建立的连接,尤其在双方都不发数据时。服务端再次发送数据后,TCP 会重传并最终超时;开启 TCP keepalive 可以探测长时间空闲的对端,但探测周期通常不适合作为唯一业务故障判定。在线聊天这类场景我会加带序号的应用心跳和读空闲超时,连续漏掉阈值后断开会话、释放连接与订阅,同时让客户端重连时用会话令牌恢复。注意网络超时只说明‘当前不可达’,不能绝对证明对方已经死亡,断线重连后的消息要考虑去重。”

原理与场景拆解

情况服务端常见观察处理
客户端有序关闭收到 FIN,读返回 0/EOF;写方向可能尚未关闭按半关闭语义完成待发送数据或主动关闭
进程退出、连接被重置可能收到 RST,读写报错;具体时点取决于系统行为清理 socket、会话和未完成请求
断电、断网、NAT 状态丢失暂时无报文,服务端可能毫无感知读写超时、保活探测或应用心跳后回收
flowchart LR
  A[客户端故障] --> B{服务端收到报文?}
  B -->|FIN 或 RST| C[读写事件暴露故障]
  B -->|无报文| D[连接暂时仍显示 ESTABLISHED]
  D --> E[读写超时或探测超时]
  C --> F[清理连接与业务状态]
  E --> F

例子: WebSocket 在线状态不能只凭 TCP 连接表。服务端每 15 秒发一次心跳,允许连续数次缺失后标记离线,并给重连留短暂宽限期;具体阈值由移动网络抖动、在线状态时效与资源成本决定。清理时还要取消订阅、超时中的 RPC 和连接关联的内存对象。

关键细节与常见误区

  • TCP 本身不会因应用进程“心跳停止”自动立即关闭连接。RFC 9293 将对端无感知的关闭或重启列为半开连接;后续通信可能触发 RST。
  • TCP keepalive 是可选机制,其参数由操作系统和应用配置;单次探测无回应不能直接判死。应用心跳可同时携带业务会话状态,但会增加流量与连接负载。
  • read 阻塞不代表对端还活着;要设置合理的读空闲/请求超时。write 成功也只说明数据交给本机协议栈,不能证明业务端已处理。
  • 超时后关闭 socket 只是本地决定;重试请求可能与客户端之前成功但未收到确认的请求重叠,需要请求 ID 和幂等处理。

面试官递进追问

  1. FIN、RST 和没有任何报文时,服务端分别会看到什么?
  2. TCP keepalive 与应用层心跳各解决什么问题,阈值如何设?
  3. 客户端重连后重复提交了上一次超时的支付请求,如何判断和处理?

自测与学习清单

  • 不看笔记,用 60 秒分别说明“进程崩溃”和“网络黑洞”两条路径。
  • 画出心跳超时、会话清理、客户端重连和幂等重放的顺序。
  • 用故障注入验证读写错误、连接回收时间和误判率,观察连接数、心跳超时率、重连率。

参考资料

维护与整理 · Yihui在 GitHub 上编辑

继续阅读

浏览全部文章

如何为Redis分布式锁设置合理的超时时间?

日期:2026-09-27 标签:#面试 #场景设计 #Redis 难度:中等 来源:牛面场景题 答案说明:独立整理(站内题目标记为 VIP,未读取会员答案) 一句话答案 租约应覆盖可预期的执行、暂停与网络抖动,同时限制故障后的等待;没有可靠耗时上界时用有身份校验的受控续期,并在业务资源侧防止旧执行者写入。 面试…

阅读全文

怎么用Redis实现可重入的分布式锁?

日期:2026-09-27 标签:#面试 #场景设计 #Redis 难度:中等 来源:牛面场景题 答案说明:独立整理(站内题目标记为 VIP,未读取会员答案) 一句话答案 为同一把锁保存“本次最外层获锁的唯一令牌 + 重入次数 + 租约”;嵌套调用共享该令牌并原子递增,释放时递减,次数归零才删除。新一轮独立获锁必…

阅读全文

基于 Redis 实现分布式锁有什么优缺点?

日期:2026-09-27 标签:#面试 #场景设计 #Redis 难度:简单 来源:牛面场景题 答案说明:独立整理(站内题目标记为 VIP,未读取会员答案) 一句话答案 Redis 锁接入简单、响应快,适合容忍少量故障窗口内重复执行的任务;租约过期与主从切换可能破坏互斥,关键写入还须在资源侧拒绝旧持有者。 面试…

阅读全文