Jack Jiang

我的最新工程MobileIMSDK:http://git.oschina.net/jackjiang/MobileIMSDK
posts - 487, comments - 13, trackbacks - 0, articles - 1

2025年2月5日

本文由B端技术中心资深开发工程师马家忆分享,原题“B站在实时音视频技术领域的探索与实践”,下文进行了排版和内容优化。

1、引言

直播行业从传统的娱乐直播发展到教育直播、电商直播等形式,产生了很多新的玩法。传统的直播是一位主播展示才艺,观众通过弹幕、送礼物等方式进行互动。随着网络质量不断地提高,用户也对直播平台产生的新的要求,实时互动直播的场景就出现了,观众可以同时观看多位主播之间互动的画面,让直播间的气氛更好。B站直播的连麦PK、视频连线业务就提供了这个能力。主播看到的是对方主播实时的流(延迟400ms以内),而观众看到的是“准实时”的流(延迟2~5s左右)。

本文讲述搭建这样一套最新流行的实时视频直播系统需要了解的背景知识以及系统的整体架构,希望对大家有帮助。

2、系列文章

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

视频直播技术干货(一):揭秘百万级粉丝互动的Facebook实时视频直播

视频直播技术干货(二):P2P技术如何将实时视频直播带宽降低75%?

视频直播技术干货(三):实时直播答题系统的实现思路与技术难点分享

视频直播技术干货(四):首次披露快手是如何做到百万观众同场看直播仍能秒开且不卡顿的?

视频直播技术干货(五):七牛云使用QUIC协议实现实时视频直播0卡顿

视频直播技术干货(六):新浪微博实时直播答题的百万高并发架构实践

视频直播技术干货(七):实时视频直播首屏耗时400ms内的优化实践

视频直播技术干货(八):淘宝高清、低延时的实时视频直播技术解密

视频直播技术干货(九):千万级直播系统后端架构设计的方方面面

视频直播技术干货(十):一文读懂主流视频直播系统的推拉流架构、传输协议等

视频直播技术干货(十一):超低延时视频直播技术的演进之路

视频直播技术干货(十二):从入门到放弃,快速学习Android端直播技术

视频直播技术干货(十三):B站实时视频直播技术实践和音视频知识入门》(* 本文

3、关于作者

马家忆:B端技术中心资深开发工程师。

4、实时音视频关键技术概述

从0到1搭建一套实时音视频系统并支撑现有的业务,如果没有接触过这方面的东西会感觉无从下手。

我们可以看到,1996年IETF就推出了RTP协议用于实时音视频传输,2011年Google推出了WebRTC用于网页端实时音视频通话(见《了不起的WebRTC:生态日趋完善,或将实时音视频技术白菜化》)。

从这些现有的协议和项目中,我们可以发现实时音视频技术的关键点,评估自身现有的基础组件支持情况并结合业务场景寻找适合自己的解决方案。

5、关键技术1:传输协议

RTP协议(Real-time Transport Protocol)定义了在互联网上传输实时音视频数据的标准格式,属于应用层协议。RFC 3550描述RTP协议的传输层主要使用UDP,RFC 4571描述了RTP协议的TCP传输方式。

在我们的实时音视频场景中应当优先选择UDP,理由如下:

1)TCP保证数据流的可靠性和顺序性。TCP的超时重传策略为了保证通用和公平,相对比较保守,重传超时时间(RTO)可能会变的很大。假如中途丢失一个包,后续的包即使先到达也要缓存起来等待重传完成以后才能送到应用层。在网络状况不佳的情况下,使用TCP传输会产生较大的延迟;

2)UDP允许数据包丢失、乱序和重复。即使数据丢失也不会阻塞接收缓冲区等待重传,这就为实时性提供了保障。在上层的RTP协议中,协议头部包含了时间戳和序列号,可以对数据包进行重排和丢弃,解决了乱序和重复的问题。如果接收端监测到丢包,并且丢失的包是必要的且无法恢复,则发送NACK消息通知发送端重传(下一节会详细探讨这个话题)。

UDP虽然在低延迟领域上有压倒性的优势,但是用户侧有可能存在防火墙拦截所有的UDP包。考虑到在网络环境足够好的情况下使用TCP也能达到不错的效果,因此我们做了一个降级策略,优先使用UDP,当且仅当UDP不通的时候使用TCP。

6、关键技术2:丢包补偿

前面讲到我们的传输层协议优先选择UDP,那么就需要引入一些机制解决丢包问题。

前向纠错FEC(Forward Error Correction)指的是发送端发送原始数据的同时附加部分冗余的信息,如果接收端检测到原始数据丢失则尝试使用冗余的信息进行恢复。发送端发送n个数据包,同时根据原始数据生成k个冗余的数据包,将n+k个数据包发送出去,接收端只要收到至少n个数据包就可以得到全部的原始数据。

FEC算法的关键在于异或。异或(Exclusive OR)是一个数学运算符,数学符号为“⊕”,两边数值转换成二进制按位运算,相同时为0,不同时为1。

以一阶冗余算法为例,n个数据包生成1个冗余包,发送n+1个数据包。我们发送三个数值分别为a、b、c,生成冗余数据x=a ⊕b ⊕ c一起发送。假如数值b在传输中丢失了,计算a ⊕c ⊕ x即可得到b。

在实际应用中,FEC没有这么简单,WebRTC实现了UlpFEC和FlexFEC,UlpFEC可以针对数据包的重要程度实施不同程度的保护以充分利用带宽,FlexFEC还支持对列做冗余,同时WebRTC默认的音频编码器Opus本身就支持FEC。

前向纠错适合少量随机丢包的场景,可以无视网络延迟时间,但是增加了带宽消耗。

后向纠错包括ARQ(Automatic Repeat Request)和PLC(Packet Loss Concealment)。ARQ指的是接收端检测到数据丢失的时候发送NACK报文请求发送端重传,适合突发大量丢包的场景,没有额外的带宽消耗,但是时效性取决于RTT,如果存在很多接收端还要考虑避免NACK风暴造成雪崩。PLC用于音频,当数据缺失时使用模型根据前后数据预测丢失的数据。

总之,前向纠错和后向纠错各有优缺点,需要搭配使用。

7、关键技术3:流量控制

流量控制指的是根据网络状况的波动估算可用带宽,根据带宽的变化自动调节音视频码率和发送速率。当网络质量变差的时候迅速降低数据量以确保实时性,网络较好时则慢慢提升数据量带来更清晰的画面。在WebRTC中提供了优秀的Google Congestion Control算法,包括基于延迟的评估和基于丢包率的评估,取两种评估方式的最小值作为目标带宽通知编码器和数据发送模块。

基于延迟的评估算法包括Transport-CC和Goog-REMB,目前最新版的WebRTC默认使用的是Transport-CC。Transport-CC在发送端进行带宽评估,接收端通过TransportFeedback RTCP包向发送端反馈每个RTP包的到达时间,发送端在一个时间窗口内计算每个RTP包到达时间与发送时间之差,通过Trendline滤波器处理后预测网络状况。假设我们当前处于Hold状态,如果检测到网络状态为OverUse,此时应该减小数据量,变更为Decrease状态;如果检测到网络状态为Normal,此时可以尝试增加数据量,变更为Increase状态。

基于丢包的评估算法是当网络突发大量丢包时的兜底策略:

  • 1)如果丢包率在2%以下的时候说明网络质量好,目标带宽增加8%;
  • 2)如果丢包率在在2%~10%说明当前发送数据的带宽和网络质量相匹配可以保持不变;
  • 3)如果丢包率大于10%说明网络质量差,目标带宽减小到(1-丢包率*0.5)* 当前带宽。

8、关键技术4:数据缓冲

如果我们只考虑实时性,那么收到数据就立刻解码并渲染必然是最好的选择,但是网络并不稳定,延迟、乱序、丢包、重复包都有可能发生。如果采用上面的策略,音频可能因为网络的抖动变的断断续续,视频可能因为丢包导致缺少参考帧从而出现黑屏或花屏,所以有必要引入一个缓冲区,增加一点可以接受的延迟来保证用户体验。

