1、前言
有过移动端开发经历的开发者都深有体会:移动端IM的开发,与传统PC端IM有很大的不同,尤其无线网络的不可靠性、移动端硬件设备资源的有限性等问题,导致一个完整的移动端IM架构设计和实现都充满着大量的挑战。本文将简述移动端IM最重要的架构设计和通信协议选择方面的坑点,希望为IM开发者同行带来些许启发。
2、概述
![48fdacfc8c5997d19b8c6dbb4883683d.png](https://i-blog.csdnimg.cn/blog_migrate/3a6ac65f43c9cae13f7fc97200331f27.png)
移动互联网时代的来临促使我们所有的开发者都要从用户视角出发,基于某一特定场景来创建应用,满足用户需求。通常,在这些应用中,沟通环节都是必不可少的。这就要求创业者不仅要花时间和精力来琢磨用户在某一特定场景下有何痛点需求,琢磨如何解决这一需求,并且可能还要花费更多的精力和时间来解决产品中“沟通”这一技术节点。
而要解决沟通问题,就需要一套IM系统(而且肯定要支持移动端)。做为IM开发者或即将成为IM开发者的技术人员,IM的价值和重要性不言自明。但从技术实现来说,这并不容易。当然,假设你有100个用户,什么都是容易的,但是假设你有了100万、1000万甚至1亿的用户,再简单的技术节点解决不好,都会成为灾难,何况IM系统(尤其是移动端的IM系统)还是存在许多技术难点和坑点的。
3、有关移动端IM通信协议的坑
其次,我们再看一下IM 协议如何选型。通常IM采取的协议有xmpp、mqtt、protobuf等数据通信私有协议,我们来逐一分析他们的优缺点。1. XMPP协议:
- 优点:基于xml协议,容易理解,使用广泛,易于扩展。
- 缺点:流量大,在移动终端也耗电。交互过程复杂。多被pc时代的产品使用,不适合移动时代的IM产品,即使我们基于xmpp进行改进,简化握手过程,改进文件传输机制,但是它的基因决定了如何改进,他都不适合移动互联网时代的IM产品。就像凤姐无论怎么整容,也变成不了高圆圆一样。
2. MQTT协议:
- 优点:适配多平台。
- 缺点:协议简单,但是需要自己扩展好友,群组等功能。
3. 私有协议:
- 优点:随心所欲,自己定义,流量小。
- 缺点:工作量巨大,扩展性差,需要考虑全面。
4. Protobuf协议:
- 优点:非常小、非常快、非常简单,一条消息数据用Protobuf序列化后的大小是JSON的1/10、XML格式的1/20、是二进制序列化的1/10。
- 缺点:不能表示复杂的数据结构,但是对于IM来讲,已经足够。强烈推荐此协议。
补充1:强列建议使用Protobuf,理由如下
- 灵活、高效:灵活(方便接口更新)、高效(效率经过google的优化,传输效率比普通的XML等高很多);
- 易于使用:开发人员通过按照一定的语法定义结构化的消息格式,然后送给命令行工具,工具将自动生成相关的类,可以支持java、c++、python等语言环境。通过将这些类包含在项目中,可以很轻松的调用相关方法来完成业务消息的序列化与反序列化工作。
- 语言支持:原生支持c++、java、python等多达10余种语言。
补充2:Protobuf主要适用于:
- 需要和其它系统做消息交换的,对消息大小很敏感的。那么protobuf适合了,它语言无关,消息空间相对xml和json等节省很多。
- 小数据的场合。如果你是大数据,用它并不适合。
- 项目语言是c++、java、python等,因为它们可以使用google的源生类库,序列化和反序列化的效率非常高。其它的语言需要第三方或者自己写,序列化和反序列化的效率不保证。
总体而言,Protobuf还是非常好用的,被很多开源系统用于数据通信的工具,在google也是核心的基础库。
后台私信“1”可以领取一份Protobuf语法详解
![e446db2994f55939505f569c7a69ed95.png](https://i-blog.csdnimg.cn/blog_migrate/dafea18416197c91d5869ea7e9dd0a74.jpeg)
4、移动端IM客户端的坑
最后,我们再来了解一下移动端有哪些难点需要解决。1. 流量:
采取哪种协议、图片缩略图、附件的压缩三点决定了流量的大小。2. 耗电:
(1)流量越小,耗电越低。(2)心跳策略,减少心跳次数,耗电量就会降低。3. 心跳时长:
wifi,2G,3G,4G,移动、电信、联通,不同网络,不同运行商,NAT失效时间不一样,因此心跳的时间也就不一样。4. 网络连接:
cmnet和cmwap下连接处理机制。5. 网络不稳定:
移动端最大的特点就是网络不稳定,在不稳定的网络状态下,如何保证消息以最快的速度到达?如何避免重联风暴?这些既需要从整体架构考虑,也需要在移动端采取巧妙的策略加以避免。
5、移动端IM架构设计的坑
首先,来看移动端IM架构设计需要考虑的问题。1. 连接器的设计:
连接器主要用来管理客户端的长连接。目前最好的连接器单台8G8核的服务器可以做到70万—100万的连接,而某些开发者只能做到4000左右的连接,相差好几个数量级。这里的奥妙在哪里呢?2. 中间件的设计:
是否采用通讯中间件?通讯中间件的好处有哪些?如果不采用中间件,连接器和逻辑服务器的连接关系如何管理呢?3. 逻辑服务器:
逻辑服务器通常简单一点,主要是根据业务逻辑进行最小粒度的划分即可。但是即便如此,还是有很多的开发者把看似相关实则不相关的逻辑放在一起,如把鉴权和message服务器放在一起。4. 状态服务器:
状态服务器主要管理用户在线、离线的相关状态,需要采取中心节点的方案,否则状态就会不同步。这里主要需要考虑状态服务器所对应的数据存储机制,如何进行写操作,如何进行读操作?以便最大的提高状态服务器的处理能力和响应速度。5. 数据库的设计:
数据库的设计是最难的,也是做大的瓶颈。因为无论对于sql(关系型)数据库还是nosql(非关系型)数据库,都有读写处理的极限,那就需要考虑数据库如何分区(根据什么原则、什么操作、哪些用户访问哪个节点上的数据库)。同时又需要考虑每个原子操作(如登陆)需要读哪些库,写哪些库。只有这些指标明确了,你才能在假设有100万并发用户,100万条并发消息的情况下,准确评估服务端需要多少台服务器,如何部署。6. 其他:
还有设备推送的处理,何种机制能够保证不丢消息,离线消息如何处理,等等。这些都是必备而又非常复杂的功能点和技术要求,都需要采取正确的架构和策略才能实现。
6、结语
以上难点和坑点草草记录下来也不过千把字,但是真正要解决这些问题并达到生产应用标准,却要不知道花费多少日日夜夜、敲下多少行代码,恐怕也只有真正做过IM的开发者才有比较深刻的体会。
- 另外还有一些关于c++ Linux后台服务器开发的一些知识点分享:Linux,Nginx,MySQL,Redis,P2P,K8S,Docker,TCP/IP,协程,DPDK,webrtc,音视频等等视频。
![6886eb4ab186e87edfede703c08ed2ff.png](https://i-blog.csdnimg.cn/blog_migrate/585a884f93ffc3daa1c6fb29bc82dcda.jpeg)
![6fd889b24acc41945e5711a71a42fbce.png](https://i-blog.csdnimg.cn/blog_migrate/d5977bcc793f13309790ddac681de097.jpeg)