高并发IM系统架构优化实践

互联网+时代,消息量级的大幅上升,消息形式的多元化,给即时通讯云服务平台带来了非常大的挑战。高并发的IM系统背后究竟有着什么样的架构和特性

本文要点:

  • 网易云信整体架构解析
  • 云信中的客户端连接和接入点管理
  • 服务化和高可用

网易IM云分层架构图解析

  1. 底层客户端SDK,覆盖了安卓,iOS,windows PC桌面端,web网页端和嵌入式设备等多个平台。在SDK层使用的网络协议有4层的TCP协议和基于7层的Socket.IO协议,后者专门用于Web SDK中提供长连接能力;除了集成到应用App中的SDK之外,还提供了供第三方服务器调用的API接口,基于Http协议;最后的A/V SDK是基于UDP协议的实时音视频SDK,用于实现基于网络的语音和视频通话。

  2. 网关层:提供客户端直接接入并维护与服务器之间的长连接;其中WebSDK直连的是Weblink服务,这是一个基于Socket.IO协议实现的长连接服务,而供AOS/IOS/PC等客户端SDK直连的是基于TCP协议的Link服务;在Link和WebLink服务中承担的一个非常重要的功能就是所有客户端长连接的管理,后面基于HTTP协议上的网关有API服务,和LBS服务等,其中LBS服务用于帮助客户端SDK选取最合适自己的网关接入点,优化网络效率;而API服务则直接提供来自第三方服务器的业务请求;
  3. HA层:在网关接入层之上是HA层,网关接入层可提供给客户端直连,在link层和Service层之间有一个HA层用来解耦并提供高可用和易扩展等特性;在HA的具体实现方式上,对Link和WebLink这两个维持客户端长连接的服务,云信提供了协议路由的服务,代为分发业务请求,路由层会按照预定义的规则将来自客户端的请求转发到相应的业务节点上,当业务集群扩容之后路由服务马上能发现新的可用节点,并将请求转发过去,当发现业务节点出现异常时也会被路由层标记并隔离下线以备替换。
  4. 业务节点集群:在HA层上就是具体的业务节点集群,我们称为App服务,该服务处理具体的客户端请求,后端直连DB、cache等各种基础服务,这个集群中的节点的特点是轻量,并且每个节点都是无状态的,云信在实际部署这个集群时会跨网络环境部署,比如在同城双机房中分别部署一套业务服务节点,前端通过路由层来分发业务请求,平时正常时业务互为热备,平均分担线上的业务流量;当单一网络环境或者基础设施出现故障时马上会被路由服务检测到,并将该环境下的计算节点标记下线,将线上的流量请求全部转发到正常工作的集群中;从而提高了服务的整体可用性;配合监控平台等运维工具,业务节点的实时处理能力和容量使用情况都会被动态监测起来,当处理能力达到预设的水位线时会立即出发报警,运维人员可以非常方便快捷得通过自动部署平台对业务节点集群进行扩容。
  5. 业务层:其中包含了一些关键功能:核心的单聊消息、群聊消息和聊天室,通知等;以及用户信息托管,特殊关系管理等;还有面向API提供的如短信业务,回拨电话和专线会议等;还有实时音视频和直播功能等相关能力。

最右边列出的是从服务层上单独列出来的更重要的功能,包括与开发者应用的第三方数据同步,个性化的内容审核支持,超大群服务,登陆登出事件日志,漫游消息和云端消息历史功能,推送服务等等。

网易IM云部署拓扑

通过以下这张简化后的部署拓扑图可以对云信整体技术体系的有初步了解。最右边是客户端,客户端通过LBS服务获取到网关接入点列表,再与Link和WebLink这类长连接服务器建立起长连接,并进行RPC操作,所有来自客户端的请求都会通过路由层转发到后端的APP层,APP层实时处理并下发同步请求的处理结果,并把一些异步任务通过队列服务送到异步任务中,这些异步服务如大群消息的发送,推送服务,云端历史消息的存储和第三方的数据抄送同步服务等;在最下面的API接口上也是类似,API直接提供给第三方的服务器调用请求,API后端是各种独立的业务,如回拨电话,短信等;同样的所有的API后端业务请求也会产生相应的日志;和APP上的日志样,这些日志都会被通过日志采集平台收集到大数据平台中,一方面这类数据会存储到HDFS上用于作为数据统计分析的数据源;另一方面会被导入到Hbase等数据仓库中,用于提供日志检索和二次分析。