在WebRTC中,视频包会被放入JitterBuffer模块进行处理,JitterBuffer会进行视频包的排序、组装成完整的帧、确保参考帧有效,然后把数据送到解码器。同时,根据网络状况自适应地调节缓冲区的长度。音频包会被放入NetEQ中,它维护了音频的缓冲区,同时负责将音频同步到视频。我们做播放器一般都是以音频的时间为基准同步视频,但是WebRTC刚好相反,它是以视频为基准的。当音频数据堆积的时候加速音频播放,音频数据不足的时候降低速度把音频拉长。

9、关键技术5:回声消除

在语音通话的场景中,麦克风采集到的声音发送给远端,远端的扬声器播放出来以后又被远端的麦克风采集到这个声音并传送回来,这样讲话的人会感觉到有回声,影响体验。

WebRTC提供了回声消除算法AEC,时延估计(Delay Estimation)模块找到扬声器信号和麦克风信号的时延,线性自适应滤波器(Linear Adaptive Filter)参考扬声器信号估算回声信号并将其剪去,最后通过非线性处理(Nonlinear Processing)模块消除残留的回声。

10、关键技术6:最优路径

实时音视频对网络的要求非常高,如果通话双方距离很远,那么通话质量是很难保证的。城市A的设备给城市D的设备发送数据,直接发送未必是最优的选择,从城市B和城市C中转一下有可能更快。

理想的解决方案是在全球部署加速节点,用户就近接入。根据加速节点之间的实时网络质量探测数据,找到一条最优传输路径,避开网络的拥堵。

11、开源音视频框架WebRTC简述

刚才介绍了实时音视频系统实现过程中所需的关键技术,多次提到了WebRTC。显然,对于绝大多数团队来说,这些内容如果全部自主研发几乎是不可能的事情,而我们站在WebRTC的基础上去设计自己的系统是较为明智的选择。

WebRTC的代码非常复杂,想要把它搞清楚是一件非常困难的任务,我第一次看到WebRTC的代码根本就不知道从哪里下手。

幸运的是,WebRTC官方提供了架构图,可以先帮助我们对它进行一个宏观的了解。

WebRTC整体架构大概可以分为接口层、会话层、引擎层和设备I/O层:

1)接口层包括Web API和WebRTC C++ API,Web API给Web开发者提供了JavaScript接口,这样Web端就具备了接入WebRTC的能力;WebRTC C++ API面向的是浏览器开发者,让浏览器开发商具备集成WebRTC的能力。当然,WebRTC C++ API也可以用于Native客户端接入;

2)会话层主要包含信令相关的逻辑,比如媒体协商,P2P连接管理等;

3)引擎层是WebRTC最核心的功能,包括音频引擎、视频引擎和传输模块。音频引擎包含音频编解码器(Opus)、NetEQ和著名的3A(回声消除、自动增益、降噪)算法;视频引擎包括视频编解码器(VP8、VP9、H264)、JitterBufer和图像增强(降噪)算法;传输模块包含SRTP、多路复用和P2P模块;

4)设备I/O层主要和硬件交互,包括音视频采集和渲染,以及网络I/O。

上面一节描述的实时音视频关键技术中,WebRTC实现了除“最优路径”之外的全部内容。WebRTC几乎每个模块都是可以按需替换的,便于我们增加定制的内容。我们可以根据实际需求决定如何使用WebRTC,Native客户端可以通PeerConnection接口接入,服务端拿到RTP/RTCP包以后完全可以直接调用引擎层处理拿到最终的YUV和PCM数据,甚至只把WebRTC内部模块抠出来用在自己的系统上也是没问题的。

更多相关资料可阅读:

  1. 零基础入门:基于开源WebRTC,从0到1实现实时音视频聊天功能
  2. 实时音视频入门学习:开源工程WebRTC的技术原理和使用浅析
  3. 零基础快速入门WebRTC:基本概念、关键技术、与WebSocket的区别等

12、B站视频直播系统架构

我们回到B站的连麦PK业务场景,两位主播进行互动PK,同时大量观众在直播间观看PK的过程。

显然,两位主播通话要求低延迟,必须使用实时音视频系统交互;而观众观看直播的延迟要求相对没那么严格,可以采取传统直播的模式,通过RTMP或者SRT推流到CDN,用户从CDN拉流。

然后我们要思考两个问题。

12.1 问题1:主播之间的音视频通话是采用P2P还是服务器中转?

首先对P2P和服务器中转两种方案做个对比:

对于P2P方案来说,只需要部署STUN和TURN服务器,如果成功建立P2P连接那么后续媒体数据传输就不需要经过服务器,所以具有成本优势。然而,P2P的缺点也很明显,如果打洞失败还是需要TURN服务器中转,且建立连接的过程耗时较高,用户之间距离较远的情况下网络质量不可控,而且现有的第三方网络加速服务基本上都不支持P2P。

我们这里选择服务器中转的方案,因为实时音视频本身对网络的要求比较高,不会设置过高的码率,所以网络传输的数据量是可控的,成本能够接受。而且我们的实时音视频数据要对接AI审核,还要实现服务器混流,这是P2P方案做不到的。

12.2 问题2:推送给观众的流到CDN,这个工作放在主播客户端还是服务器?

两位主播PK对应的是两路流,观众只从CDN拉一路流,所以必须有个地方做混流。这里的混流指的是把两位主播的视频进行拼接、音频进行混合,然后打包成一路流。主播客户端能收到对方的流,可以和自己的流做混流;在前面提到的服务器中转方案中,服务器有双方的流,同样也可以完成混流。

我们先对比一下两种方案的优劣:

服务器进行混流需要先解码再编码,这需要消耗大量计算资源,所以成本很高;主播客户端进行混流需要额外增加一路流的编码和上传,对设备性能和上行带宽来说也是很大的挑战。

主播客户端需要等待服务器把对方的流发送过来才能混流,所以从延迟的角度来看服务器混流稍微占据优势,不过这个延迟相比CDN的延迟可以忽略不计。如果后期对通话质量要求变高,主播的设备性能和上行带宽跟不上,我们可以很容易增加服务器来扩展计算资源和带宽,所以在可扩展性方面服务器混流胜出。

另外,当主播从正常直播切换到连麦PK状态的时候,采用服务器混流必须先把直播的流停掉再由服务器接管,中间的时间差可能会产生卡顿或黑屏影响观众体验,而主播客户端混流可以做到无缝切换。

所以,这两种方案各有优缺点,我们采取折衷的办法:如果主播的设备负载较低且上行带宽比较充足,优先采用主播客户端混流的方式,否则降级为服务器混流。

12.3 开始架构设计

上面两个问题分析清楚了,就可以开始设计了。

这是我们的系统整体架构:

rtc-service主要提供信令、频道管理、主播管理、公有云上媒体服务器集群的健康检查和节点分配、同步主播状态到业务服务器、记录通话流水。

rtc-job是对rtc-service的补充,定期检查当前在线主播的状态,发现主播异常下线时触发兜底逻辑。

rtc-router负责收发主播的音视频数据。主播可以收到同一个频道内其他人的音视频流。如果需要服务器混流,则访问注册中心并采用Google的有界负载一致性哈希算法(Consistent Hashing with Bounded Loads)选取rtc-mixer节点,并往对应节点推送主播的音视频流。

rtc-mixer负责混流,根据需求拼接画面和混音,然后推送到CDN,观众通过CDN拉流。

主播的客户端并没有直接向rtc-router发送数据,而是通过第三方的四层加速网络转发。我们前面提到了“最优路径”的概念,第三方的四层加速服务可以让用户接入最近的加速节点,然后寻找最优路径把数据转发到我们的公有云节点。客户端只能看到第三方的加速节点IP,看不到我们公有云媒体服务器的IP,这在一定程度上可以防止服务器遭到攻击;其次,我们可以在保证异地多活的前提下让公有云集群相对比较集中,节省成本。

服务的可用性和容错性也是一个很重要的问题,假如在主播PK即将胜利的时刻服务出现故障,弹出"PK异常终止请重新再来",这很令人绝望。我们不仅要保证服务可用,还要尽最大可能保证服务出现故障时减小对用户的影响,让流程能够走下去。接下来讨论系统中每个风险模块为了实现这个目标所采取的措施:

