汽车之家IM即时通讯平台技术分享

早期之家在C端产品的即时通信功能是直接使用第三方商业软件服务(SaaS),功能扩展性上存在很大制约,某些定制化业务需求很难实现,考虑到后续业务发展需要、数据安全、内容实时审核及性能、自主可控高可用架构等因素,决定自主开发IM即时通信平台并逐步迭代替换。

2.1网络通信框架

Netty具备如下优点:

1.入门简单,文档齐全,无其他依赖,只依赖JDK就够了;

2.使用简单,预置了多种编解码功能,支持多种主流协议,对大量常用操作进行了封装,减少开发周期;

3.高性能,高吞吐,低延迟,资源消耗少;

4.灵活的线程模型,支持阻塞和非阻塞的I/O模型;

5.代码质量高,目前主流版本基本没有Bug;

6.社区活跃,版本迭代周期短,发现的BUG可以被及时修复,同时,更多的新功能会加入;

7.经历了大规模的商业应用考验,稳定性得到验证。

2.2通信协议

TCP是个“流”协议,就是没有界限的一串数据,数据传输时可能会存多包或半包传输的情况,原因如下:

1.应用程序写入字节大小于套接口发送缓冲区大小;

2.进行MSS大小的TCP分段;

3.以太网帧的payload大于MTU进行IP分片

解决策略

1.消息定长,例如每个报文大小固定200字节,如果不够,空位补空格。

2.用回车符进行分割,例如FTP协议。

3.约定特殊字符作为消息结束标记。

4.将消息分为消息头和消息体,消息头中包含表示消息总长度(或消息体长度)

5.更复杂的应用层协议。

按约定的方式编解码保证数据完整性,就是通信协议。将消息分为消息头和消息体是最常见的协议设计方式(定长消息头,可变长度消息体),如下图:

消息头

固定长度字节来标记消息类型,及消息体字节长度。

消息体

可以使用文本、XML、JSON、Protobuf等扩展性好的数据格式,尽量考虑以下几点:

1.精简消息体大小,不要有冗余数据,减少网络带宽占用(尤其是大量用户发消息群聊场景下),提高传输效率

2.数据安全性(例如加密传输)

3.编码效率及可扩展性

除了自己设计实现通信协议,还可以直接使用现成的设计好的公开协议,如目前比较流行的websocket协议,相对于私有协议有以下优点:

1.浏览器直接支持,方便web端接入

3.很多框架包括Netty都自带实现了websocket协议解码器。

客户端:用户收发消息终端

接入层:为客户端连接、收发消息、关系建立提供入口

数据层:负责各类业务逻辑数据及消息数据缓存或持久化存储,及消息指令的分发渠道。

3.1消息设置

聊天场景常见的消息类型通常有:文本、图片、表情、语音,视频。我们把消息分为消息类型,及消息内容两部分,客户端通过识别消息类型去解析消息内容并展示,像图片视频等消息,并不需要通过消息即时传递其内容,而是先将图片或视频上传到文件服务器,消息中只需要把uri带过去,并且带上base64编码的缩略图即可,如下示例:

msgType:msg_image

消息下发流程如下图:

如图,整体思路是将上行消息通过webapi写入消息队列,socket服务器通过消息队列或离线消息库进行增量消息分发同步。

socket服务承载连接着所有在线用户,发生部署上线将会导致所有在线用户断开重连,瞬间大量增加其它服务器的连接压力,且对部分用户行为可能会有短暂的影响,上行消息通过webAPI实现,统一了消息入口,方便各类渠道消息的接入,并且使得socket服务的职责变得简单单一,仅用于保持连接和推送消息,上行消息业务逻辑频繁变动时仅需要重新部署webAPI,对用户基本无感知。

还有一些建议是,对消息进行合并,压缩能极大提升消息推送吞吐能力,减少带宽占用,经测试十条以上消息压缩率能达到80%左右;细分消息队列,按不同维度拆分消息队列可以分散压力防止某类消息高峰期对其它业务消息造成延迟推送,保证其它消息的时效性,比如可以按场景用户消息,系统指令等各自使用独立的消息队列。

