因为要完成一个聊天的项目,所以借鉴了goim,第一篇分析打算半原版,先摘抄http://www.jianshu.com/p/8bd96a9a473d他的一些理解,写这些还是为了让自己更好的理解这个项目,如果有什么不对的,请大家给我留言。

Comet 角色定位

GOIM整体架构

在整个架构中,系统被分成 Comet, Logic, Job, Router 四大模块,各个模块通过 RPC 通信,参考官方中文文档,Comet 程序是连接层,暴露给公网,所有的业务处理推给 Logic 模块,通过 RPC 通信。这样设计的好处在于,长连接逻辑很少变动,稳定的保持公网连接,而后端 Logic, Router 模块经常变动,重启不会影响连接层。

几个重要的结构体

做为典型代码即注释的开源项目,goim 基本无太多阅读障碍,几个逻辑点梳理下很快就会明白。

Bucket: 每个 Comet 程序拥有若干个 Bucket, 可以理解为 Session Management, 保存着当前 Comet 服务于哪些 Room 和 Channel. 长连接具体分布在哪个 Bucket 上呢?根据 SubKey 一致性 Hash 来选择。

Room: 可以理解为房间,群组或是一个 Group. 这个房间内维护 N 个 Channel, 即长连接用户。在该 Room 内广播消息,会发送给房间内的所有 Channel.

Channel: 维护一个长连接用户,只能对应一个 Room. 推送的消息可以在 Room 内广播,也可以推送到指定的 Channel.

Proto: 消息结构体,存放版本号,操作类型,消息序号和消息体。

多协议支持

Goim 支持 Tcp, Http, WebSocket, TLS WebSocket. 非常强大,底层原理一样,下面的分析都是基于 Tcp 协议。

Bucket

先来看看结构体的定义

Bucket结构体

定义很明了,维护当前消息通道和房间的信息,方法也很简单,加减 Channel 和 Room. 一个 Comet Server 默认开启 1024 Bucket, 这样做的好处是减少锁 ( Bucket.cLock ) 争用,在大并发业务上尤其明显。最新的版本增加了routineamout,routinesize这两个选项主要是用来做progress推送消息的作用,第一个是做消息推送协程个数,第二个是管道长度。比旧版buket取消了以前的roomoptions直接使用room的参数

Room

Room结构体

Room 结构体稍显复杂一些,不但要维护所属的消息通道 Channel, 还要消息广播的合并写,即 Batch Write,
如果不合并写,每来一个小的消息都通过长连接写出去,系统 Syscall 调用的开销会非常大,Pprof 的时候会看到网络 Syscall
是大头。新版本room改动很大,以前这么同学说辞不知道是否管用,但是从结构体定义来看,room增加了下个channel和一个在线状态。

消息广播

Logic Server 通过 RPC 调用,将广播的消息发给 Room.Push,  数据会被暂存在proto这个结构体 里,每个 Room 在初始化时会开启一个 groutine 用来处理暂存的消息,达到 Batch Num
数量或是延迟一定时间后,将消息批量 Push 到 Channel 消息通道。

Channel

Channel结构体

这是一个通道。Writer/Reader 就是对网络 Conn 的封装,cliProto 是一个 Ring Buffer,保存 Room 广播或是直接发送过来的消息体。

消息流转

这里只分析 Comet 代码,所以消息生成暂时不提

1. Client 连接到 Comet Server,  握手认证

2. 新建当前长连接的 Channel, 由于 Comet 服务不处理业务逻辑,需要 RPC 去 Logic Server 获取该
Channel 的订阅信息。同时 Channel 开启一个 dispatchTCP groutine, 阻塞等待 Ring Buffer
数据可用,发送到 Client。

3. Logic 服务通过 RPC, 将消息写到 Room (广播)或是直接写到指定 Channel (单播)。注意这里,广播是有写合并 BatchWrite, 而单播没有,消息生成后立刻发送。

4. Room 里的广播消息到达一定数量 Batch Num, 或是延迟等待一定时间后,将消息写到 Channel Ring Buffer。

小结

新版本跟以前那位同学的很不一样,第一版本由于时间关系,基本大多数是摘抄这位同学的,感觉新版本很多不对,但是阅读代码还没到那个程度,所以第一版就到这里,这位同学对goim大体架子分析的很清楚,细节在我后续章节会有,如果有不对的,请及时留言纠正

补充-来自毛剑

1. bucket按照key的cityhash求余命中的,没有用一致性hash,因为这里不涉及迁移

2. 私信发送其实也有合并的,和room合并不同的是,在ringbuffer取消息饥饿时候才会真正flush

3. 还有一个优化可以改进,因为room有个特点大家消息可能都一样,所以在room提前合并成字节buffer,然后广播所有人,避免每个人都序列化一次,然后利用gc来处理这个buffer的释放,这样可以节省大量cpu,目前这个优化还没做