四层加速网络故障。这个属于第三方厂商提供的服务,每个厂商提供的接入方式大同小异,基本上就是附加的header有差别,所以同时对接多家厂商对客户端来说是很容易做到的。客户端进行连通性检查,只要存在至少一家厂商的服务可用,就不会影响业务。

公有云上的rtc-router和rtc-mixer故障。在公有云上部署服务,尽量要多厂商、多区域部署,防止单机房整体宕机。我们同样准备了多个集群,每个集群都部署了多台rtc-router、rtc-mixer和ZooKeeper,单个集群可以独立工作,如果单个集群不可用或者负载达到上限则会被熔断。核心机房的rtc-service会对公有云上的集群进行健康检查,如果rtc-router宕机,rtc-service会通过信令通道通知客户端切换到同集群中其他服务器,当同集群没有可用机器时则切换集群。如果rtc-mixer宕机,rtc-router会通过ZooKeeper重新选择一台接管混流任务。

核心机房的rtc-service和rtc-job故障。这部分内容和B站大部分核心服务部署在同样的集群,复用了B站比较成熟的高可用架构。这部分内容可以参考其他文章,这里不再赘述。

13、本文小结

如果我们把实时音视频技术比作一座富丽堂皇的城池,这篇文章只能带领大家来到城门口。我们也不会停止探索的脚步。希望大家读到这里能够有所收获,如有疏漏,欢迎批评指正。

14、参考资料

[1] 实时语音通讯的回音及回音消除概述

[2] 实时语音通讯的回音消除技术详解

[3] 实时语音通讯丢包补偿技术详解

[4] 零基础,史上最通俗视频编码技术入门

[5] IM实时音视频聊天时的回声消除技术详解

[6] 学习RFC3550:RTP/RTCP实时传输协议基础知识

[7] 基于RTMP数据传输协议的实时流媒体技术研究(论文全文)

[8] 爱奇艺技术分享:轻松诙谐,讲解视频编解码技术的过去、现在和将来

[9] 零基础入门:实时音视频技术基础知识全面盘点

[10] 实时音视频面视必备:快速掌握11个视频技术相关的基础概念

[11] 零基础入门:基于开源WebRTC,从0到1实现实时音视频聊天功能

[12] 实时音视频入门学习:开源工程WebRTC的技术原理和使用浅析

[13] 零基础快速入门WebRTC:基本概念、关键技术、与WebSocket的区别等

[14] 移动端实时音视频直播技术详解(五):推流和传输

[15] 移动端实时音视频直播技术详解(六):延迟优化

[16] 实时视频直播客户端技术盘点:Native、html5、WebRTC、微信小程序

[17] 浅谈开发实时视频直播平台的技术要点

[18] 视频直播技术干货:一文读懂主流视频直播系统的推拉流架构、传输协议等

(本文已同步发布于:http://www.52im.net/thread-4785-1-1.html)

posted @ 2025-03-06 11:46 Jack Jiang 阅读(11) | 评论 (0)编辑 收藏

     摘要: 本文引用自公众号“计算科学与信息化”,原题“运维必知的20个网络安全知识点!”,下文进行了排版和内容优化。1、引言即时通讯IM应用开发的初学者很容易迷失在网络编程的复杂性以及通信安全的各种概念里,本文不涉及深度理论知识,尽量通过一句话或几句话让你快速了解20个相关的网络编程和通信安全知识点,希望能助你愉快地开始即时通讯应用开发。技术交流:- 移动端I...  阅读全文

posted @ 2025-02-27 13:04 Jack Jiang 阅读(35) | 评论 (0)编辑 收藏

1、前言

本文深入分析了即时通信(IM)系统中所面临的各种安全问题,综合利用对称加密算法(DES算法)、公开密钥算法(RSA算法)和Hash算法(MD5)的优点,探讨组合加密算法在即时通信中的应用。

技术交流:

2、IM安全系列文章

本文是IM通讯安全知识系列文章中的第2篇,总目录如下:

即时通讯安全篇(一):正确地理解和使用Android端加密算法

即时通讯安全篇(二):探讨组合加密算法在IM中的应用》(本文

即时通讯安全篇(三):常用加解密算法与通讯安全讲解

即时通讯安全篇(四):实例分析Android中密钥硬编码的风险

即时通讯安全篇(五):对称加密技术在Android上的应用实践

即时通讯安全篇(六):非对称加密技术的原理与应用实践

即时通讯安全篇(七):用JWT技术解决IM系统Socket长连接的身份认证痛点

即时通讯安全篇(八):如果这样来理解HTTPS原理,一篇就够了

即时通讯安全篇(九):你知道,HTTPS用的是对称加密还是非对称加密?

即时通讯安全篇(十):为什么要用HTTPS?深入浅出,探密短连接的安全性

即时通讯安全篇(十一):IM聊天系统安全手段之通信连接层加密技术

即时通讯安全篇(十二):IM聊天系统安全手段之传输内容端到端加密技术

即时通讯安全篇(十三):信创必学,一文读懂什么是国密算法

即时通讯安全篇(十四):网络端口的安全防护技术实践

即时通讯安全篇(十五):详解硬编码密码的泄漏风险及其扫描原理和工具

3、即时通信应用所面临的安全问题

即时通信系统大都采用C/S、B/S、P2P等技术来实现即时通信的功能,软件编制没有统一的标准,使得IM系统本身存有多种安全漏洞,加上用户缺乏安全意识,导致在使用即时通信系统时出现各种安全问题。

3.1 信息窃取问题

目前的IM系统在交换信息或传输文件时仅仅采用了弱加密甚至不加密的方式,攻击者利用此缺陷监听、窃取重要数据,这种泄密可能性给企业或个人造成不可估量的损失,尤其是对一些特殊行业,如金融和证券等行业,将会构成巨大的商业安全威胁,这种攻击的类型是对信息机密性的攻击。

3.2 信息篡改问题

信息篡改又称中间人攻击,是攻击者试图在IM系统信息交互过程中,通过监听、窃取正常的信息流,对信息进行修改后再发往信息接收方。只要信息存在,就可能出现这种攻击,它还可能攻击传输中的信息,这种攻击的类型是对信息完整性的攻击。

3.3 信息伪造问题

在现有的IM系统中,接收方一般只根据发送方的ID或发送过来的简单信息进行确认,这样就给攻击者提供了机会。攻击者通过令人误导的昵称或者迷惑性的语言,骗取对方的信任,从而套取信息、诈骗或达到其他不良目的。这种攻击的类型是对信息真实性的攻击。

3.4 其他问题

由于IM系统的文件传输采取了P2P模式,它可以将文件作为附件通过点对点方式传送,而绕过网络周边安全防御设备。由于点对点隧道直接传至桌面计算机,因此受感染的文件借即时通信系统就能绕过防病毒网关的扫描,各种病毒如蠕虫、特洛伊木马等可以借此轻松地进入网络,很多被病毒感染的文件则可能利用即时通信系统进行传播。

攻击者也可以用缓冲区溢出、拒绝服务等攻击方式,通过IM系统的安全漏洞对整个网络系统进行攻击或传播病毒。

4、主流的加密算法介绍

4.1 对称加密:DES算法

DES即数据加密标准,这种加密算法是由IBM研究提出来的, 是一种分组密码,它用于对64比特的数据进行加密和解密。DES算法所用的密钥也是64比特,但由于其中包含了8个比特的奇偶校验位,因而实际的密钥长度是56比特。DES算法多次组合替代算法和换位算法,利用分散和错乱的相互作用,把明文编制成密码强度很高的密文。DES算法的加密和解密的流程是完全相同的,区别仅仅是加密与解密使用子密钥序列的顺序正好相反n1。DES算法属于对称加密算法,即加密和解密共享同一个密钥,主要用于解决数据机密性问题。

4.2 公开密钥算法:RSA算法

RSA算法作为惟一被广泛接受并实现的通用公共密钥加密方法,是众多阐述非对称密码体制的算法中最具代表性的,几乎成了公开密钥密码学的同义词。它是麻省理工大学的Rivest,Shamir和Adleman(RSA算法即为三人名字的缩写)于1977年研制并于1978年首次发表的一种算法。该算法的数学基础是数论的欧拉定理,它的安全性依赖于大数的因子分解的困难性,该算法至今仍没有发现严重的安全漏洞。RSA使用两个密钥,一个是公钥(PubHc Key),另一个是私钥(Private Key)加密时把明文分戍块,块的大小可变,但不超过密钥的长度。RSA把明文块转化为与密钥长度相同的密文。其算法如下:

首先选择两个相异大质数p、q,计算n=pq,取小于n的数e与(p-l)(q-l)互质。根据给定的e,再选择d满足ed除以z的模余数是1(即满足ed mod (p-l)(q-l)=1),根据欧几里得算法(a=bn+c,则a与b的最大公因子就等于b与c的最大公因子),这样的d-定可以找到。这样数对(n,e)为公钥,数对(n,d)为私钥在编码时,假设资料为A,将其分戍等长数据N块,每块为nKn。计算C=llle mod n,则c就是编码后的资料。至于解码,取III=Cd mod n。黑客攻击时怨得到e,这样就必须对n进行因式分解,选择足够大的质数p、q便能阻止分解因式。

对于p、q的选择,一般来说是足够大的素数,对于大数,并没有一个确定的界限,因为随着计算机技术的发展,破解能力正在逐步增强(根据摩尔定理计算能力18个月就翻一番)。RSA实验室的建议是,安全性要求相对较低时,p和q的乘积达到768位;安全性要求相对较高时,乘积达到1024位以上。

RSA算法还可以用于“数字签名”,即用私钥进行加密,公钥来解密。

4.3 Hash算法:MD5算法

MD5算法并不是加密算法,但却能形成信息的数字“指纹”,主要用途是确保数据没有被篡改或变化过,以保证数据的完整性。MD5算法有三个特性:

  • 1)能处理任意大小的信息,并生成固定长度128位的信息摘要;
  • 2)具有不可预见性,信息摘要的大小与原始信息的大小没有任何联系,原信息的每一个微小变化都会对信息摘要产生很大的影响;
  • 3)具有不可逆性,没有办法通过信息摘要直接恢复原信息。

