【AICon】 如何构建高效的 RAG 系统?RAG 技术在实际应用中遇到的挑战及应对策略?>>> 了解详情
写点什么

苏宁即时通信系统改造实践

  • 2019-04-02
  • 本文字数:3403 字

    阅读完需:约 11 分钟

苏宁即时通信系统改造实践

一、从外采即时通信系统到自研

苏宁最早出于办公的需要,考虑到外网访问权限控制及企业数据安全,没有采用 QQ、微信这类公有云部署的聊天软件,而是采购了 IBM 的 ST 在公司内做私有化部署。随着日常办公中企业定制化需求的深入,业务部门对 IM 和 OA 一体化诉求的日益凸显,ST 逐渐无法胜任,于是苏宁自研了一套 IM 系统。


苏宁产品定位的发展历程,从基础通讯,到企业办公、社交一体化,再到纯对内办公用途,最终服务于内同时对外提供一体化工作平台。系统架构也随着产品定位和产品架构的改变而改变,经历了从基于 XMPP 开源框架搭建的 1.0 系统到纯自研的 2.0 系统,直至目前正在研发的办公一体化、多活高可用、组件化、可轻量化灵活部署的 3.0 系统。

二、基于 XMPP 的 1.0 系统



上图所示的是苏宁构建于 XMPP 协议系统的实现原理。在实现上每个独立的 Node Server 都包含完整的业务逻辑模块,服务器和服务器之间均建有长连接通道用于交换报文。通过消息的已达已读回执,来确保消息的可靠传输。


上述实现方式有以下四个主要弊病:


1.由于 Node 之间均需维持长连接,随着服务端的横向扩展,长连接数是 N*(N-1),增长非常快。


2.每台服务器都部署全量的服务,在部署上是种浪费,也不利于单个服务的升级和维护。


3.XMPP 报文按照 xml 格式定义,三种通讯原语 message、presence 和 iq 的无效载荷非常重,按以下所示,即使不携带任何信息,头部至少也是上百字节(1 字符=2 字节),如果用 iq 实现业务层面的心跳,那也是上百字节。


<message    to="lily@jabber.org/contact"    type="chat" >     <body> 你好,在忙吗</body> </message> 
<presence from="alice@wonderland.lit/pda"> <show>xa</show> <status>down the rabbit hole!</status> </presence>
<iq from="alice@wonderland.lit/pda" id="rr82a1z7" to="alice@wonderland.lit" type="get"> <query xmlns="jabber:iq:roster"/> </iq>
复制代码


4.XMPP 框架下的标准聊天消息以 id 为关键字,已经在本地的消息,往往会在对服务端的历史消息请求中,再次被拉取,无法做到按需增补、查漏补缺。究其本质,是这种消息结构的设置,无法完成增量比对。


采用 XMPP 协议也有以下三个主要优点:


1.XMPP 有很多开源框架支撑,Ios 端有 XMPPFramework,java 的有 smack。能快速的开发和搭建自己的系统。


2.默认支持 SASL 和 TLS 的通道加密,传输更安全。