高并发IM系统连接层的优化实践

即时通讯功能中最重要的连接管理服务怎么做?消息快速到达的前提是客户端和服务器之间保持了稳定的连接;可以理解为奠定云信服务稳定性的基石。网关接入层需要解决的最重要的问题是什么?核心依然是稳定,安全和快速。

如何保证稳定?

网易云信SDK采用长连接机制来实现,并且由心跳的方式来检测断线和自动做重连,同时云信的SDK对移动网络等弱网环境非常多的优化工作,对移动端/PC端使用TCP来连接客户端与服务器,对与Web端使用socketIO协议,实现长连接的同时解决浏览器的兼容性问题;

如何实现安全?

云信要求所有在公网传输的数据都必须被加密;在SDK与服务器的连接建立过程中有一个复杂的秘钥协商过程,首先客户端需要生成一个一次性使用的加密秘钥,并使用非对称加密方式将这个秘钥加密之后传给服务器,加密数据会被服务器解密,之后该加密秘钥被保留在该长连接的会话信息中,数据来往均使用该秘钥加密,这是一个流式加密,可以有效防止中间人攻击和数据包回放等攻击手段。

如何保证快速?

首先是在网关接入点的选择上,借助LBS服务可以帮助客户端寻找到最适合自己的网关接入点,比如从ip等信息判断到的物理距离最近节点,其次在连接建立之后,长连接的机制可以极大提升消息上下行的速度,并且在数据传输过程中,云信会对数据包压缩传输,降低网络开销来升消息收发的速度;对频繁的前后台切换和重登陆这种移动客户端场景,SDK提供自动登录和重连等机制,即在UI界面起来的同时已经提前把消息通道建立;在接入网关的选择策略中,通过并行来提升连接建立的速度。

客户端与服务器建立长连接的过程展现

SDK接入的第一步是先请求LBS服务,获取可以进入的接入网关地址列表,LBS服务会根据多种策略条件来给客户端分配地址,常见的条件如下:

  1. appkey, 通过appkey可以将一个特定的应用请求全部指向到一组特定的接入点,可用于专属服务器方案;
  2. 客户端ip,用于根据客户端所处的地理位置,为其就近分配接入网关,常见于海外节点的配置;
  3. SDK版本号,将特定版本范围的客户端指向到特定网关,常用于新老版本升级的兼容方案,目前无实际使用案例;
  4. 特定环境标识,如智能客服环境等,用于将特定类型的app指向到特定网关,用于较大粒度环境隔离需求。

在从LBS服务请求到接入网关地址之后,客户端会按列表中的地址依次尝试建立连接;如果严格按照这样的顺序,那客户端建立连接的过程就会偏慢,为了加速接入过程,实际上在操作时,SDK都会使用本地缓存的最后一次LBS请求返回的地址列表来建立连接,同从LBS上拿一次新的地址列表缓存在本地,以备下次使用;当列表中的所有地址在尝试过一遍均失效,则会使用默认的link地址来建立连接;默认地址也失败是会出现415或者408这种网络错误码;

在获取到目标地址之后就会尝试建立TCP长连接,连接建立之后就会与服务器协商加密秘钥,并发出第一个鉴权包,鉴权完成之后这个长连接就是一个安全有效的连接,客户端可以发起后续的RPC请求;服务器也可以往这个连接上下发消息通知;如果秘钥协商失败或者鉴权失败,这个连接就会被认为是一个非法的连接请求,服务器会强制断开;

最后聊一下加速节点的问题,为了实现连接的快速,在网关接入点的分配时会优先距离该客户端最近的节点;这里将的加速节点就是为了更靠近用户提供的一种特殊节点。

加速节点的原理背景是运营商提供给个人用户的线路,不管是移动网络还是有线网络,其质量和IDC中心之间的网络总是有差异的;如果将整个用户链路中的关键路径替换成IDC之间的网络线路,那么对提升连接的稳定性和速度是有帮助的。