goim源码分析与二次开发-comet分析一的更多相关文章

  1. goim源码分析与二次开发-comet分析二

    这篇就是完全原版了,作为一个开始,先介绍comet入口文件main.go 第一步是初始化配置,还有白名单.还有性能监口,整体来说入口代码简洁可读性很强 然后开始初始化监控,还有bukcet这里buck ...

  2. JMeter5.4.1源码IDEA构建&二次开发(实战)

    JMeter5.4.1源码IDEA构建&二次开发(实战) 目录 JMeter5.4.1源码IDEA构建&二次开发(实战) 1.下载源码 2.导入IDEA 2.1 先设置Gradle目录 ...

  3. [大数据可视化]-saiku的源码打包运行/二次开发构建

    Saiku构建好之后,会将项目的各个模块达成jar包,整个项目也会打成war包 saiku目录结构:   我们选中saiku-server/target/ 下面的zip压缩包.这是个打包后的文件,进行 ...

  4. 【流媒体开发】VLC Media Player - Android 平台源码编译 与 二次开发详解 (提供详细800M下载好的编译源码及eclipse可调试播放器源码下载)

    作者 : 韩曙亮  博客地址 : http://blog.csdn.net/shulianghan/article/details/42707293 转载请注明出处 : http://blog.csd ...

  5. 超强在线考试系统源码(私有部署&二次开发)

    随着信息化技术的发展,考试系统也在进行着深入的变革.从传统的纸质考试人工评分到现在的在线考试自动评分. 在线考试系统的应用场景也在逐渐扩宽,例如:学校的学生考试.员工培训考试.招聘考试.职称考试等等. ...

  6. QGIS源码解析和二次开发

    使用Python 开发一个交通系统? 不如基于GeoServer来开发更能产生效益 QGIS3d:https://blog.csdn.net/shi_weihappy/article/details/ ...

  7. Openfire开发配置,Openfire源码配置,OpenFire二次开发配置

    1.下载源码:http://www.igniterealtime.org/downloads/source.jsp 2.把源码解压出的openfire_src目录放至eclipse workplace ...

  8. # Volley源码解析(二) 没有缓存的情况下直接走网络请求源码分析#

    Volley源码解析(二) 没有缓存的情况下直接走网络请求源码分析 Volley源码一共40多个类和接口.除去一些工具类的实现,核心代码只有20多个类.所以相对来说分析起来没有那么吃力.但是要想分析透 ...

  9. Spring源码分析之IOC的三种常见用法及源码实现(二)

    Spring源码分析之IOC的三种常见用法及源码实现(二) 回顾上文 我们研究的是 AnnotationConfigApplicationContext annotationConfigApplica ...

随机推荐

  1. hdu 1966 Pie

    Pie Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submiss ...

  2. Linux下的压缩(zip)解压(unzip)缩命令

      .zip命令 zip -r myfile.zip ./* 将当前目录下的所有文件和文件夹全部压缩成myfile.zip文件,-r表示递归压缩子目录下所有文件. 2.unzip命令 unzip -o ...

  3. 部署mariadb高可用

    上传文件到opt目录下 Galera能够实现MySQL/MariaDB数据库的主主复制和多主复制等模式,这些复制模式都是同步进行的,同步时间非常短. 每一个节点都可以同时写入和读取,当某一节点发生故障 ...

  4. Linux命令详解-文件系统管理

    1. 外部设备简介 (1.)硬盘的分类: IDE硬盘 ./dev/hda   hdb,hdc…  分区后:/dev/hda1  /dev/hda2 scsi硬盘: /dev/sda   sdb,sdc ...

  5. stm32串口接收完整的数据包

    参考了文章:<stm32串口中断接收方式详细比较> 文章地址:http://bbs.elecfans.com/jishu_357017_1_1.html 借鉴了第四种中断方式 串口的配置这 ...

  6. 写了个TP5下PHP和手机端通信的API接口校验

    写了个PHP和手机端通信的API接口校验 直接发函数吧 public function _initialize() { //定义密码和盐 $password="123456"; $ ...

  7. checkbox的美化(转)

    http://www.w3cfuns.com/blog-5422889-5398674.html <!DOCTYPE html> <html> <head> < ...

  8. HTML5 Canvas ( 图形变换矩阵 ) transform, setTransform

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  9. css之单边阴影

    css之单边阴影 需求:在网上找的其他博客上说单边阴影需要牺牲掉模糊,实际上牺牲掉模糊直接用border不就好了 效果: 原理: 1.在左边的外阴影就是右边的内阴影 2.将box-shadow写在be ...

  10. word自动生成章节标题

    一级目录 二级目录 三级标题