# websocket **Repository Path**: goeoeo/websocket ## Basic Information - **Project Name**: websocket - **Description**: websocket学习 - **Primary Language**: Go - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 1 - **Created**: 2023-12-25 - **Last Updated**: 2024-01-05 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 拉模式与推模式的区别 ## 拉模式 * 数据更新频率低,则大多数请求是无效的 * 在线的用户数量多,则服务端的查询负载很高 * 定时轮询拉取,无法满足时效性要求 ## 推模式 * 仅在数据更新时需要推送 * 需要维护大量的在线长连接 * 数据更新后可以立即推送 # websocket协议 ## 优点 * 浏览器支持的socket编程,轻松维持服务端的长连接 * 基于TCP可靠传输之上的协议,无需开发者关心通信细节 * 提供了高度抽象的编程接口,业务开发成本比较低 ## websocket协议与交互 ### 通讯流程 ![](README/img.png) ### 传输原理 * 协议升级后,继续复用HTTP的底层socket完成后续通讯 * message 被底层切分成多个frame帧传输 * 编程时只需要操作message,无需关心frame * 框架底层完成TCP网络I/O,websocket协议解析,开发者无需关心 # 服务端的技术选型和考虑 * nodejs 单线程模型,推送性能有限 * C/C++ TCP通讯,websocket协议实现成本高 * GO 多线程,基于协程模型并发,成熟的websocket标准库,无需造轮子 # go语言实现websocket服务端 ## 实现HTTP服务端 * websocket是HTTP协议Upgrade而来 * 使用http标准库快速实现空接口:/ws # 千万级弹幕系统的架构秘密 ## 分析技术难点 ### 内核瓶颈 * 推送量大:100完在线*10条/秒=1000万条/秒 * 内核瓶颈:linux内核发送tcp的极限包帧 约等于 100万/秒 ### 锁瓶颈 * 需要维护在线用户集合(100完用户在线),通常是一个字段结构 * 推送消息即遍历整个集合,顺序发送消息,耗时极长 * 推送期间,客户端仍旧正常上下线,所以集合需要上锁 ### cpu瓶颈 * 浏览器与服务端通常采用json格式通讯 * json编码非常耗费cpu资源 * 向100万在线推送1次,则需要100完次json encode ## 技术难点的解决方案 ### 内核瓶颈优化 * 减少网络小包的发送 * 将统一秒内的N条消息,合并成1条消息 * 合并后,每秒推送次数只等于在线连接数 ### 锁瓶颈优化 * 连接打散到多个集合中,每个集合有自己的锁 * 多线程并发推送多个集合,避免锁竞争 * 读写锁取代互斥锁,多个推送任务可以并发遍历相同集合 ### CPU瓶颈优化 * 减少重复计算 * json编码前置,1次消息编码+100万次推送 * 消息合并前置,N条消息合并后只编码1次 # 架构 ## 单机架构 ![](README/img_1.png) * 维护海量长连接需要花费不少内存 * 消息推送瞬时消耗大量cpu资源 * 消息推送瞬时带宽高达400MB-600MB(4-6Gbits),是主要瓶颈 > 服务器通常是前兆网卡,如果要跑到400MB-600MB 需要万兆网卡 ## 分布式架构 ### 逻辑集群 * 基于HTTP2 协议向gateway集群分发消息 (HTTP2支持连接复用,用作RPC性能更加) * 基于HTTP1 协议对外提供推送API(HTTP1更加普及,对业务方更加友好) ![](README/img_2.png) # 总结 ## 技术 * 生产工具,就像斧子和铲子一样 * 开发语言,框架都是技术,努力学习大多可以掌握 ## 思想 * 来自于常年累月对技术的积累和理解 * 合理的设计,架构经验,来自于不断的技术实践和总结 ## 精神 * 不在局限于特定的技术体系与思想体系 * 凭借直觉,能够快速抓住问题的本质,在众多纷扰中作出正确的选择