【原创】开源OpenIM:轻量、高效、实时、可靠、低成本的消息模型

1、内容概述

一套完整IM系统中,除开基本的业务设计,消息模型的设计是其中最为关键的一环,它关系到整个IM系统的可靠性、高效性、稳定性,因此需要设计一套合理的消息传递收发机制以承载IM的各种需求,OpenIM结合具体的业务场景,提炼出IM后端的重要接口,并经过反复推敲,验证,设计出了自己的一套通信协议OMTP,协议中每个字段尽量的减少冗余,使其精简高效、最大限度的满足现有的业务需求并能够支持业务的水平拓展,同时为了达到消息的实时可靠与高效,消息模型也经过了精心设计。

(1)消息的实时性:消息的实时性是考验IM系统的重要标准,传统的IM通过http长短轮询的方式来模拟实时消息,存在“实时性盲区”,所以OpenIM也同样使用了HTML5的Websocket技术,Websocket是真正的全双工双向通信技术,能够实现服务器主动推送消息到客户端,实现真正的实时双向通信(服务器通知客户端有信息到达,客户端随时向服务器发送新消息),一次连接,随时都可以使用,不用像轮询技术中不断使用http请求,这样降低了服务器的负载,并减少一些高频无用的请求。

(2)消息的可靠性:消息的可靠性,是指消息的不丢失,不重复,由于网络环境的各种复杂情况,包括数据在到达客户端后,数据需要进行各种解析与处理,包括写入db,存入cache,UI的各种展现等等,而且还包括客户端的各种异常情况,当项目越庞大时候,应用层出现错误的可能性会更高,都可能会造成消息的丢失,通常为了使得消息更为可靠,业务层通常采取的方案有:1、在应用层增加ACK消息,这种方案可以理解为模拟TCP的流程去保证消息的可靠性,server发送数据到达客户端后,客户端处理完毕(通常是保证数据已经存入db中)会向server发送一条ACK消息确认自己已经收到了消息,当server收到ACK消息后才确认消息已经成功交付,否则就会使用某种策略进行消息的重发;这个方案也会出现如果ACK消息发送后,server出于网络的原因没有成功收到,然后server进行了重发消息,客户端会重复的收到了这条消息,所以客户端需要进行去重处理。2、消息增加一条序列号,为每条消息分配一个消息ID(OpenIM便是使用的这种方案),对于每个用户而言,在自己的消息收件箱中,消息的收取队列中seq应该是连续的,如果客户端层面,或者网络原因造成消息没能够实时的到达,客户端可以在应用层增加逻辑采取某种策略通过seq对比,本地的seq和服务器的seq之间的差值去拉取没能正确交付到客户端的消息,这种方案相比于ACK消息来说,不用每一条消息都需要server判定ACK来确认消息是否已经到达客户端,消息的获取获取逻辑更加简单,但是消息的拉取依赖于客户端,如果pull拉取频率过于高,其流量的损耗的也是不低的,所以OpenIM在客户端断网重连,消息拉取策略上做了优化处理以确保消息拉取频率在一个合适的范围。

(3)兼具轻量、高效、低成本:OpenIM设计之初,便是以“一切从简”的原则出发,去除了一些不必要、不合理的设计,使得整个消息通道更加简洁,系统更加轻量级,系统设计使用的是微服务架构方式,每个节点都能够支持集群部署,各个节点之间通过注册中心互连,在集群模式下能够自动的进行负载均衡与流量切换,并且消息通道提供了给应用服务器回调接口,方便应用服务器对于消息的控制,方便其他应用能够高效的接入OpenIM并拓展自己的业务,由于OpenIM是一个开源系统,任何企业和个人都能免费获取源码,并自行构建OpenIM服务,快速搭建私有IM服务器,并迅速让IM功能集成到自己的系统中,数据自我掌握,不用依赖于他人,相比云服务商,极大的降低了获取IM能力所需要的成本。

服务器层面从消息发送到接收的流程大致可以分为两个阶段:

客户端发送消息到服务器阶段

服务器传输消息到客户端阶段

2、消息发送阶段模型图:

OpenIM消息的发送阶段,也就是消息服务的上行阶段,流程如下:

