请选择 进入手机版 | 继续访问电脑版

默认
打赏 发表评论 25
想开发IM:买成品怕坑?租第3方怕贵?找开源自已撸?尽量别走弯路了... 找站长给点建议
通俗易懂:基于集群的移动端IM接入层负载均衡方案分享
微信扫一扫关注!

1、前言


要开发一个真正能用于生产环境的移动端IM系统,难度还是比较大的,因为移动端IM系统是多种技术手段的综合应用:包括移动端网络编程、通信安全、高性能互联网架构等等,尤其在当下IM技术相对封闭、实践资料并不容易找到的情况下。

本文将以基于TCP数据传输协议的移动端IM为例,通过循序渐进地方式,分享如何构建一个基于分布式集群的移动端IM接入层的设计和实现。

2、IM开发干货系列文章


本文是系列文章中的第8篇,总目录如下:


另外,如果您是IM开发初学者,强烈建议首先阅读《新手入门一篇就够:从零开发移动端IM》。

3、Web短连接与基于TCP长连接的负载均衡系统各自的特点


1.png

互联网架构中,web-server接入一般使用nginx来做反向代理,实施负载均衡。整个架构分三层:

  • 上游调用层:一般是browser或者APP;
  • 中间反向代理层:nginx;
  • 下游真实接入集群:web-server,常见web-server的有tomcat,apache。

整个访问过程为:

  • browser向daojia.com发起请求;
  • DNS服务器将daojia.com解析为外网IP(1.2.3.4);
  • browser通过外网IP(1.2.3.4)访问nginx;
  • nginx实施负载均衡策略,常见策略有轮询,随机,IP-hash等;
  • nginx将请求转发给内网IP(192.168.0.1)的web-server。

由于http短连接,以及web应用无状态的特性,理论上任何一个http请求落在任意一台web-server都应该得到正常处理(如果必须落在一台,说明架构不合理,不能水平扩展)。

与传统的Web系统不同的是:基于tcp长连接的IM系统中,每条长连接通路都是有状态的,客户端和服务端一旦建立连接,一个client发起的请求必须落在同一台tcp-im-server上。那么此时该如何做负载均衡,如何保证水平扩展呢?我们继续往下看。

4、单机场景下的tcp-im-server


2.png

单机tcp-im-server显然是很容易保证请求一致性的:

  • client向tcp.daojia.com发起tcp请求;
  • DNS服务器将tcp.daojia.com解析为外网IP(1.2.3.4);
  • client通过外网IP(1.2.3.4)向tcp-im-server发起请求。

方案的缺点呢?那就是无法保证高可用

5、一个典型的基于集群的tcp-im-server方案及其缺点


3.png

通过搭建tcp-im-server集群来保证高可用,客户端来实现负载均衡:

  • client内配置有tcp1/tcp2/tcp3.mydomain.com三个tcp-im-server的外网IP;
  • 客户端通过“随机”的方式选择tcp-im-server,假设选择到的是tcp1.mydomain.com;
  • 通过DNS解析tcp1.mydomain.com;
  • 通过外网IP连接真实的tcp-im-server。

那如何保证高可用呢?
如果client发现某个tcp-im-server连接不上,则选择另一个。

潜在的缺点?
每次连接前,需要多实施一次DNS访问:
  • 难以预防DNS劫持;
  • 多一次DNS访问意味着更长的连接时间,这个不足在手机端更为明显。

如何解决DNS的问题?
直接将IP配置在客户端,可以解决上述两个问题,很多公司也就是这么做的(俗称“IP直通车”)。

“IP直通车”有什么新问题?
将IP写死在客户端,在客户端实施负载均衡,扩展性很差:
  • 如果原有IP发生变化,客户端得不到实时通知;
  • 如果新增IP,即tcp-sever扩容,客户端也得不到实时通知;
  • 如果负载均衡策略变化,需要升级客户端。

6、优化1:把负载均衡策略放到服务端做


只有将复杂的策略下沉到服务端,才能根本上解决扩展性的问题。

4.png

增加一个http接口,将客户端的“IP配置”与“均衡策略”放到服务端是一个不错的方案:

  • client每次访问tcp-im-server前,先调用一个新增的get-tcp-ip接口,对于client而言,这个http接口只返回一个tcp-im-server的IP;
  • 这个http接口,实现的是原client的IP均衡策略;
  • 拿到tcp-im-server的IP后,和原来一样向tcp-im-server发起TCP长连接。

