如何设计一款高性能、高并发、高可用的im综合消息平台是很多公司发展过程中会碰到且必须要解决的问题。比如一家公司内部的通讯系统、各个互联网平台的客服咨询系统,都是离不开一款好用且维护的方便im综合消息系统。

那么,我们应该怎么样来设计一款三高特性的im系统,并能同时支持各个业务线的接入(比如:内部OA通讯、客服咨询、消息推送等等功能)有呢?

im第一版设计的初衷是公司需要一款im消息中间件用于支撑客服咨询业务。

但是,考虑到为了方便日后其他业务线也能接入消息沟通平台,所以一开始就将整个消息中心的能力需求给到中间件团队进行开发,以便除客服外的各业务线接入综合消息中心,从而实现多元的消息实时触达能力。

我们逐个解释一下各模块的作用。

1)存储端:

在初版的架构下,存储端我们使用tidb、redis作为主要存储:

1)redis用于存储消息已读未读,缓存连接信息等功能;
    2)tidb作为开源的分布式数据库,选择它是为了方便消息的存储。

2)mq消息总线:

我们使用rocketmq来实现消息总线(PS:即分布式情况下,不同im实例间通过MQ进行消息交互)。

消息总线是整个im的核心,使用rocketmq能支持十万级别的tps。基本所有服务都要从消息总线中消费消息进行业务处理。

3)zookeeper注册中心:各个服务会注册到zk中,方便服务之间内部进行调用,同样也可以暴露服务给外部进行调用。

4)link服务:

link服务主要用于接收客户端的ws(WebSocket协议)、tcp、udp等协议的连接。

同时调用用户服务进行认证,并投递连接成功的消息给位置服务进行消费,存储连接信息。

ws(WebSocket协议)过来的消息先到link再投递到消息总线。

5)消息分发服务:

消息分发服务主要用于接收消息总线推过来的消息进行处理,按照im内部消息协议构造好消息体后,又推送到消息总线中(比如会推给会话服务、消息盒子、link服务)。

6)位置服务:

存储link的(WebSocket协议)连接、tcp连接等信息,并使用redis进行缓存(key为userId),方便根据UserId查询到该用户所登录的客户端连接在哪个link上。即时通讯聊天软件app开发可以加蔚可云的v:weikeyun24咨询

一个用户在相同设备只能登录一个,但可以支持多端登录。

7)用户服务:用于存储所有用户,提供认证查询接口。

8)消息盒子:存储所有消息,提供消息查询、消息已读未读、消息未读数、消息检索等功能。

9)会话服务:管理会话、群聊会话、单聊会话等功能。

初版IM架构存在的问题及思考

在上节的架构设计介绍中,我们详细分享了初版IM系统架构的设计思路以及具体流程。

那么在初版IM架构设计中还存在什么样的问题,又该如何优化呢?我们一条条来看看。

使用MQ消息总线的问题

正如上节所分享的那样,我们初版IM架构中,link服务到消息分发服务的消息使用的MQ消息总线。

初版架构设计中,link服务将消息下推给消息分发服务进行处理时,使用的是mq消息总线(通俗了说,IM集群内不同IM实例间的通信是依赖于MQ进行的消息传递),而mq消息总线必然做对有一定的时延(而且时延受制于MQ本身的系统实现和技术策略)。

举个例子:
当两个处于不同IM实例的客户端A和B聊天时,A用户发送消息到link --> 消息总线 --> 消息分发服务 --> 消息总线 --> link --> B用户。

正如上面这个例子,im消息投递流程太长了,并且这样也会大大降低系统的吞吐量。

那么为啥微信使用写扩散不是缺陷,而对于我们的IM架构来说确是缺陷呢?

微信的技术特性:

1)微信号称没有存储用户的聊天记录,全是实时推送;
    2)微信聊天记录全部会在我们手机端存储一份,两台手机终端上的聊天记录并不互通,并且互不可见。

我们的IM综合消息中心技术特性:

1)综合消息中心是会有拉取历史聊天记录(服务端拉取)的功能,存储了全量消息;
    2)综合消息中心的客户端,需要支持网页版本。

综上所述:

1)写扩散对微信这样有移动端的富客户端版本的即时通讯产品十分友好,每个消息在消息分发的时候给处于这个会话(单聊,群聊)下的所有用户所在客户端先推送消息,没找到连接就针对这个用户写一个离线缓存消息,那么下次该用户登录进来,可以从缓存中拉取到该消息,并且清掉缓存;
    2)写扩散对于我们这类通用综合消息平台并不友好,由于接入方大部分是网页版的客户端,所以没有缓存消息的能力,浏览器刷新就没有了任何消息,所以需要实时去服务端拉取历史消息。假设我是写扩散,在一个群聊中有五百个用户,针对这五百个用户在这个会话,我需要去写五百条消息,大大的增加了写io,并且还不能写缓存(得写数据库)。

tidb存在不稳定性和事务并发的问题

tidb是目前主流的开源分布式数据库,查询效率高、无需分库分表。

但同样的,tidb存在一些隐藏的问题:

1)tidb在高并发情况下,并发事务会导致事务失败,具体原因不知;
    2)tidb排错成本高,公司很少有tidb专业运维,经常遇到不走索引的情况。

群聊、单聊冗余在同一个服务的问题

在我们初版的IM架构设计中,单聊和群聊是冗余在会话服务中的,并且冗余在同一张表的。

其实单聊、群聊从数据角度来说,还是会有些不同(比如业务属性)虽然都是会话,我们还是需要将这两个服务拆分开,细粒度的服务拆分能更好的把控整体的逻辑。

正如前面两节分享的那样,渐渐的我们发现初版im架构有很大的不足之处。

在生产上暴露出了以下问题:

1)tps没达到预期,吞吐量不能满足公司业务的发展;
    2)使用的存储中间件难以维护(主要是tidb),试错成本高,经常在生产暴露问题,并且速度越来越慢;
    3)消息写扩散没有太大必要,并大大增加了系统io次数(原因见上一节);
    4)一些特性无法支持,比如消息图文检索,消息已读未读。

改版后的各模块情况如下:

1)存储端:存储端我们改用了mysql,针对消息服务单独使用了主从mysql集群(主节点用于写消息、从节点用于消息检索)——;
    2)mq消息总线:与第一版相比没有改动;
    3)link服务:与第一版相比,改动了link服务到消息分发服务的消息推送方式(由MQ总线方式变更为tcp实时推送);
    4)消息分发服务:集成了消息处理能力、路由能力,每台消息分发服务拥有所有link服务的tcp连接;
    5)单聊服务:负责单聊会话的管理能力;
    6)群聊服务:负责群聊会话的管理能力;
    7)用户服务:提供用户认证,登录\注册能力。