(1)主要由客户端主动发送消息到服务器,目前所支持的应用层协议主要是http和websocket,为了应对不同客户端的需求,我们在消息网关接口中分别设置了https和wss的接口来作为OpenIM的网关接入层。

(2)接口层依赖于ETCD集群(用于RPC服务的注册和发现)调用RPC共同调用消息处理单元,处理单元处理完毕后将消息放入MQ中,并返回给客户端相应结果,消息只要成功落入MQ中,就可以视为发送成功,消息发送的可靠性依赖于MQ集群。

(3)值得一提的是,在消息的处理单元,我们增加了外部调用接口(由具体的业务服务器实现的http接口),可以实现业务服务器对消息的控制处理,例如消息的禁止发送,过滤等具体的业务需求,这种消息的回调业务服务器的设定方便使用者可以根据自己的业务需求对消息进行处理,设立在服务器回调这种方式也更加安全可靠,可见在OpenIM的上行消息发送阶段,我们通过ACK、集群化部署等方式,来保证消息的发送中数据传输的可靠性。

3、消息传输阶段模型图:

OpenIM消息的传输阶段(包括将消息交付到接收者客户端或发送者的其他客户端),即是消息服务的下行阶段,流程如下:

(1)上游将拆分处理后的消息放入MQ中,传输阶段主要的任务,是从MQ中拿到消息,并进行持久化存储以及交付push模块。

(2)在消息的存储方面,我们所使用的是收件箱模式,即每个用户都带一个信箱,一条消息发送后,发送者和接收者的信箱都会增加一条信息,这种写扩散的的方式将写进行了放大,它的优点是,对于客户端而言,无论是直接接收数据,还是主动拉取数据逻辑都比较简单,直接获取自己收件箱里面所有的消息,我们主要使用Redis存储消息的seq(每一条消息对于接收者和发送者都会产生一个唯一的递增的消息序列号),使用MongoDB存储历史消息(用户直接拉取的消息),MySQL存储全量的历史消息(漫游消息)。

(3)消息异步交付持久层后,通过RPC调用push模块,为了增加消息的可靠性,我们使用了RPC+MQ双向保证消息推送的到达,当RPC直接调用失败后,会通过MQ中转消息到达push模块。

(4)push模块主要的任务是负责消息的传递(包括接收者多端收到消息,以及发送者多端的消息同步等),主要是通过将从RPC接口中或MQ中获取的消息通过接入网关使用websocket进行消息的在线推送,当用户不在线时,调用三方的离线推送确保消息能够到达客户端。

在本文中主要阐述了OpenIM的特点和在服务器层面上的消息模型架构设计,方便开发者对后端消息的整个流程有一个清晰的认识,在后续的文章中,我们会继续讲解OpenIM客户端层面的消息的架构设计。

源链接: 

OpenIM官方论坛

OpenIM官网

更多技术文章:

开源OpenIM:高性能、可伸缩、易扩展的即时通讯架构

【OpenIM原创】简单轻松入门 一文讲解WebRTC实现1对1音视频通信原理

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,332评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,508评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,812评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,607评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,728评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,919评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,071评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,802评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,256评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,576评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,712评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,389评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,032评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,026评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,473评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,606评论 2 350

推荐阅读更多精彩内容

  • 本文属于OpenIM技术团队原创,转载请注明出处,谢谢 网上有很多关于IM的教程和技术博文,有亿级用户的IM架构,...
    OpenIM阅读 1,186评论 0 2
  • 这个项目可以理解为针对互联网IT人打造的中文版awesome-go。已有的awesome-go项目, 汇总了很多g...
    零一间阅读 2,668评论 0 5
  • 我是黑夜里大雨纷飞的人啊 1 “又到一年六月,有人笑有人哭,有人欢乐有人忧愁,有人惊喜有人失落,有的觉得收获满满有...
    陌忘宇阅读 8,531评论 28 53
  • 人工智能是什么?什么是人工智能?人工智能是未来发展的必然趋势吗?以后人工智能技术真的能达到电影里机器人的智能水平吗...
    ZLLZ阅读 3,767评论 0 5
  • 首先介绍下自己的背景: 我11年左右入市到现在,也差不多有4年时间,看过一些关于股票投资的书籍,对于巴菲特等股神的...
    瞎投资阅读 5,708评论 3 8