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

默认
打赏 发表评论 6
通俗易懂:基于集群的移动端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状态。

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

附录:全站即时通讯技术资料分类


[1] 网络编程基础资料:
TCP/IP详解 - 第11章·UDP:用户数据报协议
TCP/IP详解 - 第17章·TCP:传输控制协议
TCP/IP详解 - 第18章·TCP连接的建立与终止
TCP/IP详解 - 第21章·TCP的超时与重传
技术往事:改变世界的TCP/IP协议(珍贵多图、手机慎点)
通俗易懂-深入理解TCP协议(上):理论基础
通俗易懂-深入理解TCP协议(下):RTT、滑动窗口、拥塞处理
理论经典:TCP协议的3次握手与4次挥手过程详解
理论联系实际:Wireshark抓包分析TCP 3次握手、4次挥手过程
计算机网络通讯协议关系图(中文珍藏版)
UDP中一个包的大小最大能多大?
Java新一代网络编程模型AIO原理及Linux系统AIO介绍
NIO框架入门(一):服务端基于Netty4的UDP双向通信Demo演示
NIO框架入门(二):服务端基于MINA2的UDP双向通信Demo演示
NIO框架入门(三):iOS与MINA2、Netty4的跨平台UDP双向通信实战
NIO框架入门(四):Android与MINA2、Netty4的跨平台UDP双向通信实战
P2P技术详解(一):NAT详解——详细原理、P2P简介
P2P技术详解(二):P2P中的NAT穿越(打洞)方案详解
P2P技术详解(三):P2P技术之STUN、TURN、ICE详解
高性能网络编程(一):单台服务器并发TCP连接数到底可以有多少
高性能网络编程(二):上一个10年,著名的C10K并发连接问题
高性能网络编程(三):下一个10年,是时候考虑C10M并发问题了
高性能网络编程(四):从C10K到C10M高性能网络应用的理论探索
>> 更多同类文章 ……

[2] 有关IM/推送的通信格式、协议的选择:
为什么QQ用的是UDP协议而不是TCP协议?
移动端即时通讯协议选择:UDP还是TCP?
如何选择即时通讯应用的数据传输格式
强列建议将Protobuf作为你的即时通讯应用数据传输格式
全方位评测:Protobuf性能到底有没有比JSON快5倍?
移动端IM开发需要面对的技术问题(含通信协议选择)
简述移动端IM开发的那些坑:架构设计、通信协议和客户端
理论联系实际:一套典型的IM通信协议设计详解
58到家实时消息系统的协议设计等技术实践分享
>> 更多同类文章 ……

[3] 有关IM/推送的心跳保活处理:
Android进程保活详解:一篇文章解决你的所有疑问
Android端消息推送总结:实现原理、心跳保活、遇到的问题等
深入的聊聊Android消息推送这件小事
为何基于TCP协议的移动端IM仍然需要心跳保活机制?
微信团队原创分享:Android版微信后台保活实战分享(进程保活篇)
微信团队原创分享:Android版微信后台保活实战分享(网络保活篇)
移动端IM实践:实现Android版微信的智能心跳机制
移动端IM实践:WhatsApp、Line、微信的心跳策略分析
>> 更多同类文章 ……

[4] 有关WEB端即时通讯开发:
新手入门贴:史上最全Web端即时通讯技术原理详解
Web端即时通讯技术盘点:短轮询、Comet、Websocket、SSE
SSE技术详解:一种全新的HTML5服务器推送事件技术
Comet技术详解:基于HTTP长连接的Web端实时通信技术
WebSocket详解(一):初步认识WebSocket技术
WebSocket详解(二):技术原理、代码演示和应用案例
WebSocket详解(三):深入WebSocket通信协议细节
socket.io实现消息推送的一点实践及思路
LinkedIn的Web端即时通讯实践:实现单机几十万条长连接
Web端即时通讯技术的发展与WebSocket、Socket.io的技术实践
Web端即时通讯安全:跨站点WebSocket劫持漏洞详解(含示例代码)
>> 更多同类文章 ……

[5] 有关IM架构设计:
浅谈IM系统的架构设计
简述移动端IM开发的那些坑:架构设计、通信协议和客户端
一套原创分布式即时通讯(IM)系统理论架构方案
从零到卓越:京东客服即时通讯系统的技术架构演进历程
蘑菇街即时通讯/IM服务器开发之架构选择
腾讯QQ1.4亿在线用户的技术挑战和架构演进之路PPT
微信技术总监谈架构:微信之道——大道至简(演讲全文)
如何解读《微信技术总监谈架构:微信之道——大道至简》
快速裂变:见证微信强大后台架构从0到1的演进历程(一)
17年的实践:腾讯海量产品的技术方法论
>> 更多同类文章 ……

[6] 有关IM安全的文章:
即时通讯安全篇(一):正确地理解和使用Android端加密算法
即时通讯安全篇(二):探讨组合加密算法在IM中的应用
即时通讯安全篇(三):常用加解密算法与通讯安全讲解
即时通讯安全篇(四):实例分析Android中密钥硬编码的风险
即时通讯安全篇(五):对称加密技术在Android平台上的应用实践
即时通讯安全篇(六):非对称加密技术的原理与应用实践
传输层安全协议SSL/TLS的Java平台实现简介和Demo演示
理论联系实际:一套典型的IM通信协议设计详解(含安全层设计)
微信新一代通信安全解决方案:基于TLS1.3的MMTLS详解
来自阿里OpenIM:打造安全可靠即时通讯服务的技术实践分享
简述实时音视频聊天中端到端加密(E2EE)的工作原理
移动端安全通信的利器——端到端加密(E2EE)技术详解
Web端即时通讯安全:跨站点WebSocket劫持漏洞详解(含示例代码)
>> 更多同类文章 ……