IM即时通讯综合消息系统的架构相关推荐

  1. 爱聊天(LoveChat)即时通讯聊天APP系统——技术架构

    爱聊天(LoveChat)即时通讯聊天APP系统--技术架构 公司旗下第三代即时通讯产品 第一代:阿卡信 https://gitee.com/openzaly/akaxin-openzaly 第二代: ...

  2. MobIM仅为开发者提供即时通讯的消息通道服务

    产品概述: MobIM完全免费的即时通讯服务. MobIM仅为开发者提供即时通讯的消息通道服务.MobIM专注于保障通讯的安全稳定可靠,支持开发者使用App的自有用户系统,或第三方用户系统.MobIM ...

  3. 小程序如何集成即构IM实现即时通讯发消息聊天

    之前的文章已经介绍了如何实现Web端的即时通讯IM,为了让大家全面的体验通信互动的快乐. 本文介绍如何使用 ZIM SDK 快速实现实现小程序端的基本的消息收发功能,在微信中实现一个mini版微信,也 ...

  4. 基于springboot+h5+websocket的即时通讯客服系统和百度实时语音转译(语音在线识别)

    本文章由本人原创 下载链接:https://download.csdn.net/download/u014191624/51948075 这是一个基于springboot+h5+websocket的即 ...

  5. 分布式发布订阅消息系统 Kafka 架构设计 - 目前见到的最好的Kafka中文文章

    转自:http://www.oschina.net/translate/kafka-design 参与翻译(4人):fbm, 飞翔的猴子, Khiyuan, nesteaa 感谢这些同志们的辛勤工作, ...

  6. 教你微信IM即时消息系统的架构设计

    1 用户视图的IM IM系统组成 用户账号 聊天的参与需要用户,所以需要有一个用户账号,用来给用户提供唯一标识,以及头像.昵称等可供设置的选项 账号关系 账号之间通过某些方式(比如加好友.互关等)构成 ...

  7. Web端即时通讯、消息推送的实现

    在浏览某些网页的时候,例如 WebQQ.京东在线客服服务.CSDN私信消息等类似的情况下,我们可以在网页上进行在线聊天,或者即时消息的收取与回复,可见,这种功能的需求由来已久,并且应用广泛. 网上关于 ...

  8. #即时通讯#实现消息已读回执功能的思路与实现

    最近项目的聊天模块中增加了一个消息已读回执的功能,从技术上不是很难实现,但还是在这里记录一下,以便以后查阅. 所谓的消息已读回执,就是双方聊天时,如果对方看到了你新发的信息,这条消息在你这端就会标为& ...

  9. 基于asp.net的最新版即时通讯聊天室系统

    网络聊天是互联网应用过程中出现的一种新的社会活动,上网者通过同一网络聊天软件, 与分布在不同地方的人进行文字.语音或者声像形式的信息沟通.作为一种现代的实时网络 通信方式, 网络聊天以其快速.低成本. ...

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

    本文属于OpenIM技术团队原创,转载请注明出处,谢谢 网上有很多关于IM的教程和技术博文,有亿级用户的IM架构,有各种浅谈原创自研IM架构,也有微信技术团队分享的技术文章,有些开发者想根据这些资料自 ...

最新文章

  1. java8u211_jre864位u211
  2. 大脑如何编码视觉信息?动态电极到图像(DETI) 映射技术也许有助于我们揭示其原理...
  3. 为什么黑客用python-为什么如此多的黑客都用python?
  4. linux之创建临时文件的方法
  5. Surrounded Regions
  6. python面向编程:类继承、继承案例、单继承下属性查找、super方法
  7. html52D转换3D,CSS3 Transform 2D和3D转换
  8. 【论文学习】Bringing Old Photos Back to Life
  9. while循环random结合_Java 经典算法:二分法查找(循环和递归两种方式实现)
  10. Android开发笔记(一)像素的单位
  11. ashx实现ajax功能遇到的浏览器缓存问题
  12. 【比赛经验】ALL in BERT:一套操作冲进排行榜首页
  13. 2012-1-31学习日记
  14. docker学习3-虚拟网络模式
  15. oracle unused 语法_【转】Oracle set unused的用法
  16. 空间计量经济学 matlab,空间计量经济学基于MATLAB的应用分析
  17. 谁谋杀了我们的游戏?转自 斗战神制作人-Yocar
  18. 文本比较算法剖析(1)-如何确定最大匹配率
  19. h5中的图片点击放大
  20. 利用mininet进行链路拥塞造成数据丢包的实验

热门文章

  1. 听吐的微信提示音终于能改了
  2. 关于微信适配的坑==》ios、安卓强制微信字体
  3. 【文末下载PPT】李中文:软件成分安全分析(SCA)能力的建设与演进
  4. python判断三位数水仙花数_Python如何判断一个数字是否为水仙花数
  5. Geoserver发布OSM官网地图
  6. 举例说明 频分多址FDMA、时分多址TDMA、码分多址CDMA、空分多址SDMA的异同
  7. java中入参_JAVA传参
  8. java 建造者模式的实际应用场景
  9. kubeadm,kubevip,containerd部署高可用的kubernetes集群
  10. 计算机编程音乐,扒取网易云歌单音乐