这样的话,扩展性问题就解决了:

  • 如果原有IP发生变化,只需要修改get-tcp-ip接口的配置;
  • 如果新增IP,也是修改get-tcp-ip接口的配置;
  • 如果负载均衡策略变化,需要升级客户端。

然而,新的问题又产生了,如果所有IP放在客户端,当有一个IP挂掉的时候,client可以再换一个IP连接,保证可用性,而get-tcp-ip接口只是维护静态的tcp-im-server集群IP,对于这些IP对应的tcp-im-server是否可用,是完全不知情的,怎么办呢?

7、优化2:改为由tcp-im-servert主动上报状态


5.png

get-tcp-ip接口怎么知道tcp-im-server集群中各台服务器是否可用呢,tcp-im-server主动上报是一个潜在方案,如果某一个tcp-im-server挂了,则会终止上报,对于停止上报状态的tcp-im-server,get-tcp-ip接口,将不返回给client相应的tcp-im-server的外网IP。

该设计的存在的问题?
诚然,状态上报解决了tcp-im-server高可用的问题,但这个设计犯了一个“反向依赖”的耦合小错误:使得tcp-im-server要依赖于一个与本身业务无关的web-server。

8、优化3:改为主动拉取tcp-im-server的状态


6.png

更优的方案是:web-server通过“拉”的方式获取各个tcp-im-server的状态,而不是tcp-im-server通过“推”的方式上报自己的状态。

这样的话,每个tcp-im-server都独立与解耦,只需专注于资深的tcp业务功能即可。

高可用、负载均衡、扩展性等任务由get-tcp-ip的web-server专注来执行。

多说一句,将负载均衡实现在服务端,还有一个好处,可以实现异构tcp-im-server的负载均衡,以及过载保护:

  • 静态实施:web-server下的多个tcp-im-server的IP可以配置负载权重,根据tcp-im-server的机器配置分配负载(nginx也有类似的功能);
  • 动态实施:web-server可以根据“拉”回来的tcp-im-server的状态,动态分配负载,并在tcp-im-server性能极具下降时实施过载保护。

9、本文小结


web-server如何实施负载均衡?
利用nginx反向代理来轮询、随机、ip-hash。

tcp-im-server怎么快速保证请求一致性?
单机。

如何保证高可用?
客户配置多个tcp-im-server的域名。

如何防止DNS劫持,以及加速?
IP直通车,客户端配置多个tcp-im-server的IP。

如何保证扩展性?
服务端提供get-tcp-ip接口,向client屏屏蔽负载均衡策略,并实施便捷扩容。

如何保证高可用?
tcp-im-server“推”状态给get-tcp-ip接口,或者 get-tcp-ip接口“拉”tcp-im-server状态。

(原文链接:点此进入,有改动)

附录:更多IM架构文章