5、应用探讨:组合加密算法实现即时通信系统的认证模型

本文综合利用以上算法的优点,在IM系统中建立以下消息发送模型,以解决IM系统所面临的信息窃取、篡改、伪造等安全问题。模型中用户A和B为IM系统的客户端,用户A和B之间彼此拥有对方的公钥或数字证书,A向B发送消息,其全过程如图1所示。

对于IM系统中蠕虫病毒感染安全问题的处理,通过以下模型进行处理,如图2所示。

6、应用探讨:组合加密算法实现即时通信系统的通信模型

按照以上加密认证模型,建立如图3所示的安全即时通信系统的实现模型,该模型包含两个层次的认证,一是服务器与客户机之间的双向认证,二是客户机与客户机之间的双向认证,即在两端连接发送数据之前,必须协商并交换密钥信息。服务器作为自签署证书的CA认证中心,认证的所采用的密码技术极为公开密密钥技术。

模型中的公开密钥技术充当了加密共享密钥和数字签名的作用,以解决服务器与客户机、客户机与客户机之间的身份鉴别和客户机之间进行数据通信的密钥传输问题。在Java密码术体系结构中,密钥生成和操作可以使用keytool程序来执行。

7、应用探讨:组合加密算法应用模型的安全性及效率分析

在以上模型中,利用对称加密算法处理消息、文件的加密,以解决信息、文件传送的机密性问题,具有加密速度快的特点;用公开密钥算法的加密技术解决了对称密钥在网络中明文传输问题;用Hash算法计算出摘要,再通过公开密钥算法的数字签名技术对摘要进行签名,既提高了效率,又保证了信息文件传输的鉴别和不可否认性;在文件处理过程中,通过病毒扫面和组合加密双重处理,减少了网络中文件传输病毒蠕虫感染的几率。

更多有关IM安全和架构资料

[1] 传输层安全协议SSL/TLS的Java平台实现简介和Demo演示

[2] 理论联系实际:一套典型的IM通信协议设计详解(含安全层设计)

[3] 微信新一代通信安全解决方案:基于TLS1.3的MMTLS详解

[4] 来自阿里OpenIM:打造安全可靠即时通讯服务的技术实践分享

[5] 简述实时音视频聊天中端到端加密(E2EE)的工作原理

[6] 移动端安全通信的利器——端到端加密(E2EE)技术详解

[7] Web端即时通讯安全:跨站点WebSocket劫持漏洞详解(含示例代码)

[8] 通俗易懂:一篇掌握即时通讯的消息传输安全原理

[9] IM开发基础知识补课(四):正确理解HTTP短连接中的Cookie、Session和Token

[10] 快速读懂量子通信、量子加密技术

[11] 即时通讯安全篇(七):如果这样来理解HTTPS原理,一篇就够了

[12] 一分钟理解 HTTPS 到底解决了什么问题

[13] 一篇读懂HTTPS:加密原理、安全逻辑、数字证书等

[14] 基于Netty的IM聊天加密技术学习:一文理清常见的加密概念、术语等

[15] 手把手教你为基于Netty的IM生成自签名SSL/TLS证书

[16] 微信技术分享:揭秘微信后台安全特征数据仓库的架构设计

[17] 零基础IM开发入门(二):什么是IM系统的实时性?

[18] 零基础IM开发入门(三):什么是IM系统的可靠性?

[19] 零基础IM开发入门(四):什么是IM系统的消息时序一致性?

[20] 新手入门一篇就够:从零开发移动端IM

[21] 转转平台IM系统架构设计与实践(一):整体架构设计

[22] 基于实践:一套百万消息量小规模IM系统技术要点总结

[23] 一套亿级用户的IM架构技术干货(上篇):整体架构、服务拆分等

[24] 一套亿级用户的IM架构技术干货(下篇):可靠性、有序性、弱网优化等

[25] 一套海量在线用户的移动端IM架构设计实践分享(含详细图文)

[26] 一套原创分布式即时通讯(IM)系统理论架构方案

(本文已同步发布于:http://www.52im.net/thread-217-1-1.html)

posted @ 2025-02-26 11:32 Jack Jiang 阅读(19) | 评论 (0)编辑 收藏

本文由美团安全研究员乔丹分享,作者硕士毕业于复旦大学,目前在美团致力于云原生安全建设。原题“浅谈硬编码密码及其扫描工具”,下文进行了排版和内容优化。

1、引言

密码是对服务、系统和数据的访问权限进行授权的数字身份凭证,常见的密码有API密钥、非对称私钥、访问Token等。硬编码密码(Hardcoded Secret),或称嵌入式密码(Embedded Secret),是指将密码以明文方式直接写入代码中。这种处理方式极大地提高了攻击者命中密码的概率,使服务或系统暴露在风险中,容易造成严重损失。

针对此问题,本文详细讨论了硬编码密码的成因、危害及治理方法,同时本文从安全人员的角度出发,对现有的硬编码密码检测工具的算法进行了深入调研,并提出了我们的自动化检测工具。

 
 

2、系列文章

本文是IM通讯安全知识系列文章中的第15篇,此系列总目录如下:

3、为什么会用硬编码密码

随着互联网组织转向云架构、SaaS 平台和微服务,密码等数字身份验证凭证的数量和多样性正在快速增长。与此同时,企业也不断推动更短的发布周期,开发人员面临巨大时间压力的同时,需要处理的密码量比以往任何时候都多。许多开发人员采取捷径,选择使用硬编码的方式处理密码。

在企业的代码仓库中普遍存在大量的硬编码密码问题。据GitGuardian统计,在公共Git存储库上每天会泄露数以千计的密码,其中仅2020年就有超过200万个密码被上传至Git存储库中,而2021年该组织发现的密码数量超过600万,同比增长近2倍,而私人存储库的密码泄露事件存在可能性比公共库高4倍。

根据统计,硬编码密码包括API密钥、访问Token、非对称私钥、认证ID、安全证书、口令、特权用户账户等类型。

硬编码密码所涉及的平台十分广泛,包括如下领域:

  • 1)开发工具,如Django、Rapid API;
  • 2)数据存储,如MySQL、Mongo;
  • 3)金融服务,如PayPal、Amazon MWS;
  • 4)消息通讯系统,如Gmail、Telegram;
  • 5)云提供商,如AWS、Azure、Google;私钥;
  • 6)社交媒体,如Twitter、Facebook;
  • 7)版本控制平台,如Github、Gitlab 等等。