3.2消息扩散

消息扩散分发是im设计的重点,尤其是一对多的场景,如群聊。简单的说就是每条消息需要扩散给群里所有人收到,通常有两种方式,读扩散,写扩散。什么是读扩散?什么是写扩散?

读扩散:

描述:每条消息只存一份,群组所有成员读取这一份数据。

优点:节省存储空间,无写入压力。

缺点:

1.获取离线增量消息逻辑复杂,需要根据用户所有会话关系去遍历获取,且并未知道会话是否有增量消息,会造成大量无效空读,效率极慢。

2.针对消息做单个用户个性化操作时设计会变的麻烦,比如其中一个用户删除消息,已读回执等操作时,不能去影响其它用户的视角。

写扩散:

描述:每个用户有独立的消息列表,每条消息给所有消息关联人同步一份副本。

优点:读取逻辑简单,效率极快,通过用户自身消息列表一次性获取所有离线增量消息即可,用户个性化操作实现简单,不会影响其它用户的视角。

缺点:存储空间增加,写入压力较大。

两种方案如图所示:

对比两种消息扩散方案优缺点都比较明确,同时也都面临无法接受的极端情况,比如读扩散,如果某用户拥有巨量会话,那他每次上线时读取消息就是灾难,再如写扩散,如遇到万人群,每条消息都会产生一万分副本,作为设计者必须根据实际情况从逻辑上去结合两种方案来平衡读写压力。

3.3IMSDK架构构图

IMSDK架构按模块分工可以分为中间件层、核心层、协议层。

中间件层

负责请求连接时需要的Token,以及对Token的缓存、Token过期更新等逻辑。当App启动之后平台层会设置用户信息到中间件,中间件根据设置的用户信息判断本地是否缓存该用户的Token,如果有则直接用该Token进行连接;如果没有则会请求接口获取Token。获取到之后使用获取到的Token进行连接,连接成功之后将该Token本地缓存,方便下次使用。如果连接过程中服务器端返回Token过期的错误,客户端会删除掉本地缓存的Token,并重新请求Token进行再次连接。

核心层

包含连接模块、监听模块、API封装模块、日志模块、本地数据库模块。连接模块负责Socket的连接、保活、断线重连、断开、收发消息等操作,连接模块每隔50秒发送一次ping来保活,连接模块重连机制是2秒、4秒、8秒、16秒等2的n次方逐渐增加,当重试次数到10次后会认为当前网络有问题,不再重试,等待监听网络变化或者前后台切换之后再次重试;监听模块当收到会话变更、消息变更、连接状态变更时将变更内容通知到所有注册监听的业务层,业务层根据收到的通知做出相应处理。

协议层

主要负责跟服务端通讯内容的编解码工作,包括消息的编解码、会话的编解码、命令的编解码等工作,协议层将收到的数据进行解析,区分出诸如收到新消息、删除消息、撤回消息、增加会话、删除会话、会话更新等行为,同时将收到的数据解码成消息或者会话Model传递到上层,通知到业务层。

3.4连接流程图

App需要同AppServer进行数据交互,获取IM连接需要的Token数据,并且AppServer负责维护业务数据,如用户数据、会话数据、好友关系等;

App通过Token数据与IMServer进行连接,建立数据通道实现消息的实时接收与推送功能;

IMServer维护App的连接状态,在接收实时消息时判断用户是否在线,将消息转发给目标设备或保存为离线消息;

会话及气泡:

在面对特殊用户会话较多时每次从服务拉取会话信息时将面临较大压力,我们采用本地和服务端结合方案实现,本地缓存一份会话,接收消息对会话气泡进行叠加,本地会话设置发生变更如免打扰,隐藏会话,已读消息等,上报给服务端,服务端在发生好友关系或加入群组等操作时产生会话,或会话信息变更时也会对本地进行同步,服务器和本地之间会话同步包括连接时同步、实时同步、主动同步。