浅谈IM系统的架构设计
简述移动端IM开发的那些坑:架构设计、通信协议和客户端
一套海量在线用户的移动端IM架构设计实践分享(含详细图文)
一套原创分布式即时通讯(IM)系统理论架构方案
从零到卓越:京东客服即时通讯系统的技术架构演进历程
蘑菇街即时通讯/IM服务器开发之架构选择
腾讯QQ1.4亿在线用户的技术挑战和架构演进之路PPT
微信后台基于时间序的海量数据冷热分级架构设计实践
微信技术总监谈架构:微信之道——大道至简(演讲全文)
如何解读《微信技术总监谈架构:微信之道——大道至简》
快速裂变:见证微信强大后台架构从0到1的演进历程(一)
17年的实践:腾讯海量产品的技术方法论
移动端IM中大规模群消息的推送如何保证效率、实时性?
现代IM系统中聊天消息的同步和存储方案探讨
IM开发基础知识补课(二):如何设计大量图片文件的服务端存储架构?
IM开发基础知识补课(三):快速理解服务端数据库读写分离原理及实践建议
IM开发基础知识补课(四):正确理解HTTP短连接中的Cookie、Session和Token
WhatsApp技术实践分享:32人工程团队创造的技术神话
微信朋友圈千亿访问量背后的技术挑战和实践总结
王者荣耀2亿用户量的背后:产品定位、技术架构、网络方案等
IM系统的MQ消息中间件选型:Kafka还是RabbitMQ?
腾讯资深架构师干货总结:一文读懂大型分布式系统设计的方方面面
以微博类应用场景为例,总结海量社交系统的架构设计步骤
快速理解高性能HTTP服务端的负载均衡技术原理
子弹短信光鲜的背后:网易云信首席架构师分享亿级IM平台的技术实践
知乎技术分享:从单机到2000万QPS并发的Redis高性能缓存实践之路
IM开发基础知识补课(五):通俗易懂,正确理解并用好MQ消息队列
微信技术分享:微信的海量IM聊天消息序列号生成实践(算法原理篇)
微信技术分享:微信的海量IM聊天消息序列号生成实践(容灾方案篇)
新手入门:零基础理解大型分布式架构的演进历史、技术原理、最佳实践
一套高可用、易伸缩、高并发的IM群聊、单聊架构方案设计实践
阿里技术分享:深度揭秘阿里数据库技术方案的10年变迁史
阿里技术分享:阿里自研金融级数据库OceanBase的艰辛成长之路
社交软件红包技术解密(一):全面解密QQ红包技术方案——架构、技术实现等
社交软件红包技术解密(二):解密微信摇一摇红包从0到1的技术演进
社交软件红包技术解密(三):微信摇一摇红包雨背后的技术细节
社交软件红包技术解密(四):微信红包系统是如何应对高并发的
社交软件红包技术解密(五):微信红包系统是如何实现高可用性的
社交软件红包技术解密(六):微信红包系统的存储层架构演进实践
社交软件红包技术解密(七):支付宝红包的海量高并发技术实践
社交软件红包技术解密(八):全面解密微博红包技术方案
社交软件红包技术解密(九):谈谈手Q红包的功能逻辑、容灾、运维、架构等
社交软件红包技术解密(十):手Q客户端针对2020年春节红包的技术实践
社交软件红包技术解密(十一):解密微信红包随机算法(含代码实现)
即时通讯新手入门:一文读懂什么是Nginx?它能否实现IM的负载均衡?
即时通讯新手入门:快速理解RPC技术——基本概念、原理和用途
多维度对比5款主流分布式MQ消息队列,妈妈再也不担心我的技术选型了
从游击队到正规军(一):马蜂窝旅游网的IM系统架构演进之路
从游击队到正规军(二):马蜂窝旅游网的IM客户端架构演进和实践总结
从游击队到正规军(三):基于Go的马蜂窝旅游网分布式IM系统技术实践
IM开发基础知识补课(六):数据库用NoSQL还是SQL?读这篇就够了!
瓜子IM智能客服系统的数据架构设计(整理自现场演讲,有配套PPT)
阿里钉钉技术分享:企业级IM王者——钉钉在后端架构上的过人之处
微信后台基于时间序的新一代海量数据存储架构的设计实践
IM开发基础知识补课(九):想开发IM集群?先搞懂什么是RPC!
IM开发基础知识补课(十):大型IM系统有多难?万字长文,搞懂异地多活!
阿里技术分享:电商IM消息平台,在群聊、直播场景下的技术实践
一套亿级用户的IM架构技术干货(上篇):整体架构、服务拆分等
一套亿级用户的IM架构技术干货(下篇):可靠性、有序性、弱网优化等
从新手到专家:如何设计一套亿级消息量的分布式IM系统
企业微信的IM架构设计揭秘:消息模型、万人群、已读回执、消息撤回等
融云技术分享:全面揭秘亿级IM消息的可靠投递机制
IM开发技术学习:揭秘微信朋友圈这种信息推流背后的系统设计
阿里IM技术分享(三):闲鱼亿级IM消息系统的架构演进之路
阿里IM技术分享(四):闲鱼亿级IM消息系统的可靠投递优化实践
阿里IM技术分享(五):闲鱼亿级IM消息系统的及时性优化实践
阿里IM技术分享(六):闲鱼亿级IM消息系统的离线推送到达率优化
基于实践:一套百万消息量小规模IM系统技术要点总结
>> 更多同类文章 ……

即时通讯网 - 即时通讯开发者社区! 来源: - 即时通讯开发者社区!

评分

1

查看评分

上一篇:微信后台团队:微信后台异步消息队列的优化升级实践分享下一篇:一套海量在线用户的移动端IM架构设计实践分享(含详细图文)

本帖已收录至以下技术专辑