除了程序代码中,这些硬编码还容易出现在基础设施配置文件、监控日志、运行日志、堆栈调试track记录、git历史中。所有类别的硬编码密码都使企业暴露在攻击之下。

4、硬编码密码的典型危害

硬编码密码主要对安全和研发两方面具有危害。

1) 削弱系统安全性:

攻击者常通过公共代码库或反编译分析获得硬编码密码字符串,利用密码访问敏感数据或获取敏感操作权限。攻击者还可以进一步扩大攻击范围,进行数据勒索、帐户操纵、帐户创建、通过用户数据进行利用等,使得企业和用户都遭受严重损失。在以下案例中,攻击均是从密码的泄露开始的:2014年,Uber数据库被未经授权访问,导致数千名Uber司机私人信息的数据被泄露;2016年,Uber又因外部的未授权访问导致5700万用户的个人信息被泄露;2018年,Github和Twitter在内部日志系统中以明文方式存储密码,分别涉及2700万和3.3亿用户数据泄露;2020年,用户在Github仓库中发现了星巴克的API密钥,涉及重大信息泄露;2021年,黑客组织 Sakura Samurai 在一次重大数据泄露事件中获得了访问联合国 (UN) 员工私人数据和系统的权限……由硬编码密码导致的安全事故层出不穷,也不断有相关CVE和CWE被披露。

硬编码密码对特定设备、固件、服务、应用程序本身,对其连接的IT生态系统其他部分,甚至使用服务的第三方都存在风险,使其同样暴露在风险中。

2)不易于程序维护:

硬编码密码的修复较为困难,密码一旦被利用无法轻易被修正。对于正在线上运行的服务或系统,修复硬编码密码问题需要停服重新发布。大型企业的服务流量较大,服务间还存在依赖,则需要灰度发布,修复流程更长,其间可能持续受到攻击者威胁。

密码的蔓延也使维护变得困难。与传统凭证不同,密码旨在分发给开发人员、应用程序和基础设施系统,这将不可避免地使开发中使用的密码数量增加,一个密码可能出现在代码中多处位置,这进一步增加了修复的难度。

此外,开源的代码造成密码泄露,即使在源码中删除硬编码密码,也会残留在git历史里。

5、怎样避免硬编码密码

企业代码中的硬编码密码问题日益严重,只有通过安全人员和研发人员的共同协作才能解决。源代码中的密码泄露很难彻底避免,但与其他漏洞一样,它完全由内生因素决定:开发人员需要访问更多的资源,以更快的速度构建和部署。这意味着只要有足够的纪律和教育,再加上正确的工具,就有可能大幅改善这种情况。

从开发人员角度:需要注意尽量避免将密码以明文形式写入代码中。代码中需要对密码进行校验时,对入站身份验证可使用强单向散列函数进行密码模糊化,并将这些散列结果存储在具有适当访问控制的配置文件或数据库中;对出站身份验证,可将密码存储在代码之外的一个经过严格保护的、加密的配置文件或数据库中,该配置文件或数据库不会被所有外部人员访问,包括同一系统上的其他本地用户;大型企业可以使用KMS服务进行一站式密码管理。

从安全人员角度:应尽量做到风险左移,尽早发现密码泄露,帮助开发人员降低修复成本。可通过代码检测扫描,将硬编码密码检测集成到开发工作流程中,提前发现硬编码密码问题。

6、硬编码密码的典型检测方法

由于硬编码密码有如此的危险性,学术界和工业界都有许多组织针对此问题研发了代码扫描工具。我们对开源工具和学术文章进行了一系列调研,总结了目前的硬编码密码扫描工具常用的检测算法,并对其优缺点进行了讨论。

6.1 正则表达式匹配

正则表达式通常被用来检索符合某种模式的字符串。对于检测具有固定结构或特征的密码,正则表达式可能很有效。

常用于密码检测的正则表达式可分为:

  • 1)针对各种特定平台密码的表达式;
  • 2)不针对任何平台的通用表达式。

1)针对各种特定平台密码的表达式:

许多平台的API密钥、访问Token、认证ID等具有平台独有的特征,例如亚马逊AWS密钥均以“AKIA”字符串开头;常用于非对称加密的私钥如RSA、EC、PGP及通用私钥等,常由ssh-keygen、openssl等工具生成,多数情况下私钥以单独的PEM等文件格式存储,其内容也具有一定特征,例如RSA私钥文件由"-----BEGIN RSA PRIVATE KEY-----"字符串作为开头。对于这类密码,可以通过匹配具有其特征的正则表达式进行检测。

下表列举了部分常用平台密码的类型以及正则表达式。本文仅以此表举例,实际上特定平台的密码种类十分丰富,此处不便一一列举。

2)不针对特定平台的通用的表达式:

由于特定平台表达式和平台的一一对应性质,其覆盖范围有限,此时需要用覆盖范围较广的通用表达式来补充。许多平台的密码具有一些通用的特征,例如密码字符串以api_key、access_token等关键字为开头。

此外,根据开发人员的编程命名习惯规范,也可以根据变量名中的关键字进行匹配,例如变量名中含有Secret、Token等关键字的字符串很可能是密码。

优点:

  • 1)配置简单;
  • 2)自定义扩展方便。

缺点:

  • 1)正则表达式覆盖范围不够广则容易漏报;
  • 2)使用一组不准确的正则表达式容易出现大量误报;
  • 3)即使是正确的正则表达式也有一定程度的误报,例如“AKIAXXXEXAMPLEKEYXXX”虽然符合亚马逊AWS的正则表达式,但并不是有效的密码;
  • 4)通用表达式中使用变量名关键字匹配的检测方法容易被对抗。

6.2 熵字符串编码检测

在信息论概念中,熵是对不确定性的量度,越随机的数据的熵越高。大多数API密钥、访问Token等密码字符串具有高度熵的特性,因此可以通过搜索高熵字符串来检测密码。这种算法被以TruffleHog为代表的工具所采用。现有的工具一般采用香农熵算法来计算字符串熵值,对字符串A的香农熵值计算公式如下图所示,其中pi表示第i个字符出现的频率。

1)优点:

  • 1)能够检测出无明显特征的密码,对于正则表达式未覆盖到的范围有补充效果;
  • 2)可用于对正则表达式检测结果的验证,如上文提到的正则表达式误报字符串“AKIAXXXEXAMPLEKEYXXX”,其熵值较低,可通过验证筛除。

2)缺点:

  • 1)字符串被判定为密码的熵阈值难以确定,阈值过高容易漏报,阈值过低又容易误报。即使是学术论文中的阈值也全凭实验经验确定,缺乏坚实的理论支撑;
  • 2)一些高熵值的SHA、MD5等字符串容易被误报为密码。对于这一问题,可通过过滤SHA、MD5值出现较密集的文件扩展名来降低误报,例如.lock, .inc文件;
  • 3)容易将具有明显升降序的字符串误报为密码。香农熵只对出现频率进行计算,不考虑字符顺序,具有明显升降序的字符串同样会表现出较高熵值,例如Hex编码的“123456789abcdef”和“d9b41a72f683ce5”两字符串香农熵相等,但前者一般不会是一个有效的密码。对于这一问题,需要通过一些启发式处理方式降低升降序字符串的熵值,或通过后期过滤筛除。

7、美团的硬编码密码检测工具研发实践

为了保障美团整体研发环境安全,同时节约安全人员的审计成本,我们研发了针对硬编码密码的代码扫描工具。我们认为在众多字符串中寻找密码如同在沙里淘金,因此将工具命名为Gold-digger。

7.1 工具设计