3.XMPP 实体的地址称为 Jabber Identifier 或 JID,作用相当于用户 id,其格式为:[node’@’]domain[’/'resource],在组网上也配有协议网关。这就支持了与其他通信系统(如 AIM、ICQ、IRC、MSN Massager、RSS0.9 和 Yahoo Massager)的互通,也可以在架构上支持多域名的部署及互通。


三、自研 2.0 系统



为了解决 1.0 系统的上述问题,同时支持高可用、支持 SaaS 多企业,苏宁开发了自研 2.0 系统。


在系统架构层面:


  • 服务端将接入层 Node Server 做薄,只负责通信接入以及协议解析,使用 netty 作为 NIO 通信层框架,同时将所有业务逻辑归并到业务逻辑层 Center Server,Node 和 Center Server 都可以自由扩展, Node 和 Center Server 建立长连接通道交换数据。

  • Node 实现协议转换层和兼容 XMPP 连接方式,重构过渡期支持新老客户端互通。

  • 提供单独的 passport,支持 OAuth 方式与其他账号体系联合登陆。


在业务逻辑层面:


  • 支持多企业,苏宁作为一个独立的企业,企业之间互相隔离;

  • 优化了消息归档机制;

  • 部分数据实体增加了版本号,变更拉取更省流量;

  • 消息按会话增加了 long 型序列号,离线消息由推送变成按需拉取,消息状态及已达已阅,通过消息区间来计算实现;

  • 单点登录 SOA;

  • 增加批量接口、合并推送。


高可用的基本要求是无单点故障,基本方法是分层 (分而治之) 与冗余 (失效转移),苏宁采取了以下措施:


  • 在应用层:负载均衡,集群;

  • 在数据层:主从复制,读写分离;

  • 在软件质量控制上:制定代码规范标准,代码控制,自动化测试,支持灰度发布;

  • 在日志与监控上:服务端接入调用链监控,客户端接入稳定性、性能监控。

四、消息的多端同步、终端消息的防乱序防丢失办法

2.0 系统业务逻辑层面的最大变化在于对消息的处理。因为 IM 系统的核心问题就是要解决聊天消息的离线和在线处理,解决好这个,系统问题就等于解决了一半。


我们想到的是两点:


1.移除离线缓冲,变离线消息推送为上线后终端的按需拉取,确保离线消息在各个客户端上均能被同步、按需补充。


2.作为配套算法,解决在线消息推送至终端时展示乱序的问题。


为了做到这个我们的技术方案为:


1.除消息的 uuid(全局唯一标识)和 ts(时间戳)以外,给消息定义 long 类型的 seq(序列号),按会话独立编号,编号从 1 开始必须连续。服务端需保证任意两条同一会话内的消息,seq1 > seq2、ts1 > ts2 互为充要条件;


2.终端上线后,由终端主动获取最近会话列表,从而得到每个会话的最大 seq。在某个会话需要展示消息时,检查该会话当前的本地消息区间,向消息服务端请求本地缺失的消息,请求以 seq 区间为参数发起批量请求。



3.终端在收到推送消息后,如果推送消息的 seq 与会话的最后一条消息的 seq 不连续,则先把消息加入到对应的缓冲窗口,并启动定时器。在收到后续的推送消息时,先检查缓冲窗口,把连续的一批消息退出窗口并写入数据库、展示给用户。如果超过定时器的时长,消息 seq 还未接续,则说明消息在传输过程中发生丢失,不再等待,一次性把窗口中的消息写入数据库并展示。丢失消息的补充,则通过前述的终端主动拉取来实现。




苏宁与业内典型的离线消息处理方案的差别如下图:



1.移除了离线缓冲和配套数据库


2.流程 1 改为请求最近会话的最大 seq


3.流程 3 返回最近会话的最大 seq


4.流程 4、6 改为上述技术方案图示的按需拉取

五、对于高性能移动端架构的一些想法

由于用户对 IM 系统的体验是通过终端来感知的,所谓的高性能,最终还是要靠终端的算法来完成。


而具体到高性能的移动端设计这块,我觉得主要弄好以下几点:


1.需要独立的组件用于支撑登陆账号和网络协议这块。



2.在协议层上构建逻辑层,对于移动端的上传下载、接口调用、内部算法调用,都要有统一的线程池管理。其他服务,如断线重连、心跳服务,数据库 DAO 服务,缓冲服务等都在逻辑层统一封装和控制。


3.服务端推送的变更,要先在数据库生效,再通知 UI 层生效,走消息总线通知。通知尽量细分颗粒度,变更的数据携带在通知中,避免通知接收方再去查数据库。


4.如果数据库使用的是系统默认的 SQLite,要避免在主线程直接进行任何数据库操作(增删改查),因为 SQLite 并发锁的颗粒度是文件级别的,会导致后台线程的数据库操作阻塞前台的。一方面,我们要识别和优化端上最慢的数据库操作的耗时,另一方面,全在后台操作数据库,界面就不会随机卡顿。


5.在 UI 层还涉及到要防跳帧(用户可感知的 60 帧/秒–16ms/帧)。这需要持续关注和简化各个 UI 布局的嵌套层次,从而减少布局尺寸计算和渲染的开销。另外在 android 端需要特别关注内存抖动引发的跳帧:避免高频调用的方法中分配局部大对象频繁触发大 GC,从而挂起主线程造成跳帧。


6.没有 6 了,一时大脑堵塞了。

六、正在研发的 3.0 系统

移动办公已成为企业提效、降成本的有效手段之一,在企业建设移动信息化的过程中,存在以下建设痛点:



  • 内部沟通渠道混乱,信息外泄风险大

  • 移动业务繁多,使用和管理混乱

  • 信息系统孤岛现象严重,相互隔离

  • 缺乏通用办公应用及个性化应用开发能力


为此苏宁正在研发办公一体化的 3.0 系统,具体的产品和技术架构稍后公司会通过正式渠道对外公布。

七、结语

个人技术面偏移动端架构,涉及服务端的实现可能阐述的不够透彻,唯希望能以有限文字多少给后来者提供些借鉴吧,谢谢。

作者简介

陈思佳,苏宁科技集团移动端资深架构师,主要负责苏宁移动通讯、IoT 、一体化工作平台等项目研发工作。在移动端架构方面拥有十多年的实践经验,先后就职于华为无线产品线、Motorola GSG(Global Software Group)。精通 Android、iOS 编程架构、开发工具,对 IM 协议及架构也有深厚积累。


赵一唯,苏宁科技集团服务端资深架构师,主要负责易适配、邮件系统、移动办公一体化平台等项目研发工作,并为 IM 产品线技术第一负责人。在分布式架构方面拥有十多年的实践经验,先后就职于 ZTE 中兴通讯、趋势科技、IBM 等公司。精通 java 服务端编程,对多活、高可用的解决方案有独到见解,在 IM 协议及架构方面也有深厚积累。


更多内容,请关注前端之巅。



2019-04-02 08:003466

评论

发布
暂无评论
发现更多内容

架构师训练营—第七周学习总结

orchid9

第七周架构师训练学习笔记

郎哲158

极客大学架构师训练营

极客时间 - 架构师一期 - 第七周作业

_

极客大学架构师训练营 第七周作业

Newbe.ObjectVisitor 0.2.10 发布,更花里胡哨

newbe36524

C# dotnet

架构师训练营 2 期 - 第三周总结

Geek_no_one

极客大学架构师训练营

架构师训练营week07作业

FG佳

极客大学架构师训练营 week07

架构师训练营第三周总结

张浩

第七周总结

睁眼看世界

极客大学架构师训练营

手写单例

落朽

训练营第七周作业2

仲夏

第七周作业

极客大学架构师训练营

性能压测

橘子皮嚼着不脆

架构师训练营第二期 Week 3 作业

bigxiang

极客大学架构师训练营

第七周命题作业

orchid9

架构是训练营-第三周总结

架构师训练营 1 期第 7 周:性能优化(一)- 作业

灵霄

极客大学架构师训练营

架构师训练营 2 期 - 第 3 周命题作业

Geek_no_one

极客大学架构师训练营

训练营第七周作业 1

仲夏

极客大学架构师训练营

「架构师训练营第 1 期」第七周作业

张国荣

架构师训练营-单例模式

三周学习总结

水浴清风

AI会取代人类劳动吗?

脑极体

架构师训练营第三周作业-手写单例模式

张浩

架构师训练营week07总结

FG佳

一期二班-吴水金-第五课总结

吴水金

架构师训练营 Week03 作业-手写单例模式

Fedora32安装MySQL8

ilovealt

MySQL Linux

架构师训练营第 1 期 week7

张建亮

极客大学架构师训练营

架构师训练营第七周作业

郎哲158

极客大学架构师训练营

Architecture Phase1 Week7:HomeWork

phylony-lu

极客大学架构师训练营

第七周作业(作业一)

Geek_83908e

极客大学架构师训练营

苏宁即时通信系统改造实践_语言 & 开发_赵一唯_InfoQ精选文章