推荐方案
评论 25
文章确实通俗易懂,但“8、优化3:改为主动拉取tcp-im-server的状态”这一点,如果能深入的写写到底怎么个“拉取”法就更好了!
签名: 国庆长假还没有缓过来,请让我静一静,产品狗死远点...
确实通俗易懂,赞

这里有个comet的方案,与文中描述的原理相似,对于需要消息推送的web或者app用起来还是很方便的。
https://github.com/ideawu/icomet/wiki


引用:ZhouWei 发表于 2018-01-26 15:40
这里有个comet的方案,与文中描述的原理相似,对于需要消息推送的web或者app用起来还是很方便的。
https ...

现在是HTML5的Websocket时代了,你还在玩Comet技术啊
引用:JackJiang 发表于 2018-01-26 16:01
现在是HTML5的Websocket时代了,你还在玩Comet技术啊

我叫它comet方案不完全准确,我只是看到这库的名字叫icomet,然后,在客户端可以跟comet的用法一样。我主要是想表达,这个库与这个描述的方案很像,服务器用c的libevent实现,利用nginx做反向代理,这样就可以做到文中提到的水平扩展。icomet还实现了SSE,在APP中还支持stream方式的推送,整体来说,给看到这个文章的人提供了一个很不错的选择,作为已经开发出来,还有人维护的项目来说,很有实用价值。一金币到手!
引用:ZhouWei 发表于 2018-01-26 18:29
我叫它comet方案不完全准确,我只是看到这库的名字叫icomet,然后,在客户端可以跟comet的用法一样。我主 ...

回答的很详细
神秘人  发表于 5 年前
文中:tcp-im-server怎么快速保证请求一致性?
单机。 这个怎么理解呢?对于同一个个client 保证每次长连接都是同一个 server?
引用:chiya 发表于 2018-08-21 10:53
文中:tcp-im-server怎么快速保证请求一致性?
单机。 这个怎么理解呢?对于同一个个client 保证每次长连 ...

集群的情况下没有办法保证每次连接的都是同一台,也没有必要每次都连同一台服务器
神秘人  发表于 5 年前
引用:JackJiang 发表于 2018-08-21 12:00
集群的情况下没有办法保证每次连接的都是同一台,也没有必要每次都连同一台服务器

感谢,多读了几遍理解了,其实就是说 某一次TCP长连接过程中,这次长连接的所有请求都是在同一台服务器上。但是这个用单机  tcp-im-server 的请求一致性怎么理解呢?
方案很赞,和当初我们的方案如出一辙,我们定义了一个【注册中心】【数据上报中心】用于解耦,进一步进行负载均衡
引用:一夕 发表于 2019-02-26 12:59
方案很赞,和当初我们的方案如出一辙,我们定义了一个【注册中心】【数据上报中心】用于解耦,进一步进行负 ...

你们的产品,现在运营用户规模有多少了?
引用:JackJiang 发表于 2019-02-26 13:10
你们的产品,现在运营用户规模有多少了?

我们用户的量极少,都是政府和我们公司运维人员,真正的并发量在于下面的智能终端。
引用:一夕 发表于 2019-02-26 13:13
我们用户的量极少,都是政府和我们公司运维人员,真正的并发量在于下面的智能终端。

能把这样的架构理清搞通,很不错了
我们目前也是用这种方案,20年的时候用户300多万,春节在线并发30多万 ~ 50万之间,基本稳定
引用:weixiaoyao 发表于 2021-03-29 15:43
我们目前也是用这种方案,20年的时候用户300多万,春节在线并发30多万 ~ 50万之间,基本稳定

你这个量对于市面上的im来说,不小啊
引用:JackJiang 发表于 2021-03-29 17:23
你这个量对于市面上的im来说,不小啊

我们主要做在线教育,学生稍微多点
引用:weixiaoyao 发表于 2021-03-30 18:24
我们主要做在线教育,学生稍微多点

能做成这个体量,不错啊
大佬们,如果client-A 挂在了server-1下面, clietn-B 挂在server-2下面 这个时候client-A和client-B怎么通讯啊,这个时候服务做不了转发吧,如果是群聊这消息。。。我裂开
引用:csj 发表于 2021-05-17 17:27
大佬们,如果client-A 挂在了server-1下面, clietn-B 挂在server-2下面 这个时候client-A和client-B怎么通 ...

在server-1和server-2间用rpc进行消息转发
打赏楼主 ×
使用微信打赏! 使用支付宝打赏!

返回顶部