连接时同步:用户每次连接时会向服务器传递会话唯一标识,服务端通过用户传递的标识进行逻辑判断并向用户推送会话数据,包括全部会话和增量会话,SDK接收到会话数据后进行本地的新增、修改、删除操作,并通知给UI层,本地会话“标识”由服务端每次同步会话时提供。

实时同步:本地会话修改会通知给服务端,服务端接收到会话信息变更时,会即时通过IM推送给SDK,其中包括新增、修改、删除会话的操作,SDK接收到会话数据后进行本地的新增、修改、删除操作,并通知给UI层。

主动同步:客户端接收到不存在的会话消息时,会主动向服务器获取此会话信息进行本地保存并通知UI层。

会话部分字段:

单聊:两个用户之间进行一对一的聊天,聊天消息可以持久化保存至本地进行查看。

群组:两个或两个以上的用户在同一个会话中进行聊天,发送的消息会被群组所有成员接收并可以持久

化保存至本地进行查看。

公众号:企业或官方通过系统账号向单个或多个账号推送消息,消息可以持久化保存至本地进行查看。

聊天室:一个或多个用户在同一个会话中进行聊天,发送的消息会被推送至当前聊天室中所有用户,用户接收端消息不会保存本地。

4.服务器优化

我们系统的设计要求是单机百万连接支持、下行消息QPS一百万。由于一个连接会占用一个文件描述符,首先就要对系统的文件描述符上限做调整,让服务器能够支持百万级连接的建立;

#/etc/security/limits.conf

*softnporc1500000

*hardnporc1500000

*softnofile1500000

*hardnofile1500000

#/etc/sysctl.conf

fs.nr_open=3000000

fs.file-max=3000000

网卡收到数据帧后,将数据帧以DMA的方式拷贝到内存的RingBuffer中,该步骤不需要CPU的参与。当拷贝完成后,网卡便会触发一个网卡硬件中断,CPU必须立即响应硬件中断,CPU根据中断类型,在中断注册表中查找对应的中断处理程序,然后调用网卡注册的中断处理程序(网卡驱动),此后网卡驱动程序触发一个软中断,自此硬件中断返回,硬中断不会做过多事情,它只负责通知驱动有数据到达,具体的操作由软中断过程来处理。

DMA是DirectMemoryAccess,直接存储器访问。在DMA出现之前,CPU与外设之间的数据传送方式有程序传送方式、中断传送方式。CPU是通过系统总线与其他部件连接并进行数据传输,DMA就是指外部设备不通过CPU而直接与系统内存交换数据的接口技术。

RingBuffer网卡环形缓冲区,如果该缓冲区被占满,新到来的数据包将会被丢弃,从而导致丢包。把该缓冲区由原来的512调整到2048后,丢包问题得以解决,方法如下:

查看当前Buffer

ethtool-gem1

Ringparametersforem1:

Pre-setmaximums:

RX:4096

RXMini:0

RXJumbo:0

TX:4096

Currenthardwaresettings:

ethtool-Gem1rx2048

ethtool-Gem1tx2048

修改

ethtool-Gem1rx4096

ethtool-Gem1tx4096

4.1设置网卡队列

当网卡收到报文时,通过Hash包头的SIP、SPort、DIP、DPort四元组信息,将数据投递到相应的网卡队列,同时会触发该队列绑定的中断,通知CPU进一步处理;由此可知CPU使用不均衡,无非就是两个原因,队列收到的数据包不均衡或者CPU与网卡队列绑定不合理导致;

#设定网卡队列

ethtool-Lem1combined16

4.2网卡中断号

InterruptRequest,简称IRQ,中断就是由硬件或软件所发送的中断请求信号。系统上的每个硬件设备都会被分配一个IRQ号,通过这个唯一的IRQ号就能区是来自哪个硬件了。开启了多队列的网卡,每个队列都会有唯一的中断号。

#查看网卡队列中断号

4.3CPU亲和力绑定

把每个网卡队列与CPU一一绑定,均衡CPU的使用

#CPU绑定