为服务于全公司研发环境,Gold-digger工具有如下需求:

  • 1)编程语言无关:公司各业务使用的编程语言不同,Gold-digger需要无障碍地应用于所有编程语言代码中;
  • 2)模块化,方便扩展迭代:为了根据测试反馈结果不断提高效果,Gold-digger需要长期不断迭代;
  • 3)能够集成到软件开发生命周期中:Gold-digger侧重预防,需要工具集成在CI/CD管道中,从源头遏制密码泄露风险;
  • 4)高精确率召回率:Gold-digger的设计初衷之一是节约人力成本,为降低审计、维护和运营压力,必需尽可能准确、全面地检测密码。

基于上述需求,Gold-digger的架构主要分为四个模块:核心引擎、转换器、检测器、过滤器。

Gold-digger工作流程如下图,箭头表示数据流向。核心引擎依次读取代码仓库中文件,经过预验证和输入处理后将代码以行为单位传输给检测器,其中部分特殊格式由转换器处理后再传输给检测器;检测器在代码中检测密码候选值;过滤器对密码候选值进行后过滤,将过滤后的密码传回核心引擎;最后核心引擎将代码仓库中所有密码进行收集后,将密码相关信息输出为可读性较强的JSON文件报告。

1)核心引擎:

该模块为Gold-digger赋能,负责调度其他模块,也是负责输入输出处理、数据收集存储等。输入处理部分负责读取代码文件,先调用过滤器对文件后缀进行全局预验证,再通过引号标识匹配或调用转换器识别代码中的字符串及其赋值变量;然后核心引擎调用调用检测器和过滤器进行密码收集,将检测到的密码数据以文件为单位存入不同集合,能够方便地对集合进行合并、删减等操作;输出处理部分将仓库中所有密码关键信息,如密码值、文件位置、检测算法等,输出为JSON格式。

2)转换器:

该模块是专为部分特殊格式文件进行格式转换的处理器。尽管核心引擎能处理大部分代码格式,但无法处理.yaml、.ini、.properties等不使用引号作为字符串特征标识的格式。为保证语言无关性,我们使用转换器处理上述特殊格式,将其转换为用引号标识字符串的代码。这种解析方式无需为不同语言分析抽象语法树,能够有效节省算力。

3)检测器:

该模块是Gold-digger的密码检测算法模块。我们在综合调研同类型检测工具后,汲取了各方优点,采用了正则表达式匹配和熵字符串检测两类算法。Gold-digger的检测器包含数十种特定平台正则表达式、通用正则表达式以及Hex编码、Base64编码的熵字符串检测算法。检测器中每种算法以插件方式各自独立,方便扩展、启用或禁用,同时Gold-digger也允许用户自定义检测算法插件。代码将遍历所有检测算法,任一算法命中便记录为密码候选值。

4)过滤器:

该模块为Gold-digger的验证、过滤模块。预验证部分在检测器运行前对文件格式进行验证,筛除压缩文件、多媒体文件等非文本类型;后过滤部分在检测器运行后对所有密码候选值进行启发式过滤,并将过滤后的密码传回核心引擎。后过滤过程中每项密码候选值将遍历所有过滤规则,所有规则都未能筛除的候选值会被记录在密码集合中(检测器和过滤器的主要处理流程如下图所示)。过滤规则主要为开发测试人员凭经验总结的启发式规则,例如:过滤升降序字符串、过滤高度重复字符串、过滤uuid、过滤间接引用赋值等。

5)CI/CD集成:

Gold-digger的最终目标是消除代码中的密码泄露问题,因此检测到密码并不是最后一步,修复才是最后一步。我们把Gold-digger集成到公司研发环境CI/CD管道中,方便开发人员根据密码报告及时修复漏洞,从源头遏制风险。当开发人员向公共存储库提交代码后,Gold-digger会进行on-push扫描,对包含密码的提交进行拦截和告警。此外,我们还允许开发人员在本地使用Gold-digger,进行pre-commit或pre-push检查,整体风险左移。

7.2 数据对比

我们使用Gold-digger与最先进的开源工具进行了对比。

我们对内部服务代码进行了分析,将人工安全审计发现的密码作为测试基准,使用工具对代码进行测试并统计结果。下表结果显示,我们的工具准确率和召回率高于其他所有开源工具,误报率和漏报率低于其他所有开源工具。

分析显示,Gold-digger检测的密码中大部分是通过通用正则表达式和熵字符串检测获得的。这是由于内部代码中包含的密码大多无明显前缀后缀特征,特定平台表达式检测不到。正因如此,大部分工具尽管定义了大量的特定平台的正则表达式但漏报率仍很高,例如trufflehog定义了700多种特定平台正则表达式,但通用正则表达式种类较少,故对特定平台表达式未覆盖到部分的检测能力较弱。Gold-digger可以利用通用正则表达式和熵字符串检测进行弥补,有效降低漏报。

密码检测的一大难点是避免来自非密码字符串的误报。Gold-digger通过多种启发式规则的过滤得到了较低的误报率。其他工具大量误报的主要原因则是正则表达式的匹配范围太宽泛又缺乏有效过滤手段,例如Gitleaks通过通用正则表达式识别到大量密码候选值,但其中既有真正的密码,又有appkey name、间接引用等,但未进行筛除。

8、本文小结

随着互联网组织架构的高速发展和软件发布周期的不断缩短,硬编码密码问题在企业代码仓库中日益严重,其危害已通过多起严重安全事故显示出来。硬编码密码的大规模治理必需由安全人员和研发人员共同合作。

美团为保障研发安全,设计了具有编程语言无关、模块化架构、集成在CI/CD管道等特点的硬编码密码的扫描工具Gold-digger。该工具的效果优于目前所有开源工具,能够有效帮助开发人员尽早发现并修复密码泄露,从源头保障研发安全。

9、相关资料

[1] Over two million corporate secrets detected on public GitHub in 2020

[2] 传输层安全协议SSL/TLS的Java平台实现简介和Demo演示

[3] 理论联系实际:一套典型的IM通信协议设计详解(含安全层设计)

[4] 微信新一代通信安全解决方案:基于TLS1.3的MMTLS详解

[5] 来自阿里OpenIM:打造安全可靠即时通讯服务的技术实践分享

[6] 简述实时音视频聊天中端到端加密(E2EE)的工作原理

[7] 移动端安全通信的利器——端到端加密(E2EE)技术详解

[8] Web端即时通讯安全:跨站点WebSocket劫持漏洞详解(含示例代码)

[9] 通俗易懂:一篇掌握即时通讯的消息传输安全原理

[10] IM开发基础知识补课(四):正确理解HTTP短连接中的Cookie、Session和Token

[11] 快速读懂量子通信、量子加密技术

[12] 一分钟理解 HTTPS 到底解决了什么问题

[13] 一篇读懂HTTPS:加密原理、安全逻辑、数字证书等

[14] 基于Netty的IM聊天加密技术学习:一文理清常见的加密概念、术语等

[15] 手把手教你为基于Netty的IM生成自签名SSL/TLS证书

[16] 微信技术分享:揭秘微信后台安全特征数据仓库的架构设计


(本文已同步发布于:http://www.52im.net/thread-4781-1-1.html)

posted @ 2025-02-20 11:31 Jack Jiang 阅读(41) | 评论 (0)编辑 收藏

本文由转转 梁会彬、杜云杰分享,原题“转转IM的实践与思考”,下文进行了排版和内容优化。

1、引言

接上篇《整体架构设计》,笔者将以转转IM架构为起点,介绍IM相关组件以及组件间的关系;以IM登陆和发消息的数据流转为跑道,介绍IM静态数据结构、登陆和发消息时的动态数据变化;以IM常见问题为风景,介绍保证IM实时性、可靠性、一致性的一般方案;以高可用、高并发为终点,介绍保证IM系统稳定及性能的小技巧

 技术交流:

2、系列文章

本文是系列文章中的第2篇,本系列文章的大纲如下:

3、本文作者

梁会彬:转转架构部资深Java工程师,主要负责服务治理平台、Docker云平台、IM、分布式ID生成器、短域名服务等,有丰富的线上实战经验。

4、 IM架构回顾

应用层:使用IM服务的上游业务方,包括app(ios和android)、小程序/PC/m页、push、业务方等。

接入层:

  • 1)tcp entry:使用TCP协议,主要用于长连接保持、会话管理、协议解析;
  • 2)http entry:使用http协议,采用long pull技术,主要用于长连接保持、会话管理、协议解析;
  • 3)mq:接收电商推广等系统消息。推送量具有脉冲特点,使用mq削峰填谷;
  • 4)rpc-server:业务查询用户聊天数据、发送实时系统消息等。