假设一个处于美国的客户通过手机网络访问位于杭州的一个网关接入点,由于客户端所在的网络是一个移动网络,直连到杭州服务器需要经过的链路非常长而且可能跳转的中间节点不可预期,在中国来说,还要跨越防火墙;所以直连的情况大部分可能就是无法连接,或者连接之后频繁断线。

我们提供了多层的加速节点:加入了加速节点之后,用户的整体链路中原来不可预期的那段链路都换成了质量较好的线路,用户直连到本地的加速节点的网络往往就会好很多。

下面说说不同的投递模式对消息送达效率的影响:

问题一:怎么让消息投递并发能力倍增?

在这张图中,上半部分表示的是一个点对点型的Link服务器,当发送者A发送一条消息之后,通过Link这条消息提交到APP中处理,APP中查询到该消息接收者B所在的Link服务器是Link y,于是向Link y服务器下发一条下行通知包,Link y上再找到用户B对应的长连接并将通知下发到客户端;这种模式下,所有的接入点Link对于所有的用户来说都是对等的,他可以接入到任何一个服务器中,任何消息的发送都必须在业务层查询到目标接收者所在的Link服务器,并往相应的Link服务器下发通知包,如果是一次群发行为,那就需要在业务APP上把所有群内的成员所在的Link列表都查询一遍;这是一个比较耗时的操作;并且是随着消息接收成员的数量不断上升开销不断增大;所以如果是需要往聊天室内发送消息,由于聊天室内的成员数量非常庞大,这种模式很快就会遇到性能瓶颈,消息投递的延时会非常严重;

对于广播型的Link服务器,云信在分配接入点时首先遵循一个原则,那就是同个聊天室内的成员在分配聊天室时,尽量分配在同一组接入点上;在Link上维护了每个房间内所有的成员的长连接集合;而在App上维护的不再是特定用户和Link之前的映射关系,而是维护了特定房间分配的Link的集合;于是在任何一个成员发出一条聊天室广播消息之后,消息通过link上行到App,App只要找到该聊天室已经分配的Link地址列表,往每个Link上下发一个广播消息,Link在收到下行的广播消息之后再在本地做广播分发;这个效率比点播的模式高出了不止一个数量级;

问题二:怎么解决单节点的性能瓶颈?

在讲完了点对点型和广播型这两种Link的区别之后;云信再回头来看看另外一类基于socket.io实现的weblink的代理方案在云信中的演变优化过程;

在这之前需要再强调下WebLink中两个关键点,首先WebLink是基于Socket.io协议的,为了保证数据通道的可靠,云信需要使用Https来对通道加密,其次由于是Https的请求所以必须提供独立的域名。

图一中显示的是最早的方案,后端Weblink提供连接,并实现SSL加密,多个节点前面通过LVS做代理,域名绑定在LVS代理之上,LVS代理之上再做Keepalived方案来保证HA;这种方案对外暴露的域名只有一个,而内部实际有很多的节点,扩容对外也是透明的;Web客户端在连接时只需要直连这个唯一域名就可以,对于单一产品来说这种方式最简便快捷,客户端可以绕过地址分配的过程;缺点也集中在单一出口,如果这个单一出口受到DDOS攻击,只能通过域名换绑来规避,而域名换绑需要一定的生效时间,带来和一些运维上的代价,其次对于云信这种服务来说,单一出口就丧失了灵活性;所有客户直连到同一个入口,也无法实现专属服务和业务隔离,无法实现加速节点方案;

于是便有了第二种方案,这种方案借鉴了Link业务中的LBS分配的方式,还是在Weblink节点上实现SSL加密,并为每个Weblink节点分配独立域名,客户端在接入前先通过LBS服务来分配到合适的接入点;这种方案好处就是提供了更大的灵活性,随时可以给集群扩容,也可以动态调整特定应用的接入点地址,也提供做加速节点的可能性;但是这种方案的问题是每个节点都是单点,而且节点内还是需要做SSL编码,由于java的SSL对cpu资源开销比较大,在突发用户流量是会影响单个节点的服务能力;

