Skip to content
/ cinx Public

基于 Go 语言开发的轻量级TCP长连接并发服务器框架。

Notifications You must be signed in to change notification settings

Cai-ki/cinx

Repository files navigation

cinx

基于 Go 语言开发的轻量级TCP长连接并发服务器框架。

  • 并发处理模型:采用协程池与任务队列结合的设计,分离读写协程实现 I/O 与业务逻辑并发处理,支持万级并发连接。
  • 高效传输协议:基于 TLV 格式的二进制协议实现,有效解决 TCP 粘包/拆包问题。
  • 架构设计:服务器状态管理、连接管理器、可扩展协议接口。
  • 场景组件:心跳检测与断线重连机制。

架构图

代码开发中的问题与解决方案

  1. 客户端初始化与发送逻辑顺序问题

    现象 :测试时客户端未完成初始化即执行发送逻辑,引发空指针异常。

    问题本质 :协程调度顺序不确定导致:

    • 连接未初始化完成
    • 发送逻辑提前执行

    解决方案 :

    • 引入 ready 管道同步协程
    • 调整关键协程启动顺序
    • 非关键路径保留并发

    经验总结:

    • 执行并发逻辑需确保依赖实例初始化完整
  2. 高并发场景下的服务端稳定性问题

    现象 :压力测试时端口耗尽导致客户端断连,服务端崩溃。

    问题本质 :

    • 连接异常处理机制缺陷
    • 并发协程资源竞争
    • 任务执行完整性不足

    改进方案 :

    • 状态管理 :

      • 原子变量标记连接状态

      • sync.WaitGroup 跟踪任务

    • 执行流程优化 :

      reader异常 -> 设置关闭状态 -> stop流程 -> wg.Wait -> workpool处理遗留任务 -> writer尽力发送 -> wg.Done -> 清理资源
      
    • 容错设计 :

      • 任务提交不检查连接状态
      • 写协程统一处理异常
      • 提供用户级熔断接口
    • 性能考量 :

      • "尽力而为"处理异常任务
      • 优雅关闭分阶段执行(停读 -> 停写 -> 清理)

    经验总结:

    • 资源释放需保证执行完整性
  3. 服务端异步启动后 stop 在大量并发连接下的死锁问题

    现象:服务端在异步启动后调用 Stop 方法时,面对大量并发连接场景,程序因死锁异常退出。

    问题本质 :

    • 锁竞争与链式调用 :

      • 原connmanager模块使用sync.Mutex保护连接集合(map),Stop操作需遍历所有连并逐个调用conn.Stop()。

      • conn.Stop()内部可能再次申请锁(如连接自身的状态锁),导致嵌套锁竞争 。

      • 当connmanager的锁未释放时,调用conn.Stop()可能因等待连接内部锁而阻塞,形成死锁链。

    • 资源清理顺序缺陷 :

      • 未明确资源释放的优先级,导致连接关闭时可能仍在处理旧任务或接收新请求。

    解决方案 :

    • 数据结构优化 :
      • 替换为sync.Map : 将连接集合从普通map+Mutex替换为sync.Map,利用其无锁并发特性,避免遍历时的锁竞争。
      • 原子状态管理 : 使用atomic包标记服务端状态,确保状态变更的原子性,避免竞态。

    经验总结 :

    • 避免嵌套锁 :优先使用并发安全的数据结构(如sync.Map)减少锁粒度。
    • 资源生命周期管理 :明确资源创建、使用、销毁的顺序,避免循环依赖。
    • 优雅退出设计 :
      • 分阶段关闭(先停读,再停写,最后清理)。
      • 通过原子状态和WaitGroup确保执行完整性。
    • 压测验证必要性 :高并发场景必须通过压力测试暴露隐藏的竞态和死锁问题。

About

基于 Go 语言开发的轻量级TCP长连接并发服务器框架。

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages