因为要完成一个聊天的项目,所以借鉴了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. jQuery控制网页字体大小和肤色

    在一些网站上经常看到有控制网页肤色和字体大小的功能,接下来,我们将用两个例子来实现这两个功能. 网页字体大小 首先我们在网页中添加一些被控制大小的文字和字体控制的按钮. <!DOCTYPE> ...

  2. Linux下几种反弹Shell方法的总结与理解

    之前在网上看到很多师傅们总结的linux反弹shell的一些方法,为了更熟练的去运用这些技术,于是自己花精力查了很多资料去理解这些命令的含义,将研究的成果记录在这里,所谓的反弹shell,指的是我们在 ...

  3. CentOS 6.6下安装配置Tomcat环境

    本文转载至:http://www.linuxidc.com/Linux/2015-08/122234.htm 实验系统:CentOS 6.6_x86_64 实验前提:防火墙和selinux都关闭 实验 ...

  4. Linux常用命令收藏

    常见操作: 快速清空文件内容的几种方法:#: > filename # > filename # echo "" > filename # echo > f ...

  5. 第3章 文件I/O(4)_dup、dup2、fcntl和ioctl函数

    5. 其它I/O系统调用 (1)dup和dup2函数 头文件 #include<unistd.h> 函数 int dup(int oldfd); int dup2(int oldfd, i ...

  6. Oracle 11g trace events

    oracle的events,是我们在做自己的软件系统时可以借鉴的 Oracle 11g trace eventsORA-10001: control file crash event1ORA-1000 ...

  7. php parse_str() 函数

    php parse_str() 函数把查询字符串解析到变量中,主要用于页面之间传值(参数).本文章向码农介绍php parse_str() 函数的使用方法,感兴趣的码农可以参考一下. 定义和用法 pa ...

  8. 提高solr的搜索速度

    之前是使用12台机分布式搜索,1台为主机做索引并分发给子机,8台做大索引搜索服务,3 台做小索引搜索服务,配置基本是内存在4-8G,cpu:2-8core的服务器,索引的大小为8G.搜索的响应时间 是 ...

  9. rhel7配置ELK过程

    参考网站:https://www.cnblogs.com/hongdada/p/7887455.html https://my.oschina.net/codingcloud/blog/1615013 ...

  10. springsource-tool-suite插件各个历史版本

    转自:https://blog.csdn.net/zhen_6137/article/details/79384798 目前spring官网(http://spring.io/tools/sts/al ...