echo/proc/irq/107/smp_affinity_list0

echo/proc/irq/108/smp_affinity_list1

中断号为107的队列绑定0号CPU,中断号为108的队列绑定1号CPU,依此类推,每个网卡队列都需要绑定到不同的CPU核上,这样我们就完成了网卡队列的设置以及与CPU的绑定。

这里还有个问题是,CPU不紧要处理网路数据,还要处理Nginx应用,这个时候CPU资源的分配要根据具体的压测情况进行调整;

4.4IntelFlowDirector

上面提到投递到网卡队列的数据包是均衡的,如何能做到均衡呢?有个办法是使用Intel以太网FD(FlowDirector)技术,自定义数据包投递规则,应用监听多个端口,不同目标端口的数据包按制定的规则投递到相应的网卡队列,从而达到均衡数据包的目的,进而均衡CPU的使用;

#数据投递规则根据目的端口把数据投递到不同队列

至此网卡丢包以及CPU使用率不均衡的问题得到解决,基本就是解决了客户端接收数据毛刺的问题;

4.5其他优化

对部分需要更高时时性及稳定的用户,如客服、商家号等,可以增加专用服务器来应对,专用服务器通常接入量较小,连接和消息推送都会更稳定快速。

增加备用域名(不同cdn),在连接失败重试过程中使用可有效减少外部网络波动带来的影响,使系统更加稳定可靠。我们之前有一次线上故障,使用的第三方的即时通讯服务,

为提高连接效率及服务器连接压力SDK增加了token缓存机制,IM连接成功后,会将token进行本地缓存,当设备再次触发连接时,会优先检查本地是否存在token,如存在立刻使用缓存数据进行连接,若不存在或过期会向服务器获取新token数据进行连接,连接成功后将新Token缓存本地。

SDK具备自动重连机制,在整个应用全局只需要调用一次连接即可,连接异常断开后会启动重连机制进行多次重连,在这之后如果仍没有连接成功,还会在当检测到设备网络状态变化时再次进行重连。

心跳保活,为了保持客户端和服务端的实时双向通信,需要确保客户端和服务端之间的TCP通道保持连接不断开,IM连接成功后,SDK每间隔50秒会向服务器发送一个ping包,服务器接收到ping包后立即响应一个pong包,如果服务在120秒内检查没有收到过ping包会立即断开此连接,释放资源。SDK在检测断开后会自动触发重连机制。

发送方->接收方:ping

接收放->发送方:pong

5.总结

作者简介

林道辉

■C端及中台产研中心-看选技术团队

■2012年加入汽车之家,目前主要负责参与热聊业务及之家im通信平台架构及研发工作。

THE END
1.掌握API接口:精准查询车辆信息的实用秘籍大公开在现代社会,我们经常需要查询车辆信息,无论是为了买车、租车还是处理交通事故等。然而,传统的查询方式往往耗时耗力,效率低下。因此,今天我将向大家介绍一个非常实用的API接口,可以帮助我们准确快速地查询车辆信息。 这个API接口可以查询人车关系、车辆出险报告和车辆信息,识别率高达90%以上。具体来说,它可以帮助我们查询https://blog.csdn.net/m0_57991918/article/details/144156446
2.宁波均联智及申请车载影像相关专利,解决冷启动车载影像出图慢问题金融界2024年12月4日消息,国家知识产权局信息显示,宁波均联智及信息技术服务有限公司申请一项名为“一种车载影像的图像处理方法、图像处理系统及车辆”的专利,公开号 CN 119065776 A,申请日期为2024年11月。 专利摘要显示,本申请提供了一种车载影像的图像处理方法、图像处理系统及车辆,车载影像包括控件模块;图像处理方https://www.dongchedi.com/article/7444523467703058980
3.www.scmc四魔图片库美女图片 1天前 黄片黄片黄片黄片黄片 日产精品无码一级毛片 7天前 动漫 享受 得到 玩偶 兔子 wwwxxx性视频 5天前 护士好爽20p 美女脱内衣让男人桶爽黑丝 9天前 永濑唯miaa146中文字幕在线 国产近期操逼免费 0天前 亚洲免费3 甜蜜惩罚二季免费观看动漫 1天前 国产av一区二区三区老鸭窝http://www.scmc-xa.com/xxxr508317
4.www.jxmzxx.com{$woaini}>www.jxmzxx.com{$woaini}至于这款新车能不能受到消费者的认可,关键还要看价格。如果上汽奥迪能够“放下身架”和国产同级别的电动汽车同价位竞争的话,也不排除它会热销的可能性。最后,对于上汽奥迪发布的AUDI E,您有什么看法? 新华社昆明12月2日电(记者林碧锋、黄韬铭)据中国地震台网正式测定:12月2日1时36分在云南德宏傣族景颇族自治州http://www.jxmzxx.com/appnews/031241
5.已支持的视觉智能服务及api列表ListFaceDbs 查看人脸数据库列表。 AddFaceEntity 向人脸数据库中添加人脸样本数据。 GetFaceEntity 查询人脸数据库中的人脸样本数据。 ListFaceEntities 查询人脸数据库中的人脸样本列表。 UpdateFaceEntity 更新人脸数据库中的人脸样本数据。 AddFace 为指定数据库添加人脸数据。 SearchFace 根据输入图片,可以在数据库中https://help.aliyun.com/document_detail/161463.html
6.Nosql图数据库图数据库是什么图数据库(Graph database)并非指存储图片的数据库,而是以图这种数据结构存储和查询数据。 图形数据库是一种在线数据库管理系统,具有处理图形数据模型的创建,读取,更新和删除(CRUD)操作。 与其他数据库不同,关系在图数据库中占首要地位。这意味着应用程序不必使用外键或带外处理(如MapReduce)来推断数据连接。 https://www.jianshu.com/p/d1e426470c7a
7.摄图网正版高清图片免费下载摄图云库 便捷的企业私有图库 摄图API 轻松获取海量版权素材 商品定制 个性定制,一件起订 视频在线编辑 一键嵌套,极速出片 图片在线编辑 0基础做出好设计 定制拍摄/设计 轻松获取海量版权素材全站通VIP 860万创意内容 十大分类海量下载 立即开通 终身VIP 限量抢购 照片VIP 插画VIP 创意背景VIP 免抠元素https://699pic.com/
8.www.cole原神琴乳液狂飙图片 无翼乌邪恶漫画漫画_漫画搜索_动漫屋_36氪 409.44MB 22好评 操她下面xx偷拍蜜柚app下载汅API免费下载 378.25MB 9402好评 《绿巨人无限看丝瓜ios破解版》最新高清完整版免费在线拔萝卜电视剧高清免费观看全集大牛影库 870.42MB 492好评 国产乱伦bbw 天美传媒thetm.em_三联生活http://www.cole-ec.com/mabbt56918566/669983.html
9.u9a7eu8003u5b9du5178u6781u901fu7248隐私政策(详细版)分别需要获取相机、相册(iOS)/读取外部存储(Andorid)权限。图片文件将上传到u9a7eu8003u5b9du5178u6781u901fu7248App服务器并调用阿里云OCR API(即应用程序接口。由阿里云计算有限公司提供 官网:https://ai.aliyun.com/ocr联系电话:400-80-13260)识别图中文字。图片文件将在上http://laofuzi.kakamobi.com/agreements/privateAgreement.html?_productCategory=jiakaobaodian&_product=u9a7eu8003u5b9du5178u6781u901fu7248&_appName=jiakaokemusi
10.3650000免费图库api:随机生成小姐姐图片3650000随机API提供了好多免费api接口,大部分都是图库壁纸的,官方有简单的参数和文档说明。 1.使用示例 随机生成图片 https://3650000.xyz/api/?type=img 2.API地址 http://3650000.xyz/api/ http://3650000.xyzhttps://www.4spaces.org/1241.html
11.数据科学实战手册(R+Python)1.获取:数据科学管道的第一步是从不同来源获取数据,包含传统数据库、NoSQL、文件、网页抓取、分布式文件存储系统(如Hadoop平台上的HDFS、RESTful API、文本文件),甚至还包括PDF(当然但愿不要是这种形式)。 2.探索和理解:第二步是要理解你要分析的数据,以及要理解数据是如何采集的;这一步经常需要做一些显著性的探https://www.epubit.com/bookDetails?id=N5839
12.聚美智数车型库查询车型大全车系大全车型识别【聚美智数】车型库查询-车型大全-车系大全-车型识别-汽车标志-车型车系查询是基于腾讯云的服务,【车型库车型大全车系大全汽车标志大全】通过VIN解析后可匹配相关车型,查询车型车系详细信息,为了更好的匹配,建议与聚美VIN查询接口配套使用。—— 我们只做精品!https://market.cloud.tencent.com/products/28013
13.一入门·ApacheCN深度学习译文集·看云它拥有最大的社区和库支持生态系统。 用于 Python 的 TensorFlow API 是最完整的,因此,Python 是首选的自然语言。 Python 有两个版本-Python2.x 和 Python3.x。 在本书中,我们将讨论 Python3.x。 这种选择有几个原因: 到2020 年,Python 2.x 的开发将停止,因此,Python3.x 是 Python 的未来 Python 3.xhttps://www.kancloud.cn/apachecn/apachecn-dl-zh/1956114
14.Springboot+Vue实现将图片和表单一起提交到后端,同时将图片地址保存到60%"label-width="100px"class="demo-ruleForm"><el-form-itemlabel="汽车押金"prop="guarantee_money"><el-inputv-model="ruleForm.guarantee_money"placeholder="请输入汽车押金"></el-input></el-form-item><el-form-itemlabel="上传图片"prop="imageUrl"><el-uploadclass="avatar-uploader"action="hthttps://www.cnblogs.com/zheng-yuzhu/p/16633991.html
15.优设读报优设网梁良表示,人人影视的初衷是将翻译的字幕分享给更多爱好者,而且他提到正在研究将人人影视数据库转型为字节跳动 AI 助手豆包新增图片理解功能,已在 App 及 PC 端上线。用户上传图片后,豆包能迅速识别内容04OpenAI 发布强化微调 API,深度定制超复杂大模型 OpenAI 近日发布了“强化微调”计划,允许开发者利用专家https://www.uisdc.com/news
16.车系查询车系查询API接口标准化API接口聚合数据API>车系查询 车系查询 维护中 车系型号、报价、颜色等基本信息查询 客服 收藏 产品功能 接口文档 功能介绍 车系型号查询 用户可以通过输入车系名称或关键词,查询与车系相关的型号信息,包括车型名称、车型代码等。 报价查询 用户可以查询特定车型的市场报价信息,包括新车和二手车的价格范围、配置等。 https://www.juhe.cn/docs/api/id/74
17.版权图库高清图片素材版权图库?数千万张高清图片,创建你的精美设计 字体库?摆脱版权桎梏,轻松、高效的完成创意设计需求设计场景设计场景 在线设计 海报设计 Logo设计 简历设计API 使用教程?详尽的功能教学与设计技巧,为你在Canva可画的设计之旅保驾护航。 设计学院?看点好玩的设计资讯,也学点实用的设计技巧。 创作者计划?https://www.canva.cn/learn/creative-template/
18.VivaGraphJS首页文档和下载JS绘制图形库OSCHINAVivaGraphJS 是一个 JavaScript 库,用来在网页上进行图形绘制。旨在扩展和支持不同的渲染引擎和布局算法,当前支持通过 SVG 和 CSS 进行图形渲染。 示例代码: var graph = Viva.Graph.graph(); graph.addNode(1); graph.addNode(2); graph.addLink(1, 2); var renderer = Viva.Graph.View.renderer(graph)https://www.oschina.net/p/vivagraphjs
19.免费素材图片免费素材图片和视频,可以在任何地方使用。? 高质量 ? 100% 免费? 无需注明归属https://www.pexels.com/