逻辑层:

  • 1)logic:核心逻辑服务,负责登陆信息管理、在线消息管理、离线消息管理、在线推送管理等;
  • 2)ext-logic:扩展逻辑服务,负责子母账号推送、登陆信息统计、系统消息管理等。

数据层:

  • 1)MySQL:联系人数据、消息数据、系统消息数据等;
  • 2)Redis:登陆信息等。

5、IM消息收发

5.1场景说明

数据流中以用户A和用户B的对话为例,其中用户A的uid为1,用户B的uid为2。

下图为用户聊天场景图:

下图为用户聊天IM系统的数据流转图:

5.2数据结构

登陆信息存储在Redis中,联系人和消息数据放在TiDB中。

1)登陆信息:

key:uid

value:{entryIp:"127.0.0.1",entryPort:5000,loginTime:23443233}

2)联系人:

说明:

  • 1)recent_msg_content:最近一条对话消息的内容,用于联系人列表中展示最近的消息内容;
  • 2)recent_read_time:最近一次读取该会话消息的时间,用于控制已读状态,小于该时间的所有消息,都为已读状态。

3)消息:

说明:

  • 1)client_msg_id:客户端生成的id,客户端幂等设计,防重复;
  • 2)direction:消息方向(0代表较大uid向较小uid发送消息,1则反之)。

数据流=数据+流。上面部分讲数据,即联系人和消息表,从静态的角度介绍了IM的数据结构;下面部分讲流(IM中最重要的两个流程),即登陆和发消息,从动态的角度来阐述IM系统中数据的流转。

5.3主要流程

5.3.1 )登陆:

1)问题:entry地址发现:app直接访问vip,由vip转发到entry。

2)流程(下面的数字为图中数字的说明):

  • 1)建连:app通过vip发起与entry连接;
  • 2)转发:entry转发登陆信息到logic,获取用户uid并管理该用户的连接;
  • 3)入库:logic记录用户登陆信息到redis。

3)数据:

Redis中数据如下:

key:1

value:{entryIp:"127.0.0.1",entryPort:5000,loginTime:23443233}

5.3.2 )发消息(下面的数字为图二中数字的说明):

1)流程处理:

  • 1)发送:通过用户与entry的长连接发送文字"hello world";
  • 2)转发:entry转发文字信息"hello world"到logic;
  • 3)入库:logic存入数据库,即更新联系人表和消息表,其中联系人表更新recent_msg_content字段,消息表增加一条新消息记录;
  • 4)推送:从Redis中获取用户B登陆entry,如果未登录,走离线逻辑(发送push、推送微信、短信唤起);
  • 5)送达:用户B收到消息;
  • 6)确认:发送ack到entry;
  • 7)完成:logic收到ack,取消定时器;如果没有收到ack,logic会定时重发(用户在线时)。

2)数据:

联系人数据如下:

消息表数据如下:

5.3.3)关于数据的几个问题:

1)消息和联系人是如何分库分表的?使用TiDB,无需分库分表(现在的表设计支持根据uid_a分表,也就是无缝支持以MySQL为存储)。

2)联系人表一条消息为什么记录了两条数据?业务逻辑上,考量支持已读、删除联系人;索引性能上,考虑用户查询联系人时,sql条件为where uid_a=?,联系人表索引为uid_a,如果存单条数据,无法有效利用索引。

3)消息表一条消息记录一条数据,用户B与用户A的消息怎么查询?该表索引为<big_uid, small_uid>联合索引,无论是用户A查询与用户B的聊天信息,还是用户B查询用户A的聊天信息,其sql统统为where big_uid =max(uid_a,uid_b) and small_uid =min(uid_a,uid_b),然后根据direction字段展示聊天方向,这样就可以用一条消息,无需和联系人表一样存储两份数据,满足两种查询,节省一半的消息存储。

6、IM常见问题

6.1消息的实时性

1)是什么:

用户A给用户B发送消息"hello world",用户B怎么第一时间感知到?这里说的实时性,就是指用户如何实时获取发送的消息。

2)io模型带来的启示:

  • 1)poll、select、epoll;
  • 2)poll/select相比epoll最大的劣势在于轮询,轮询就需要轮询间隔,间隔小会浪费cpu,间隔大会不实时。epoll具有don't call me i will call you的特点,保证实时性;
  • 3)IM也面临着轮询还是通知的问题,也就是pull和push的问题。

3)怎么办:

  • 1)向epoll致敬:epoll_create、epoll_ctl、epoll_wait(此三者是epoll系统调用api);
  • 2)整个IM系统和epoll模型类似,app和entry保持长连接(epoll_create);entry session管理(即长连接管理epoll_ctl);logic等待用户A发送给用户B消息,获取用户B所登陆entry,触发推送消息(epoll_wait);综述,entry扮演着(epoll_create,epoll_ctl),logic扮演着(epoll_wait)这样IM系统就解决了消息实时性问题。

6.2消息的可靠性

1)是什么:

  • 1)用户A给用户B发送消息"hello world",用户B在线,怎么保证用户B确实收到了消息。这里说的可靠性,就是指用户如何可靠发送的消息。

2)tcp模型带来的启示:

  • 1)失败重传、ack确认。

3)怎么办:

  • 1)失败重传:图二中(1、发送2、转发3、入库)失败,告知客户端失败,由客户端重传;
  • 2)ack确认:图二中(4、推送5、送达6、确认7、完成)失败,即ack处理失败,启动重新通知逻辑。

6.3消息的一致性

1)是什么:

  • 1)现象:本来用户A给用户B发送了一个"hello world",而用户B确收到了两个"hello world";
  • 2)原因:由于可靠性逻辑中的重传逻辑,可能造成客户端认为失败了,但是服务端却成功了;推送ack返回错误,造成重推。

2)身份证带来的启示。

3)怎么办:

  • 1)client_msg_id:客户端发送消息时生成客户端id,对于单个客户端,该id具有唯一性,像身份证一样;
  • 2)客户端去重:如果客户端发现相同client_msg_id的消息,则仅仅展示一条数据。

7、IM高可用、高并发

1)扩缩容:

依托公司rpc服务注册发现能力,借助docker快速扩容,核心处理逻辑logic服务实现秒级扩容。扩容依据为各种监控指标,包括机器性能指标、 entry/logic qps指标、jvm指标、sql监控等综合考量。

2)熔断:

当大流量进入时,如果核心服务依赖的服务(比如母子账号服务)出现不可用的情况。这时,我们是直接使IM服务不可用吗?是不是有更好的选择?答案是肯定的,我们可以牺牲母子账号功能,也就是熔断不重要的依赖服务,做到柔性可用。

3)限流:

如果遇到瞬时高流量,仅仅扩容有可能适得其反。如果db处理能力达到极限,扩容就不是明智的选择,扩容反而会导致db连接增多,增加db的压力,导致服务崩溃。这时退一步采用限流,应用“fast fail”策略,让部分流量快速失败,减小服务压力,达到部分可用的效果。

4)总结:

IM作为电商应用中的一个重要节点,其重要性不言而喻,对其怎么重视都不为过。我们使用监控工具定义IM的核心metrics,根据指标进行扩缩容,这样做到了高可用;

高可用是万能的吗?IM依赖了很多服务,比如用户,母子账号,风控等服务,如果这些服务出现不可用的情况呢?这个时候就要学习一下古人的智慧,壮士断腕,牺牲小我,换取大我了,也就是柔性可用;

仅仅这样还是不够的,如果遇到突发流量,db(不可瞬时扩大处理能力)等处理能力达到极限时这个时候就要牺牲部分请求了,也就要做到部分可用。从“高可用”到“柔性可用”再到“部分可用”,面对不同case,IM要做到游刃有余。

其实,这种思想又何止IM呢,任何重要的服务都要面对这些问题吧,推而广之,面对自己负责的服务,怎么精细小心都不为过。

8、本文小结

诚然,这篇文章给大家对IM系统简单的认识,阐述了IM的一般架构、主要业务逻辑、常见问题和解决方案以及服务治理相关应用,IM还有很多业务逻辑和技术挑战。