于是又有了第三种方案,这种方案前端使用Nginx做七层代理,并在Nginx配置SSL和域名绑定,后端可以同时使用一组Weblink;由于使用了Nginx,在端口的分配逻辑上也更加科学,提高了运维的便捷性;最后云信就得到了目前在使用的一个组合方案,前端还是通过LBS服务来为SDK分配接入点,以此提供灵活性;后端使用多个Nginx集群做代理集群,每个集群分组的性能都得到了提高。

即时通讯平台服务化和高可用实践

前面重点介绍了云信在客户端接入层的实现和接入点的管理上使用的一些方法,通过这些技术手段为IM服务建立了一条稳定可靠的消息通道,现在来聊聊在业务层做的服务化和高可用上面的工作。

网关接入层负责客户端长连接的维护和管理,所有的接入节点甚至可以是无状态的对等节点,只负责客户端与服务器之间请求的传递的转发,并优化转发效率;而真正的业务处理逻辑还是需要有业务层来实现。

业务层需要处理大量请求并负责和DB,缓存,队列,第三方接口等组件的交互,其稳定性,可用性和扩展能力直接影响了整个云服务的质量;为了使业务层具有更好的弹性,云信在网关接入层和业务层之间引入了一个路由层来解耦;业务节点在上线之后会将自己注册到服务中心,路由节点会转接网关层的请求包,并从服务节点中挑选匹配的节点分发请求;这种三层架构使系统整体具有更好的弹性。

为了提高业务的可用性,云信会将业务节点分布到分属于不同网络的环境中,正常情况下可以同时提供服务,一旦其中一个环境的网络或者基础设施出现故障,就可以快速得通过路由层来将故障集群下线。

灵活支持灰度升级模式,云信可以将其中部分业务节点升级,然后通过路由层的配置将指定的用户流量导入到新升级的节点中;

专属服务的灵活支持,对于一些对资源独占需求比较强烈的客户,云信可以通过路由层将该客户应用下的所有流量导入到独立的集群中。

本文转载:https://juejin.im/post/5b1e2cc15188257d4529804b

原文地址:https://www.cnblogs.com/xiyunjava/p/9247724.html

时间: 2024-10-25 22:25:19

高并发IM系统架构优化实践的相关文章

高并发大型网站架构设计

一个大型的网站网站应该由如下6个子系统组成 负载均衡系统 反向代理系统 Web服务器系统 分布式存储系统 底层服务系统 数据库集群系统 为什么要做高并发系统设计? 事实上,针对于任何单一的网络服务器程序,其可承受的同时连接数目是有理论峰值的,通过C++中对TSocket的定义类型:word,我们可以判 定这个连接理论峰值是65535,也就是说,你的单个服务器程序,最多可以承受6万多的用户同时连接.但是,在实际应用中,能达到一万人的同时连接并能保 证正常的数据交换已经是很不容易了,通常这个值都在2

Entity Framework 数据并发访问错误原因分析与系统架构优化