[7] 有关实时音视频开发:
即时通讯音视频开发(一):视频编解码之理论概述
即时通讯音视频开发(二):视频编解码之数字视频介绍
即时通讯音视频开发(三):视频编解码之编码基础
即时通讯音视频开发(四):视频编解码之预测技术介绍
即时通讯音视频开发(五):认识主流视频编码技术H.264
即时通讯音视频开发(六):如何开始音频编解码技术的学习
即时通讯音视频开发(七):音频基础及编码原理入门
即时通讯音视频开发(八):常见的实时语音通讯编码标准
即时通讯音视频开发(九):实时语音通讯的回音及回音消除概述
即时通讯音视频开发(十):实时语音通讯的回音消除技术详解
即时通讯音视频开发(十一):实时语音通讯丢包补偿技术详解
即时通讯音视频开发(十二):多人实时音视频聊天架构探讨
即时通讯音视频开发(十三):实时视频编码H.264的特点与优势
即时通讯音视频开发(十四):实时音视频数据传输协议介绍
即时通讯音视频开发(十五):聊聊P2P与实时音视频的应用情况
即时通讯音视频开发(十六):移动端实时音视频开发的几个建议
即时通讯音视频开发(十七):视频编码H.264、VP8的前世今生
网易视频云技术分享:音频处理与压缩技术快速入门
学习RFC3550:RTP/RTCP实时传输协议基础知识
简述开源实时音视频技术WebRTC的优缺点
良心分享:WebRTC 零基础开发者教程(中文)
开源实时音视频技术WebRTC中RTP/RTCP数据传输协议的应用
基于RTMP数据传输协议的实时流媒体技术研究(论文全文)
声网架构师谈实时音视频云的实现难点(视频采访)
浅谈开发实时视频直播平台的技术要点
还在靠“喂喂喂”测试实时语音通话质量?本文教你科学的评测方法!
实现延迟低于500毫秒的1080P实时音视频直播的实践分享
移动端实时视频直播技术实践:如何做到实时秒开、流畅不卡
如何用最简单的方法测试你的实时音视频方案
技术揭秘:支持百万级粉丝互动的Facebook实时视频直播
简述实时音视频聊天中端到端加密(E2EE)的工作原理
>> 更多同类文章 ……

[8] IM开发综合文章:
移动端IM开发需要面对的技术问题
开发IM是自己设计协议用字节流好还是字符流好?
请问有人知道语音留言聊天的主流实现方式吗?
IM消息送达保证机制实现(一):保证在线实时消息的可靠投递
IM消息送达保证机制实现(二):保证离线消息的可靠投递
如何保证IM实时消息的“时序性”与“一致性”?
IM单聊和群聊中的在线状态同步应该用“推”还是“拉”?
IM群聊消息如此复杂,如何保证不丢不重?
谈谈移动端 IM 开发中登录请求的优化
移动端IM登录时拉取数据如何作到省流量?
完全自已开发的IM该如何设计“失败重试”机制?
通俗易懂:基于集群的移动端IM接入层负载均衡方案分享
微信对网络影响的技术试验及分析(论文全文)
即时通讯系统的原理、技术和应用(技术论文)
开源IM工程“蘑菇街TeamTalk”的现状:一场有始无终的开源秀
腾讯原创分享(一):如何大幅提升移动网络下手机QQ的图片传输速度和成功率
如约而至:微信自用的移动端IM网络层跨平台组件库Mars已正式开源
>> 更多同类文章 ……

[9] 开源移动端IM技术框架资料:
开源移动端IM技术框架MobileIMSDK:快速入门
开源移动端IM技术框架MobileIMSDK:常见问题解答
开源移动端IM技术框架MobileIMSDK:压力测试报告
>> 更多同类文章 ……

[10] 有关推送技术的文章:
iOS的推送服务APNs详解:设计思路、技术原理及缺陷等
Android端消息推送总结:实现原理、心跳保活、遇到的问题等
扫盲贴:认识MQTT通信协议
一个基于MQTT通信协议的完整Android推送Demo
IBM技术经理访谈:MQTT协议的制定历程、发展现状等
求教android消息推送:GCM、XMPP、MQTT三种方案的优劣
移动端实时消息推送技术浅析
扫盲贴:浅谈iOS和Android后台实时消息推送的原理和区别
绝对干货:基于Netty实现海量接入的推送服务技术要点
移动端IM实践:谷歌消息推送服务(GCM)研究(来自微信)
为何微信、QQ这样的IM工具不使用GCM服务推送消息?
极光推送系统大规模高并发架构的技术实践分享
从HTTP到MQTT:一个基于位置服务的APP数据通信实践概述
魅族2500万长连接的实时消息推送架构的技术实践分享
专访魅族架构师:海量长连接的实时消息推送系统的心得体会
深入的聊聊Android消息推送这件小事
基于WebSocket实现Hybrid移动应用的消息推送实践(含代码示例)
一个基于长连接的安全可扩展的订阅/推送服务实现思路
实践分享:如何构建一套高可用的移动端消息推送系统?
>> 更多同类文章 ……

[11] 更多即时通讯技术好文分类:
http://www.52im.net/forum.php?mod=collection&op=all

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

评分

1

查看评分

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

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

推荐方案
评论 6
文章确实通俗易懂,但“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技术啊
签名: 《 小白必读:闲话HTTP短连接中的Session和Token》http://www.52im.net/thread-1686-1-1.html
引用: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的用法一样。我主 ...

回答的很详细
签名: 《 小白必读:闲话HTTP短连接中的Session和Token》http://www.52im.net/thread-1686-1-1.html
打赏楼主 ×
使用微信打赏! 使用支付宝打赏!

返回顶部