在业务上,如未读数、群聊、多端登陆、母子账号等;在技术上,entry长连接100k问题优化、时间轮计时器实现、海量数据拆分与存储选型等。

路漫漫其修远兮,吾将上下而求索。

9、参考资料

[1] 零基础IM开发入门(二):什么是IM系统的实时性?

[2] 零基础IM开发入门(三):什么是IM系统的可靠性?

[3] 零基础IM开发入门(四):什么是IM系统的消息时序一致性?

[4] IM消息送达保证机制实现(一):保证在线实时消息的可靠投递

[5] IM消息送达保证机制实现(二):保证离线消息的可靠投递

[6] 如何保证IM实时消息的“时序性”与“一致性”?

[7] 阿里IM技术分享(四):闲鱼亿级IM消息系统的可靠投递优化实践

[8] 阿里IM技术分享(五):闲鱼亿级IM消息系统的及时性优化实践

[9] 一套亿级用户的IM架构技术干货(下篇):可靠性、有序性、弱网优化等

[10] 融云技术分享:全面揭秘亿级IM消息的可靠投递机制

[11] 一套海量在线用户的移动端IM架构设计实践分享(含详细图文)

[12] 一套原创分布式即时通讯(IM)系统理论架构方案

[13] 从零到卓越:京东客服即时通讯系统的技术架构演进历程

[14] 蘑菇街即时通讯/IM服务器开发之架构选择

[15] 现代IM系统中聊天消息的同步和存储方案探讨

[16] 一套高可用、易伸缩、高并发的IM群聊、单聊架构方案设计实践

[17] 马蜂窝旅游网的IM系统架构演进之路

[18] 一套分布式IM即时通讯系统的技术选型和架构设计

[19] 微信团队分享:来看看微信十年前的IM消息收发架构,你做到了吗

[20] 携程技术分享:亿级流量的办公IM及开放平台技术实践


(本文已同步发布于:http://www.52im.net/thread-4773-1-1.html)

posted @ 2025-02-13 12:33 Jack Jiang 阅读(59) | 评论 (0)编辑 收藏

     摘要: 本文引用了“蔷薇Nina”的“Nginx 相关介绍(Nginx是什么?能干嘛?)”一文部分内容,下文有修订和改动。1、引言Nginx(及其衍生产品)是目前被大量使用的服务端反向代理和负载均衡方案,从某种意义上来讲,Nginx几乎是低成本、高负载Web服务端代名词。如此深入人心的Nginx,很多人也想当然的认为,在IM或消息推送等场景下是否也能使用Ng...  阅读全文

posted @ 2025-02-06 13:54 Jack Jiang 阅读(85) | 评论 (0)编辑 收藏

1、前言

一个孤独的小人,面对巨大的地球站在那里,这就是微信的启动画面,许多人对此非常熟悉。而知道画面里是非洲,就不是那么容易了。这是因为图片里的地球为云团笼罩,只露出一部分地貌特征,需要对世界地图比较熟悉的有心人才能发现这一点。

 
 技术交流:

2、图片解读

不过,因为有了我,一切都变得很简单了:

非洲大陆东北角上,那狭长的红海,和东南角上的马达加斯加岛,我都用红圈标注了出来。通过对比,这是一望而知的事情。两张图的区别在于,地图是在赤道上空看地球,而照片要偏南半球很多,以至于欧洲被挤到了图片之外,相反是南极洲在图片下方占据了大量面积。

问题在于,各个国家习惯性地把自己国家置于地图的中心。例如下面英国出版的世界地图,和你平常看到的世界地图绝对不一样:

中国不在地图的中心,是不是这样?那么,为什么微信的启动画面上的地球是正对非洲,而不是中国呢?

因为它不是地图,而是一张照片,一张真实的照片,用哈苏照相机在4万5千公里外拍摄的地球照片。这张照片的官方编号是:AS17-148-22727,民间给它的名字叫“蓝色弹珠”(The Blue Marble)。

3、“蓝色弹珠”(The Blue Marble)

要谈一下这张照片,必须说到美国的“阿波罗登月计划”。从1961年5月到1972年12月的十一年时间里,美国持续进行了一系列载人登月太空飞行。其中,有6次成功登上月球。而大家最为熟悉的失败案例是阿波罗13号登月计划,它被拍成了一部非常精彩的电影。

蓝色弹珠这张照片拍摄于1972年12月7日,当时宇航员在阿波罗17号飞船上,三名宇航员中的某一位用一台80毫米镜头的哈苏照相机,拍下了完整的地球照片。这张照片非常难得,因为阿波罗17号飞船执行的是最后一次阿波罗登月计划,从此以后,人类已经很久没有飞船抵达这个距离对地球进行拍照。我们看到的大量地球的照片,都是合成照,而不是太空实拍。

站在宇航员的角度,于4万5千公里之外看过去,地球就像是一颗很小的蓝色弹珠,这就是这张照片名字的由来。

4、最文艺的解读

微信的启动画面就是用了这张“蓝色弹珠”,人类最近一次在太空中远眺母星的景象。作为一种人际沟通工具,没有第二张图能更好地表达出人类内心的孤独,以及地球家园的美好。所以,整个画面有一种孤清中的淡淡暖意,给人的感觉是文艺到死。等你知道了背后的故事,又会觉得闷骚到死。

5、另外一种解读

我这里有另外一个不同的答案:

— 为什么不是正对着中国?

— 因为他在等待着那人转过来。

— 转过来之后呢?

— I WANT YOU!

6、更多QQ、微信的技术故事

技术往事:微信估值已超5千亿,雷军曾有机会收编张小龙及其Foxmail

QQ和微信凶猛成长的背后:腾讯网络基础架构的这些年

闲话即时通讯:腾讯的成长史本质就是一部QQ成长史

2017微信数据报告:日活跃用户达9亿、日发消息380亿条

腾讯开发微信花了多少钱?技术难度真这么大?难在哪?

技术往事:创业初期的腾讯——16年前的冬天,谁动了马化腾的代码

技术往事:史上最全QQ图标变迁过程,追寻IM巨人的演进历史

技术往事:“QQ群”和“微信红包”是怎么来的?

开发往事:深度讲述2010到2015,微信一路风雨的背后

开发往事:微信千年不变的那张闪屏图片的由来

开发往事:记录微信3.0版背后的故事(距微信1.0发布9个月时)

一个微信实习生自述:我眼中的微信开发团队

首次揭秘:QQ实时视频聊天背后的神秘组织

为什么说即时通讯社交APP创业就是一个坑?

微信七年回顾:历经多少质疑和差评,才配拥有今天的强大

前创始团队成员分享:盘点微信的前世今生——微信成功的必然和偶然

即时通讯创业必读:解密微信的产品定位、创新思维、设计法则等

QQ的成功,远没有你想象的那么顺利和轻松

QQ现状深度剖析:你还认为QQ已经被微信打败了吗?

[技术脑洞] 如果把14亿中国人拉到一个微信群里技术上能实现吗?

QQ和微信止步不前,意味着即时通讯社交应用创业的第2春已来? 

那些年微信开发过的鸡肋功能,及其带给我们的思考

读懂微信:从1.0到7.0版本,一个主流IM社交工具的进化史

同为IM社交产品中的王者,QQ与微信到底有什么区别

还原真实的腾讯:从最不被看好,到即时通讯巨头的草根创业史

QQ设计团队分享:新版 QQ 8.0 语音消息改版背后的功能设计思路

社交应用教父级人物的张小龙和马化腾的同与不同

专访马化腾:首次开谈个人经历、管理心得、技术创新、微信的诞生等

一文读懂微信之父张小龙:失败天才、颠覆者、独裁者、人性操控师

微信纯血鸿蒙版正式发布,295天走完微信14年技术之路!

>> 更多同类文章 ……

(本文已同步发布于:http://www.52im.net/thread-204-1-1.html

posted @ 2025-02-05 11:47 Jack Jiang 阅读(137) | 评论 (0)编辑 收藏

Jack Jiang的 Mail: jb2011@163.com, 联系QQ: 413980957, 微信: hellojackjiang