本文主要记录近两天针对项目发生的数据访问问题的分析研究过程与系统架构优化,我喜欢说通俗的白话,高手轻拍 1. 发现问题 系统新模块上线后,使用频率较高,故在实际使用和后期的问题重现测试中,产生了一下系列的数据访问错误 错误是比较常见的错误 2. 分析问题 系统的架构为前端.业务层与数据层三层架构,采用Entity Framework 3.5作为数据处理技术,采用shared context per request模式,参照的是codeplex上的一个示例.示例地址(此文通俗易懂,代码结构也很清晰

使用NoSQL实现高并发CRM系统实践(源代码+解析)

又想速度快,又要大数据,又要保证数据不出错,还要拥抱变化,改需求的时候不那么痛苦,特别是字段的调整,按照以前的做法,想想就头疼.使用NoSQL,简直就是随心所欲,再奇葩的数据结构,处理起来也很容易.下面看我如何用NoSQL数据库实现高并发,高可靠的CRM系统. 1.前言 随着facebook.微博等WEB2.0互联网网站的兴起,传统的关系数据库在应付web2.0网站,特别是超大规模和高并发的SNS类型的web2.0纯动态网站已经显得力不从心,暴露了很多难以克服的问题,而非关系型的数据库则由于其本

大话SQL Server性能优化(MSSQL高并发、性能调控、实践)

大话SQL Server性能优化(MSSQL高并发.性能调控.实践)网盘地址:https://pan.baidu.com/s/1KxdfcQD0XGD3M2ja_Y7UWQ 提取码:435v备用地址(腾讯微云):https://share.weiyun.com/5dTuZJ9 密码:xhmge4 本课程源于一家国内较知名的ERP厂商的一款产品出现性能问题后通过咨询服务解决了性能问题,然后根据自身多年技术培训.项目开发.产品研发与运维管理.软件公司内部咨询等经验,整理了在SQL Server 20

亿级数据的高并发通用搜索引擎架构设计(转-张宴)

[文章作者:张宴 本文版本:v1.0 最后修改:2008.12.09 转载请注明原文链接:http://blog.zyan.cc/post/385/] 曾经在七月,写过一篇文章──<基于Sphinx+MySQL的千万级数据全文检索(搜索引擎)架构设计>, 前公司的分类信息搜索基于此架构,效果明显,甚至将很大一部分带Where条件的MySQL SQL查询,都改用了Sphinx+MySQL搜索.但是,这套架构仍存在局限:一是MySQL本身的并发能力有限,在200-300个并发连接下,查询 和更新就

阿里秒杀系统架构优化思路

秒杀业务为什么难做 im系统,例如qq或者微博,每个人都读自己的数据(好友列表.群列表.个人信息) 微博系统,每个人读你关注的人的数据,一个人读多个人的数据 秒杀系统,库存只有一份,所有人会在集中的时间读和写这些数据,多个人读一个数据例如:小米手机每周二的秒杀,可能手机只有1万部,但瞬时进入的流量可能是几百几千万. 又例如:12306抢票,票是有限的,库存一份,瞬时流量非常多,都读相同的库存.读写冲突,锁非常严重,这是秒杀业务难的地方.那我们怎么优化秒杀业务的架构呢? 优化方向 优化方向有两个(

高并发大访问量架构设计演进之路 归纳总结

第01:大型架构的演进之路第02(上):分布式缓存第02(下):分布式缓存第03:分布式消息队列第04:分布式数据存储第05:分布式服务框架第06:高性能系统架构第07:高可用系统架构第08:系统的安全架构第09:架构实战案例分析第10:如何成为技术专家 系统的垂直伸缩,水平伸缩系统的性能瓶颈:分部式缓存:分布式数据存储,分布式服务架构: 强烈的好奇心,工程技术,产生价值赚钱(科学研究不同)扎实的软件技术基础:操作系统,数据结构,设计模式,编程语言,出色的编程能力:优秀的代码深刻领悟主流技术产品

高并发实时直播弹幕研发实践

高并发实时直播弹幕研发实践 直播间特点 聊天室限制人数的原因 应对万级以上的实时互动 跨服务器是为了解决单一服务器接入数量限制.发布消息吞吐限制等问题: 多进程并发则是为了充分利用多核CPU以及减小一个循环规模从而达到降低延迟的目的. 云巴实时系统的设计 云巴是基于MQTT协议实现的实时通信系统,采用Erlang/OTP的架构设计.简单地来说,云巴实时系统的设计包括多层结构.微服务两个要点. 多层结构 云巴系统设计中,多层结构意味着一个基本业务逻辑的完成需要经历多个模块(如图上所示). 云巴多层

全流程开发 GO实战电商网站高并发秒杀系统

获取资源点击这里:全流程开发 GO实战电商网站高并发秒杀系统 第1章 课程介绍[学前须知] 本章对这门课程进行说明,包括:秒杀系统涉及模块的介绍,秒杀核心的知识点的介绍,课程的学习规划等. 1-1 课程介绍试看 第2章 需求整理&系统设计 [明确需求] 本章对秒杀系统整体需求进行梳理,明确系统具体需求,讲解系统原型设计工具的使用,并结合秒杀系统进行整体架构设计. 2-1 需求分析 2-2 系统架构设计 2-3 [总结&扩展]需求整理&系统设计 2-4 [勤于思考,夯实学习成果]阶段