本文由字节蟩动张华挺分nQ原?#8220;你不知道的前端音视频知识”Q下文有修订和重新排版?/p>
本文回顾了Web端音视频的发展历E,同时q介l了视频的编码、率、比特率{概念,提到了Canvas作ؓ(f)视频播放的替代方案,以及(qing)FFmpeg在音视频处理中的重要作用{知识?/strong>
- Ud端IM开发入门文章:(x)?a rel="noopener nofollow" target="_blank" style="color: #1d58d1; text-decoration-line: none;">新手入门一就够:(x)从零开发移动端IM?/p>
- 开源IM框架源码Q?a rel="noopener nofollow" target="_blank" style="color: #1d58d1; text-decoration-line: none;">https://github.com/JackJiang2011/MobileIMSDKQ?a rel="noopener nofollow" target="_blank" style="color: #1d58d1; text-decoration-line: none;">备用地址Ҏ(gu)Q?/p>
Web端音视频的发展史得从刀耕火U的q代——早期 HTML说v?/p>
在早期的 HTMLQ由于带宽、技术等各种因素限制Q网主要以单的静态内容ؓ(f)主,只支持一些文字图片内容和单的排版Q不支持在线观看韌频?/p>
图ؓ(f) 1994 q的 Yahoo!Q?/p>
20 世纪初,随着互联|的发展Q各U?Web 应用和门L(fng)站不断出玎ͼZ渴望在网上看到更加丰富多彩的内容,比如视频、动ȝ{,于是 Flash q入了h们的视野?/p>
彼时?Flash 没有像现在大家印象中的那么臃肿,刚诞生的 Flash y、高效、跨q_Q同时凭借几?K 的体U做出放大也不会(x)q的各U矢量彩色动画,在还是拨号上|,带宽条g受限Q加载一个在U视频需要好几分钟的q代脱颖而出Q甚臛_以做出各Uo(h)人沉qL(fng) Flash 游戏?/p>
Flash 塑造了很多l典的小游戏角色Q火柴h是其中之一Q?/strong>
Flash 的兴P得益于当?HTML 对于媒体文g支持的匮乏?/strong>Flash 以插件的形式Q干着q_才需要负担的J重工作Qƈ得益?Adobe 的大力推q,Flash 先后增加了对 Javascrip、HTML、XML 的支持,q增Z影音斚w的功能。同时由?Flash 跨^台的Ҏ(gu),非常Ҏ(gu)被移植,市面上稍微高端点的设备,也得乖乖地给 Adobe 交授权费?/p> 然?nbsp;2007 q推出的 iPhone q不买̎Q他们以增加l航、安全ؓ(f)由抛弃了 FlashQ很多h一开始对此嗤之以鼻,但事实证明苹果对此确实有q见Q大量低质量?Flash 使当时箋航本有限的Ud讑֤更加不堪重负?012 q_(d)Android 也宣布不再支?FlashQFlash 在移动市Z再有立之地?/p> 在桌面市ZQFlash 的日子也q不好过?/strong>Chrome 从的 Chrome 42 开始,已l强制把 Flash 装入沙箱Q以 PPAPI 的Ş式运行;而从 Chromium 版本?88 开始,已经d不再支持 Flash 技术了。微软的 Edge 览器也同步不支?Flash。Chrome 的前?Firefox 更加Ȁq,?2016 q就已经默认止 Flash q行了?/p> 至于 Flash Z么走向了淘汰Q除了它的效率变低,不安全因素过多,E_性不_Q还有一个重要原因:(x)Web 韌频解x案有了更好的替代?#8212;— HTML5?/strong> 其实Q对?HTML5 是否可以真正替代 FlashQ尤大在 2011 q已l给Z预言Q?/strong> 事实正如预言所预料Q?strong>HTML5 ?2008 q发布后Q经q不断改q完善,基本上能包办 Flash 所有能q的事情了?/strong>HTML5 引入了许多新Ҏ(gu)和新功能,其中包含了 video ?audio 标签Q也是寚w视频的支持。用了支持 HTML5 标准的网l浏览器讉K HTML5 站点Q用h需在电(sh)脑上安装 Flash 插g可以在U观看视频,摆脱了对 Flash 的依赖?/p> 2021 q?1 ?20 日,chrome 88 正式发布Q彻底的止使用 Flash。自此,Flash 是d退Z历史舞台?/p> 视频Q其实就是一pdq箋播放的图片,如果一U钟播放 24 张图片,那么人眼看到的就不再是一张张独立的图片,而是动v来的画面?/p> 其中一张图片称Z帧,1s 播放的图片数UCؓ(f)帧率。由于hcȝ睛的Ҏ(gu)生理l构Q如果所看画面之帧率高于每秒U?10-12 帧的时候,׃(x)认ؓ(f)是连贯的Q当看到帧率?24 fps 以上Ӟ大脑?x)认是流畅播攄视频。所以一般有声电(sh)q拍摄?qing)播攑֓率大Uؓ(f)每秒 24 帧,Ƨ美、日本那边由于电(sh)视制式不同,大约?30 帧?/p> 关于视频?qing)视频编码相关的入门文章可以l箋详读以下资料Q?/strong> Z?24 帧的?sh)媄?30 帧的游戏要流畅许多?q其中的原因在于,?sh)媄和游戏的囑փ生成原理不同?/strong> ?sh)媄?24 fpsQ是?1/24 U拍摄一副画面,如果你玩q相机的手动讄Q你应该知道如果?1/24 U的快门速度拍摄一个运动的物体?#8220;p?#8221;掉,而正是这?#8220;p?#8221;掉的画面qv来才让我们的眼睛看上d“畅”?/p> 而游戏画面不是按 1/24 U快门拍出来的,而是每一q画面都是独立渲染出来的Q之所以跑?24fps 是因为显卡处理能力不够?#8220;丢弃”了其中的一些画面,q样一来每两幅画面之间׃q箋了,自然看上M(x)“?#8221;?/p> 举个例子Q?/strong>一个圆从左上角Ud到右下角Q如果是?sh)媄Q第一帧与W二帧可能是cM下图q样的?/p> 如果是游戏画面,W一帧与W二帧会(x)cM下面q两张图Q?/p> 此外Q与之间间隔恒定Q?/strong>人眼对于动态视频的捕捉是非常敏感的Q电(sh)影率是固定不变Q肉眼很隑֯觉出异常?/p> 而游戏的帧率却是很容易变化的——如果手动锁定帧数Q显卡会(x)默认渲染最高率?/p> 玩家触发的很多剧情往往伴随剧烈的画面变动,q时昑֍的率就?x)出C降,前后不一致的帧率很容易被肉眼捕捉Q这时我们就?x)觉得,游戏?#8220;?#8221;了?/p> 视频是由囄构成的,囄是由像素构成的,假设寸?1980*1080。每个像素由 RGB 构成Q每?8 位,?24 位?/p> 假设帧率?24Q那么每U钟的视频的寸如下Q?/strong> 一分钟视频的尺寸就?9237888000 Bytes 已经?8.8 ?G 了。可以看刎ͼ如果是不对视频做M处理Q是非常不方便对于视频做传输与存储的Q所以需要对视频q行压羃Q也是~码?/p> 视频囑փ数据有很强的相关性,也就是说有大量的冗余信息。其中冗余信息可分ؓ(f)I域冗余信息和时域冗余信息。压~技术就是将数据中的冗余信息LQ去除数据之间的相关性)Q压~技术包含内图像数据压~技术、间图像数据压~技术和늼码压~技术?/p> l过~码之后Q视频由一帧的图片,变成了一串串让h看不懂的二进制代码,因ؓ(f)~码的方?法)的不同,所以就有了~码格式的区分。常见的~码格式?H.264QMPEG-4QVP8 {?/p> 我们前端开发只需要记住一点,L览器支持的视频~码格式?H.264?/p> CD 韌的音频,存放一分钟数据需要的大小?10MQ太大了Q也需要压~(~码Q?/p> 常见的编码方式有Q?/strong>WAV、MP3 ?AAC 格式?/p> 音频的编码方式不像视频那样那么多Q而且音频在各个浏览器基本上都可以播放。具体的每种~码格式包含的音频是怎么构成的,q里׃讲了?/p> 关于音频?qing)音频编码相关的入门文章可以l箋详读以下资料Q?/strong> 我们把视频数据、音频数据打包到一P然后再添加一些基本信息,例如分L率、时ѝ标题等Q构成一个文Ӟq个文gUCؓ(f)装格式。常见的装格式?MP4、AVI、RMVB {?/p> 可以看出Q?/strong>视频的封装格式和视频的编码格式往往是无关的?/span>一?mp4 文g里面的视频流~码可以?h264也可以是 mpeg-4。所以就?x)出玎ͼ同样都?mp4 文gQ有的浏览器可以放,有的览器就放不了的问题Q因不能放是p频码的~码格式军_的?/p> 码率Q也叫比特率Q?/strong>帧率?1s 播放多少帧,cL一下,比特率就?1s 的视频有多少 bit?strong>q个参数直接军_了视频的大小与清晰程度?/strong> 一般网上流传的?sh)?MKVQBDrip-1080PQ的码率?10Mb/s 左右Q蓝光原盘是 20Mb/s 左右Q这两者都?H.264 ~码的。另外一?MV、PV、演C片什么的除了 H.264 ~码Q可能还?MPEG-2 ~码Q码率大不{,?youtube 那些在线?1080P 的视频,码率可能只有 5Mb/sQ而一?MV 的码率可以高到离谱,可以辑ֈ 110Mb/s 的,3 分多钟的 MV 差不多有 3GB 大小?/p> 而一般的视频剪辑、后期YӞ在输出序列的时候,都会(x)有码率这个选项?/p> 播放视频的基本流E是Q?/strong>解协?→ 解封?→ 解码 → 视音频同步。如果播放本地文件则不需要解协议?/p> 解协议的作用Q就是将媒体协议的数据Q解析ؓ(f)标准的相应的装格式数据?/strong>视音频在|络上传播的时候,常常采用各种媒体协议,例如 HTTP、RTMP或是 MMS {等。这些协议在传输视音频数据的同时Q也?x)传输一些信令数据。这些信令数据包括对播放的控Ӟ播放、暂停、停止)Q或者对|络状态的描述{。解协议的过E中?x)去除掉信o(h)数据而只保留视音频数据?/p> 解封装的作用Q就是将输入的封装格式的数据Q分L为音频流压羃~码数据和视频流压羃~码数据?/strong>装格式U类很多Q例?MP4、MKV、RMVB、TS、FLV、AVI {等Q它的作用就是将已经压羃~码的视频数据和音频数据按照一定的格式攑ֈ一赗例如,FLV 格式的数据,l过解封装操作后Q输?H.264 ~码的视频码和 AAC ~码的音频码?/p> 解码的作用,是视?音频压羃~码数据Q解码成为非压羃的视?音频原始数据?/strong>音频的压~编码标准包?AAC、MP3、AC-3 {等Q视频的压羃~码标准则包?H.264、MPEG2、VC-1 {等。解码是整个pȝ中最重要也是最复杂的一个环节。通过解码Q压~编码的视频数据输出成ؓ(f)非压~的颜色数据Q例?YUV420P、RGB {等Q压~编码的音频数据输出成ؓ(f)非压~的音频抽样数据Q例?PCM 数据?/p> 视音频同步的作用Q就是根据解装模块处理q程中获取到的参C息,同步解码出来的视频和音频数据Qƈ视频音频数据送至pȝ的显卡和声卡播放出来?/p> 如果我们到一些特D机型或者特D情?HTML5 ?video 解决Ҏ(gu)不是很好处理Q也可以采用 Canvas L放这个视频?/p> 使用 Canvas 播放视频主要是利?nbsp;ctx.drawImage(video, x, y, width, height) 来对视频当前帧的囑փq行l制Q其?video 参数是面中的 video 对象。所以如果我们按照特定的频率不断获取 video 当前画面Qƈ渲染?Canvas d上,可以实C?Canvas 播放视频的功能?/p> <video id="video" controls="controls" style="display: none;"> <source src="https://xxx.com/vid_159411468092581" /> </video> <canvas id="myCanvas" width="460" height="270" style="border: 1px solid blue;" ></canvas> <div> <button id="playBtn">播放</button> <button id="pauseBtn">暂停</button> </div> const video = document.querySelector("#video"); const canvas = document.querySelector("#myCanvas"); const playBtn = document.querySelector("#playBtn"); const pauseBtn = document.querySelector("#pauseBtn"); const context = canvas.getContext("2d"); let timerId = null; function draw() { if (video.paused || video.ended) return; context.clearRect(0, 0, canvas.width, canvas.height); context.drawImage(video, 0, 0, canvas.width, canvas.height); timerId = setTimeout(draw, 0); } playBtn.addEventListener("click", () => { if (!video.paused) return; video.play(); draw(); }); pauseBtn.addEventListener("click", () => { if (video.paused) return; video.pause(); clearTimeout(timerId); }); 事实上,市面上已l有不少 Canvas 播放视频的解x案,比较出名的是q个 JSMpeg。它?PIXI 一P可以选择 WebGL 渲染视频也可以直接用 Canvas 渲染视频?/p> JSMpeg 是没?npm 包的Q但是社Z有开发者基?JSMpeg 装了一?npm 包:(x)https://github.com/cycjimmy/jsmpeg-player?/p> 在官|上是这么介l的Q?/strong> JSMpeg is a Video Player written in JavaScript. It consists of an MPEG-TS Demuxer, WebAssembly MPEG1 Video & MP2 Audio Decoders, WebGL & Canvas2D Renderers and WebAudio Sound Output. JSMpeg can load static files via Ajax and allows low latency streaming (~50ms) via WebSocktes. ׃它所支持的编码格式不是常规的 H.264Q而是比较老的 MPEG1Qƈ且解装器ؓ(f) MPEG-TS。所以一般我们用它L染视频的格式?TS。TS 是日本高清摄像机拍摄下进行的装格式Q全UCؓ(f) MPEG2-TS。它的特点就是要求从视频的M片段开始都是可以独立解码的?/p> TS 文g通常作ؓ(f)多个文g保存?DVD 上,虽然它可以在高清摄像机、蓝?DVD 中无需借助其他软gp直接打开Q但?TS 视频文g与大多数的媒体播攑֙、便携式播放器或视频~辑工具都不兼容Q所以这个时候,FFmpeg 可以出Z?/p> FFmpeg是一个开源的软gQ我们直接用 homebrew 可以安装:(x) 1brew install ffmpeg 如果我们惌{换ؓ(f) jsmpeg 所需?ts 格式视频Q可以执行:(x) $ ffmpeg -i input.mp4 -f mpegts \ -codec:v mpeg1video -s 640x360 -b:v 1500k -r 25 -bf 0 \ -codec:a mp2 -ar 44100 -ac 1 -b:a 64k \ output.ts B 帧法QB frameQ是双向预测的间压~算法。当把一帧压~成 B 帧时Q它Ҏ(gu)盔R的前一帧、本帧以?qing)后一帧数据的不同Ҏ(gu)压羃本Q也即仅记录本与前后的差倹{?/p> 音频采样率是指录韌备在单位旉内对模拟信号采样的多,采样频率高Q机械L的L形就真实越自然Q?/p> 音频码率Q指一个音频流中每U钟能通过的数据量Q码率越大的话,韌好?/p> FFmpeg 是一个非常强大的韌频{换工P不仅可以视频转换Q还可以视频寸裁剪、视频时长裁剪、视频拼接等{功能,目前很多在线视频剪辑工具基本是基?FFmpeg 开发的?/p> 国内学习(fn)韌频相关的开发,l不q的一个大是雷霄骅,大{已经M了,但是留下的文章永垂不朽。本文也是参考了雷霄骅的部分博客Q如果感兴趣Q可以从q篇文章看vQ?a target="_blank" rel="noopener nofollow" style="color: #1d58d1; text-decoration-line: none;">视音频编解码技术零基础学习(fn)Ҏ(gu)》?/p> 对于直播 webrtc 感兴的Q也可以看一?nbsp;Real time communication with WebRTCQ国内慕评上李老师也有不错的教E?/p> ?ffmpeg 感兴的Q可以看一下这里:(x)https://github.com/leandromoreira/ffmpeg-libav-tutorial?/p> [1] x通讯韌频开发(十八Q:(x)详解音频~解码的原理、演q和应用选型 [2] x通讯韌频开发(十九(ji)Q:(x)零基Q史上最通俗视频~码技术入?/a> [3] x通讯韌频开发(二十Q:(x)一文读懂视频的颜色模型转换和色域{?/a> [5] |易视频云技术分享:(x)音频处理与压~技术快速入?/a> [6] 利_(d)(x)最全实旉视频开发要用到的开源工E汇?/a> [9] 爱奇艺技术分享:(x)L诙谐Q讲解视频编解码技术的q去、现在和来 [10] 零基入门Q实旉视频技术基知识全面盘点 [11] 实时韌频面视必备:(x)快速掌?1个视频技术相关的基础概念 [12] 实时韌频开发理论必备:(x)如何省流量?视频高度压羃背后的预技?/a> [13] 视频直播技术干?十三)QB站实时视频直播技术实践和韌频知识入?/a> [14] 零基入门Q基于开源WebRTCQ从0?实现实时韌频聊天功?/a> [15] 实时韌频入门学?fn)?x)开源工EWebRTC的技术原理和使用析 [16] 零基快速入门WebRTCQ基本概c(din)关键技术、与WebSocket的区别等4、HTML5的到?/h1>
5、到底什么是视频
6、电(sh)q帧率与游戏的帧率
7、视频的~码
7.1 概述
7.2 视频~码
7.3 音频~码
7.4 装格式
8、视频的码率
9、视频播攑֙的原?/h1>
10、HTML5的canvas播放视频
11、视频操作神?#8212;—FFmpeg
12、音视频的一些资源推?/h1>
13、参考资?/h1>
Q本文已同步发布于:(x)http://www.52im.net/thread-4840-1-1.htmlQ?/a>
本文p讯技术团队罗国佳分nQ原?#8220;微信M后台架构演进之\”Q下文有修订和重新排版?/p>
今年是微信读书上U?0周年Q后台技术架构也伴随着微信M的成长经历了多次q代与升U。每一ơ的lg升与架构突_(d)在一个运行了10q的pȝ上落地都不是一件容易的事情Q需要破釜沉舟的军_与胆大心l的业务联动?/p>
微信Ml过了多q的发展Q赢得了良好的用户口,后台pȝ的服务质量直接媄响着用户的体验?/strong>团队多年来始l保持着“而美”的基因,快速试错与q代成ؓ(f)常态?strong>后台团队在日怸务开发的同时Q需要主动寻求更多架构上的突_(d)提升后台服务的可用性、扩展性,以不断适应业务与团队的变化?/strong>
技术交:(x)
- Ud端IM开发入门文章:(x)?a rel="noopener nofollow" target="_blank" style="color: #1d58d1; text-decoration-line: none;">新手入门一就够:(x)从零开发移动端IM?/p>
- 开源IM框架源码Q?a rel="noopener nofollow" target="_blank" style="color: #1d58d1; text-decoration-line: none;">https://github.com/JackJiang2011/MobileIMSDKQ?a rel="noopener nofollow" target="_blank" style="color: #1d58d1; text-decoration-line: none;">备用地址Ҏ(gu)Q?/p>
微信M是独立于微信的AppQ且׃历史原因Q开发及(qing)q维环境均存在一定的差异与隔R因此,微信M的后台服务实C从接入层到存储层的一整套完整架构?/p>
架构上分解ؓ(f)典型的接入层、逻辑层和存储层:(x)
1Q?/em>接入层:(x)按业务划分ؓ(f)多个CGI服务Q实C资源隔离。在CGI层面q实C如\由、频控、接入层~存、长q接{?/p>
2Q?/em>逻辑层:(x)采用WRMesh框架构徏了多个微服务Q这些微服务按业务场景进行划分,实现了不同模块间的解耦。框架也提供了如RPC、\由发现、过载保护、限频控、监控上报等能力?/p>
3Q?/em>存储层:(x)主要采用PaxosStore存储用户数据Q分为K-V和K-Table两种cdQ具备高可用、强一致的Ҏ(gu),针对String和Table两种cd定制了缓存中间gQ以适配某些业务场景下对讉K存储的性能要求。BookStore提供书籍的存储服务,满M场景下对书籍的拆章、修攏V下载等需要。此外,也不同程度地使用了腾讯云的PaaS存储服务Q以灉|满更多场景需要?/p>
具体的业务逻辑不再赘述Q下面简单介l下微信Mq几q在后台架构上的一些演q?/p>
微信M后台微服务源于Hikit框架Q采用C++开发。该框架诞生于广研、QQ邮箱q代Q在性能、容灾、运l、监控层面都l受了线上的考验Q在微信M上线初期作ؓ(f)主要框架Q支撑了后台服务长达数年?/p>
随着微信M的发展,来多异构的系l发展v来。例如推荐算法系l是独立部v在TKE上的容器服务Q采用GO语言开发,好处是历史负担少Q运l更加方ѝ开发更加便捗?/p>
两套pȝ同时存在带来的问题是如何做好服务ȝQ推荐系l需要频J调用后台基模块获取用户数据Q必要有一套完善的路由理、容灾机Ӟ且考虑到是异构服务Q开发语a也不相同Q如果ؓ(f)每种语言都定制开发一套服务治理框Ӟ代h(hun)?x)非帔R?/p>
在这个阶D,我们开发了WRMesh框架Q采用Sidecar+Business的方式解册个问题?/p>
Sidecar专注于处理网l层的逻辑Q和Business业务层分开Z个进E,由WRMesh脚手架生成代码,上层业务无需感知?/p>
Sidecar集成了Hikit框架中用于服务治理的核心逻辑Q?/strong>通过UnixSocket与Businessq行通信Q代理Business的所有网l读写。当Businessq程中需要发L(fng)l请求时Q由WRMesh生成的Client代码?x)自动识别当前是否在mesh环境中,q{发请求给SidecarQ由Sidecar完成接下来的|络处理?/p> 因此Q?/strong>Businessq程可以׃Q意语aL框架开发,只要遵@Sidecar的通信协议Q只需要薄薄的一层网l协议{换即可接入到Hikit的服务治理框架中?/p> 另外Q?/strong>对于某些有特D\由逻辑的ClientQ如KV讉K、Batchh{,代理转发q不能满求,因此Sidecarq提供了插g能力集成q些Client逻辑Q最大限度ؓ(f)异构Business业务提供原生C++的能力?/p> 随着WXG容器q_P6N的徏设越来越完善Q许多微信的能力也是ZP6N提供Q我们也在思考如何逐步q移到P6N。由于微信读书后台运l目前依赖于企微团队Q有独立于P6N的一套运l体p,我们负责业务和架构开发?/p> 如果要一刀切把所有后台服务迁U至P6NQ将?x)面临几个问题?x) 1Q?/em>框架代码需要重新适配Q开发环境和现网环境都有巨大的改造成本?/p> 2Q?/em>q移不是一y而就Q后C百个服务在迁U过E中Q会(x)存在新旧服务互调的问题,׃q维环境不互通,微服务之间无法完成服务治理,q种互相调用最l只能通过Proxy来{发,不仅增加了网l的p|率,时g增加Q最关键的是q个q程?x)让容灾体系大打折扣?/p> 3Q?/em>存储模块的迁UL本和风险巨大Q如果不q移存储模块只迁UM逻辑模块Q那势必又会(x)存在2中的问题Q这个过E很难收?/p> 考虑Ch力成本及(qing)投入性h(hun)比,我们最l采用了折衷的方案:(x) 1Q?/em>一斚wQ我们保留了依赖于企微的q维环境Q保障绝大多数现成服务的E_q行?/p> 2Q?/em>另一面:(x)对于微信P6N中的服务Q我们搭Z比较完善的Proxy层,例如Svrkit代理、WQueue代理{,两套架构可以方便q行互通,最大限度的在原有基上接入微信的新能力?/p> 目前Q微信读书已利接入如WQueue、FKVOL、SimOL、TFCC{众多微信的能力?/p> 书籍是微信读书的内容根基Q书c数量的多少、书c质量的好坏Q很大程度上军_了用h否选择微信M作ؓ(f)阅读App?/p> q去Q?/strong>我们依托阅文集团提供?sh)子书资源,免去了书c上架前J琐的处理流E,包括排版、审校、元信息理、更新管理等Q后台服务只需要对接阅文API卛_方便获取书籍数据Q我们只需要关注书c在q_的存储管理和分发{卛_?/p> q几q_(d)(x)?sh)子书行业的大环境发生变化,一斚wQ用户对书籍品类多样性、内容质量有更高的诉求,另一斚wQ^台对成本、版权等行业因素也更为敏感。因此,我们也在U极探烦自签版权Q甚x自出品的模式Q尝试走更多不一L(fng)道\。从后台角度而言Q从q去单一依赖阅文集团API的模式,慢慢转ؓ(f)开放更多的书籍理接口QŞ成书c数据中台模式,Z层运营同学搭建内容管理^収ͼ让更多h可以方便参与到电(sh)子书的制作、排版、上下架、运营管理当中?/p> 以EPUBZQ从内容产出C架到微信MQ大致经历以下阶D:(x) 1Q?/em>排版审校Q这个阶D多Zh工或者部分机器自动化介入?/p> 2Q?/em>上架预处?/span>Q这个阶D需要创Zc信息,配置各种q营{略Q当q本书是重排版上架时Q内容发生改变,׃现网已经存在用户的划U笔记、进度等数据Q需要有完善指标评估是否适合覆盖上架Q当上架Ӟ需要对用户数据q行修复Q避免发生错位情况,严重影响用户体验?/p> 3Q?/em>EPUB解析Q当书籍上架后,׃EPUB是单一文gQ不适合解析和管理分发,因此后台?x)把源文件解析成自有格式Q包括EPUB拆章、图文分R样式分R按章生成离U包{等?/p> 4Q?/em>生成BookInfo和BookDataq落?/span>QEPUB文gl过解析后,BookInfo和BookData?x)存储到自徏的StoreSvr服务上,StoreSvr针对书籍存储、下载等场景q行了很多优化,具备高可用、低时g的特点,提供了书c信息获取、按章下载等核心接口?/p> 回到最初的目标Q我们希望把更多的书c管理能力开攑և来,对上层屏蔽电(sh)子书底层的后台逻辑Q让q营同学可以更专注于书籍的管理?/p> 因此Q我们构Z如下书籍数据中台Q?/strong> 后台服务拆分开StoreAPI和StoreSvrQ?/strong> 1Q?/em>StoreAPIQ提供书c管理的接口Q由q营同学搭徏的内容^CStoreAPI交互Q完成书c的理工作Q?/p> 2Q?/em>StoreSvrQ一斚w接受StoreAPI的请求,更新书籍数据Q另一斚w为现|用h供高可用的服务?/p> StoreAPI提供了如下接口能力:(x) 此外Q?/strong>如上所qͼ划线位置和阅读进度等核心UGC数据׃是按文g偏移记录Q当书籍文g替换后,q些数据?x)发生错位,如果不能及(qing)时修复Q将对用户体验造成巨大影响。尤其在一些热门书c里Q单本书里与位置相关的UGC数据往往能达CU别Q由于文件替换后位置的偏Ud有随机性,q不能采用简单的映射方式解决Q在q去Q我们开发了专门的修复服务来完成q个事情Q针Ҏ(gu)一个UGC内容Q采用全文模p查扄方式重新计算新的偏移Qƈ更新的UGC正排、书c倒排{多个存储中?/p> 但随着用户数据来多Q书c替换频率越来越频繁Q修复不?qing)时或者失败的问题逐渐暴露出来Q?/strong> 针对上面的问题:(x)我们重新设计了修复服务,目标是最大限度羃短修复时_(d)q且让整个过E是可靠的?/p> 为此Q我们先首手考虑业务程Q我们发现在书籍上架前,q营同学本来需要依赖UGC的修复情况做前置判断是否覆盖上架Q这个过E中虽然是对UGC抽样评估Q如果能对这个修复映结果进行缓存,在正式替换文件后Q也能一定程度提升修复速度?/p> 在核心修复流E中Q我们进行了较大的重构,把单本书的修复Q务拆解成多个子Q务,存储在Chubby上,多机器抢锁共同消费这些Q务,׃d有落盘,在服务上UK启过E中Q也能马上恢复。修复过E涉?qing)大量的KV写入Qƈ发太高时Ҏ(gu)命中单key的限频或者版本冲H,我们为此开发了针对K-Str和K-Table的写入中间gQ可以在内存中聚合一批请求进行批量合q写入,~解KV层面的失败?/p> 目前Q微信读书已通过内容q_完成了多家版权方自签Qƈ在探索自出品{内容创作新形式?/p> 账号是微信读书后台系l的基石Q?/strong>承担了登录、会(x)话密钥生成与z֏、用戯料管理等核心功能Q所有的用户h都需l过账号pȝq行鉴权验证用户w䆾Q但凡有一点系l抖动都?x)媄响到整个App的正怋用,严重者还?x)导致̎可t出无法再次d?/p> 账号pȝ的架构在微信M诞生之初便一直沿用,同一个号D늚账号服务AccountSvr和MySQL部v在同一台机器上Q备机采用主从同步的方式获取数据Q当L不可用时Q备机承担了所有读h?/strong> 在某些场景下Qؓ(f)了能使访问备机时也具备一定的写入能力Q曾l魔改过d逻辑Q但一切都昑־L不治本,且引入了更复杂的pȝҎ(gu),整个架构略显混ؕ。在机器裁撤、数据扩容过E中Q曾造成q几ơ严重故障,DApp不可用,严重影响用户体验。究其原因,是因为当时基设施q不完善Q缺高性能高可靠的Z致存储,MySQL也是手动搭徏的,q维成本和风险都非常高?/p> Zd解决q个历史包袱Q我们在2024下定军_对其q行重构?/strong>重构意味着要抛弃现有MySQLq套臃肿的存储方案,把数据迁Ud新的存储lg上?/p> q里涉及(qing)到的挑战点如下:(x) 背水一战,没有退路可a。在l历了多ơ论证后Q我们决定采用Paxosmemkv作ؓ(f)新的存储lgQ全内存、多副本、强一致的Ҏ(gu),很适合作ؓ(f)账号pȝ的底层存储?/p> 同时Q我们ؓ(f)整个q移q程制定了周密的Ҏ(gu)Q把每一步进行了分解Q且要求每个环节可灰度可回退Q同时要做好数据的一致性检查?/p> 在完成数据迁UdQ我们还需要对AccountSvrq行重构Q抛弃按h的̎号分配、\由、缓存逻辑Q以全新的视角设计更z的架构?/p> 以往微信M的搜索仅限于Z书名、作者等l度的文本召回,通过自徏的全内存索引服务实现书籍的检索?strong>全文(g)索则ZES搭徏Q采用规则分D늚方式建立索引Q能满M大部分场景的需要?/strong> 在大语言模型q速发展的q两q_(d)微信M作ؓ(f)一个庞大的内容知识库,h大量的书c原文资源。同Ӟ用户在微信读书也留下了大量的文字内容Q如书评、想法等Q这些内Ҏ(gu)成了AI问书的内容基矻I也是AI问书区别于其它问{工L(fng)核心优势?/p> Z微信M构徏RAG召回pȝQ核心挑战如下:(x) 1Q?/em>Z书籍原文构徏全文(g)索,Z辑ֈ最好的效果Q往往需要支持按语义q行D落切分Q在此基上构建embeddingq行语义召回。微信读书拥有百万书籍原文数据Q此外,对于用户导入书,更是辑ֈ亿别规模。现有架构无Z成本q是耗时上都无法解决?/p> 2Q?/em>Z支持更多l度的召回,需要对UGC内容q行召回Q部分UGC内容属于U密信息Qƈ不向全网公开Q只需要满用户个人检索即可。此时如果用常规的检索系l构建常ȝ引,讉K率太低,成本难以收敛?/p> 为此Q我们针对微信读书不同的RAG使用场景Q设计了如下召回架构Q?/strong> 我们把数据划分成两类Q?/strong>全局公开可搜以及(qing)用户个h可搜?/p> 1Q?/em>对于全局公开可搜索的数据Q?/span>如库内电(sh)子书的全文、书c大UӀ书评、h工知识库{,我们构徏了一套入库流E,能对源信息进行语义分Dc(din)生成正排倒排Q语义分D基于开源的chunk模型q行微调Q正排基于fkvQ倒排则基于ES构徏QES提供了DiskANNҎ(gu)Q通过讄合理的缓存和分片Q能在存储成本和召回效率之间取得不错的^衡。对?App 内主搜等低时延场景,Z满多种定制化检索需求,我们自徏了基于内存烦引的Searchsvr服务Q支持烦引落盘,可以在毫Uq回?sh)子书搜索结果?/p> 2Q?/em>对于用户个h数据Q?/span>如导入书全文、个人想法等Q特Ҏ(gu)数据量大但用频率不高,不需要针对全|用戯行检索,如果采用上述Ҏ(gu)Q会(x)带来成本NQ性h(hun)比极低。ؓ(f)此,我们按用户及(qing)物料的维度,ZUSearch、Xapian{方案构Z向量?qing)文本烦引,q些lg的优势在于可以把单个索引存储成文件的形式Q便于落盘,配合一些量化的Ҏ(gu)Q可以把大大压羃索引大小。在构徏索引阶段Q按用户+cd构徏Z同的索引Qƈ存储在低成本的COS上,当用户需要检索召回时Q采用读时加载的方式实时q行召回Q结合CFSq行预热可以大大提升(g)索速度。当(g)索完成后Q定时淘汰策略会(x)把长期不用的索引从CFS中清理,降低存储成本?/p> 虽然微信M已经发展了十个年_(d)但我们的脚步从未停止?/p> 在日怸务开发之余,我们也从未停止思考如何让pȝ能走得更q、更E_Q抓住每一个可能的优化点,随时做好准备Q迎接下一个精彩的十年?/p> [1] 腾讯资深架构师干货ȝQ一文读懂大型分布式pȝ设计的方斚w?/a> [2] 快速理解高性能HTTP服务端的负蝲均衡技术原?/a> [3] 子弹短信光鲜的背后:(x)|易云信首席架构师分享亿UIMq_的技术实?/a> [4] 知乎技术分享:(x)从单机到2000万QPSq发的Redis高性能~存实践之\ [5] 新手入门Q零基础理解大型分布式架构的演进历史、技术原理、最?jng)_?/a> [6] 阉K技术分享:(x)深度揭秘阉K数据库技术方案的10q变q史 [7] 阉K技术分享:(x)阉K自研金融U数据库OceanBase的艰辛成长之?/a> [8] 达达O2O后台架构演进实践Q从0?000高ƈ发请求背后的努力 [9] 优秀后端架构师必?x)知识?x)史上最全MySQL大表优化Ҏ(gu)ȝ [10] 米技术分享:(x)解密米抢购pȝ千万高ƈ发架构的演进和实?/a> [11] 一读懂分布式架构下的负蝲均衡技术:(x)分类、原理、算法、常见方案等 [12] 通俗易懂Q如何设计能支撑百万q发的数据库架构Q?/a> [13] 多维度对?ƾ主分布式MQ消息队列Q妈妈再也不担心我的技术选型?/a> [14] 从新手到架构师,一就够:(x)?00?000万高q发的架构演q之?/a> [16] 12306抢票带来的启C:(x)看我如何用Go实现百万QPS的秒杀pȝ(含源? 微信团队原创分nQAndroid版微信的臃肿之困与模块化实践之\ 微信异步化改造实践:(x)8亿月zR单机千万连接背后的后台解决Ҏ(gu) C交软gU包技术解?十三)Q微信团队首ơ揭U微信红包算法,Z你抢到的?.01?/a> 微信团队分nQ极致优化,iOS版微信编译速度3倍提升的实践ȝ IM“扫一?#8221;功能很好做?看看微信“扫一扫识?#8221;的完整技术实?/a> 微信团队分nQ微信支付代码重构带来的Ud端Y件架构上的思?/a> IM开发宝典:(x)史上最全,微信各种功能参数和逻辑规则资料汇?/a> 微信团队分nQ微信直播聊天室单房?500万在U的消息架构演进之\ 企业微信的IM架构设计揭秘Q消息模型、万人群、已d执、消息撤回等 IM全文(g)索技术专??Q微信iOS端的最新全文检索技术优化实?/a> 微信Windows端IM消息数据库的优化实践Q查询慢、体U大、文件损坏等 微信技术分享:(x)揭秘微信后台安全特征数据仓库的架构设?/a> 揭秘企业微信是如何支持超大规模IMl织架构?#8212;—技术解dl关p链 微信团队分nQ详解iOS版微信视频号直播中因帧率异常D的功耗问?/a> 微信团队分nQ微信后端v量数据查询从1000ms降到100ms的技术实?/a> IM技术干货:(x)假如你来设计微信的群聊,你该怎么设计Q?/a> 微信团队分nQ来看看微信十年前的IM消息收发架构Q你做到了吗 微信后团队分享:(x)微信后台ZRay的分布式AI计算技术实?/a> 一q撸完百万行代码Q企业微信的全新鸿蒙NEXT客户端架构演q之?/a> Q本文已同步发布于:(x)http://www.52im.net/thread-4839-1-1.htmlQ?/a>4、书c数据中台的演进
4.1 技术背?/h3>
4.2 数据中台
5、̎L(fng)l的高可用性重?/h1>
6、内容召回系l的架构设计
7、写在最?/h1>
8、相兌?/h1>
9、微信团队的其它_֍文章
本文p讯技术团队罗国佳分nQ原?#8220;微信M后台架构演进之\”Q下文有修订和重新排版?/p>
今年是微信读书上U?0周年Q后台技术架构也伴随着微信M的成长经历了多次q代与升U。每一ơ的lg升与架构突_(d)在一个运行了10q的pȝ上落地都不是一件容易的事情Q需要破釜沉舟的军_与胆大心l的业务联动?/p>
微信Ml过了多q的发展Q赢得了良好的用户口,后台pȝ的服务质量直接媄响着用户的体验?/strong>团队多年来始l保持着“而美”的基因,快速试错与q代成ؓ(f)常态?strong>后台团队在日怸务开发的同时Q需要主动寻求更多架构上的突_(d)提升后台服务的可用性、扩展性,以不断适应业务与团队的变化?/strong>
技术交:(x)
- Ud端IM开发入门文章:(x)?a rel="noopener nofollow" target="_blank" style="color: #1d58d1; text-decoration-line: none;">新手入门一就够:(x)从零开发移动端IM?/p>
- 开源IM框架源码Q?a rel="noopener nofollow" target="_blank" style="color: #1d58d1; text-decoration-line: none;">https://github.com/JackJiang2011/MobileIMSDKQ?a rel="noopener nofollow" target="_blank" style="color: #1d58d1; text-decoration-line: none;">备用地址Ҏ(gu)Q?/p>
微信M是独立于微信的AppQ且׃历史原因Q开发及(qing)q维环境均存在一定的差异与隔R因此,微信M的后台服务实C从接入层到存储层的一整套完整架构?/p>
架构上分解ؓ(f)典型的接入层、逻辑层和存储层:(x)
1Q?/em>接入层:(x)按业务划分ؓ(f)多个CGI服务Q实C资源隔离。在CGI层面q实C如\由、频控、接入层~存、长q接{?/p>
2Q?/em>逻辑层:(x)采用WRMesh框架构徏了多个微服务Q这些微服务按业务场景进行划分,实现了不同模块间的解耦。框架也提供了如RPC、\由发现、过载保护、限频控、监控上报等能力?/p>
3Q?/em>存储层:(x)主要采用PaxosStore存储用户数据Q分为K-V和K-Table两种cdQ具备高可用、强一致的Ҏ(gu),针对String和Table两种cd定制了缓存中间gQ以适配某些业务场景下对讉K存储的性能要求。BookStore提供书籍的存储服务,满M场景下对书籍的拆章、修攏V下载等需要。此外,也不同程度地使用了腾讯云的PaaS存储服务Q以灉|满更多场景需要?/p>
具体的业务逻辑不再赘述Q下面简单介l下微信Mq几q在后台架构上的一些演q?/p>
微信M后台微服务源于Hikit框架Q采用C++开发。该框架诞生于广研、QQ邮箱q代Q在性能、容灾、运l、监控层面都l受了线上的考验Q在微信M上线初期作ؓ(f)主要框架Q支撑了后台服务长达数年?/p>
随着微信M的发展,来多异构的系l发展v来。例如推荐算法系l是独立部v在TKE上的容器服务Q采用GO语言开发,好处是历史负担少Q运l更加方ѝ开发更加便捗?/p>
两套pȝ同时存在带来的问题是如何做好服务ȝQ推荐系l需要频J调用后台基模块获取用户数据Q必要有一套完善的路由理、容灾机Ӟ且考虑到是异构服务Q开发语a也不相同Q如果ؓ(f)每种语言都定制开发一套服务治理框Ӟ代h(hun)?x)非帔R?/p>
在这个阶D,我们开发了WRMesh框架Q采用Sidecar+Business的方式解册个问题?/p>
Sidecar专注于处理网l层的逻辑Q和Business业务层分开Z个进E,由WRMesh脚手架生成代码,上层业务无需感知?/p>
Sidecar集成了Hikit框架中用于服务治理的核心逻辑Q?/strong>通过UnixSocket与Businessq行通信Q代理Business的所有网l读写。当Businessq程中需要发L(fng)l请求时Q由WRMesh生成的Client代码?x)自动识别当前是否在mesh环境中,q{发请求给SidecarQ由Sidecar完成接下来的|络处理?/p> 因此Q?/strong>Businessq程可以׃Q意语aL框架开发,只要遵@Sidecar的通信协议Q只需要薄薄的一层网l协议{换即可接入到Hikit的服务治理框架中?/p> 另外Q?/strong>对于某些有特D\由逻辑的ClientQ如KV讉K、Batchh{,代理转发q不能满求,因此Sidecarq提供了插g能力集成q些Client逻辑Q最大限度ؓ(f)异构Business业务提供原生C++的能力?/p> 随着WXG容器q_P6N的徏设越来越完善Q许多微信的能力也是ZP6N提供Q我们也在思考如何逐步q移到P6N。由于微信读书后台运l目前依赖于企微团队Q有独立于P6N的一套运l体p,我们负责业务和架构开发?/p> 如果要一刀切把所有后台服务迁U至P6NQ将?x)面临几个问题?x) 1Q?/em>框架代码需要重新适配Q开发环境和现网环境都有巨大的改造成本?/p> 2Q?/em>q移不是一y而就Q后C百个服务在迁U过E中Q会(x)存在新旧服务互调的问题,׃q维环境不互通,微服务之间无法完成服务治理,q种互相调用最l只能通过Proxy来{发,不仅增加了网l的p|率,时g增加Q最关键的是q个q程?x)让容灾体系大打折扣?/p> 3Q?/em>存储模块的迁UL本和风险巨大Q如果不q移存储模块只迁UM逻辑模块Q那势必又会(x)存在2中的问题Q这个过E很难收?/p> 考虑Ch力成本及(qing)投入性h(hun)比,我们最l采用了折衷的方案:(x) 1Q?/em>一斚wQ我们保留了依赖于企微的q维环境Q保障绝大多数现成服务的E_q行?/p> 2Q?/em>另一面:(x)对于微信P6N中的服务Q我们搭Z比较完善的Proxy层,例如Svrkit代理、WQueue代理{,两套架构可以方便q行互通,最大限度的在原有基上接入微信的新能力?/p> 目前Q微信读书已利接入如WQueue、FKVOL、SimOL、TFCC{众多微信的能力?/p> 书籍是微信读书的内容根基Q书c数量的多少、书c质量的好坏Q很大程度上军_了用h否选择微信M作ؓ(f)阅读App?/p> q去Q?/strong>我们依托阅文集团提供?sh)子书资源,免去了书c上架前J琐的处理流E,包括排版、审校、元信息理、更新管理等Q后台服务只需要对接阅文API卛_方便获取书籍数据Q我们只需要关注书c在q_的存储管理和分发{卛_?/p> q几q_(d)(x)?sh)子书行业的大环境发生变化,一斚wQ用户对书籍品类多样性、内容质量有更高的诉求,另一斚wQ^台对成本、版权等行业因素也更为敏感。因此,我们也在U极探烦自签版权Q甚x自出品的模式Q尝试走更多不一L(fng)道\。从后台角度而言Q从q去单一依赖阅文集团API的模式,慢慢转ؓ(f)开放更多的书籍理接口QŞ成书c数据中台模式,Z层运营同学搭建内容管理^収ͼ让更多h可以方便参与到电(sh)子书的制作、排版、上下架、运营管理当中?/p> 以EPUBZQ从内容产出C架到微信MQ大致经历以下阶D:(x) 1Q?/em>排版审校Q这个阶D多Zh工或者部分机器自动化介入?/p> 2Q?/em>上架预处?/span>Q这个阶D需要创Zc信息,配置各种q营{略Q当q本书是重排版上架时Q内容发生改变,׃现网已经存在用户的划U笔记、进度等数据Q需要有完善指标评估是否适合覆盖上架Q当上架Ӟ需要对用户数据q行修复Q避免发生错位情况,严重影响用户体验?/p> 3Q?/em>EPUB解析Q当书籍上架后,׃EPUB是单一文gQ不适合解析和管理分发,因此后台?x)把源文件解析成自有格式Q包括EPUB拆章、图文分R样式分R按章生成离U包{等?/p> 4Q?/em>生成BookInfo和BookDataq落?/span>QEPUB文gl过解析后,BookInfo和BookData?x)存储到自徏的StoreSvr服务上,StoreSvr针对书籍存储、下载等场景q行了很多优化,具备高可用、低时g的特点,提供了书c信息获取、按章下载等核心接口?/p> 回到最初的目标Q我们希望把更多的书c管理能力开攑և来,对上层屏蔽电(sh)子书底层的后台逻辑Q让q营同学可以更专注于书籍的管理?/p> 因此Q我们构Z如下书籍数据中台Q?/strong> 后台服务拆分开StoreAPI和StoreSvrQ?/strong> 1Q?/em>StoreAPIQ提供书c管理的接口Q由q营同学搭徏的内容^CStoreAPI交互Q完成书c的理工作Q?/p> 2Q?/em>StoreSvrQ一斚w接受StoreAPI的请求,更新书籍数据Q另一斚w为现|用h供高可用的服务?/p> StoreAPI提供了如下接口能力:(x) 此外Q?/strong>如上所qͼ划线位置和阅读进度等核心UGC数据׃是按文g偏移记录Q当书籍文g替换后,q些数据?x)发生错位,如果不能及(qing)时修复Q将对用户体验造成巨大影响。尤其在一些热门书c里Q单本书里与位置相关的UGC数据往往能达CU别Q由于文件替换后位置的偏Ud有随机性,q不能采用简单的映射方式解决Q在q去Q我们开发了专门的修复服务来完成q个事情Q针Ҏ(gu)一个UGC内容Q采用全文模p查扄方式重新计算新的偏移Qƈ更新的UGC正排、书c倒排{多个存储中?/p> 但随着用户数据来多Q书c替换频率越来越频繁Q修复不?qing)时或者失败的问题逐渐暴露出来Q?/strong> 针对上面的问题:(x)我们重新设计了修复服务,目标是最大限度羃短修复时_(d)q且让整个过E是可靠的?/p> 为此Q我们先首手考虑业务程Q我们发现在书籍上架前,q营同学本来需要依赖UGC的修复情况做前置判断是否覆盖上架Q这个过E中虽然是对UGC抽样评估Q如果能对这个修复映结果进行缓存,在正式替换文件后Q也能一定程度提升修复速度?/p> 在核心修复流E中Q我们进行了较大的重构,把单本书的修复Q务拆解成多个子Q务,存储在Chubby上,多机器抢锁共同消费这些Q务,׃d有落盘,在服务上UK启过E中Q也能马上恢复。修复过E涉?qing)大量的KV写入Qƈ发太高时Ҏ(gu)命中单key的限频或者版本冲H,我们为此开发了针对K-Str和K-Table的写入中间gQ可以在内存中聚合一批请求进行批量合q写入,~解KV层面的失败?/p> 目前Q微信读书已通过内容q_完成了多家版权方自签Qƈ在探索自出品{内容创作新形式?/p> 账号是微信读书后台系l的基石Q?/strong>承担了登录、会(x)话密钥生成与z֏、用戯料管理等核心功能Q所有的用户h都需l过账号pȝq行鉴权验证用户w䆾Q但凡有一点系l抖动都?x)媄响到整个App的正怋用,严重者还?x)导致̎可t出无法再次d?/p> 账号pȝ的架构在微信M诞生之初便一直沿用,同一个号D늚账号服务AccountSvr和MySQL部v在同一台机器上Q备机采用主从同步的方式获取数据Q当L不可用时Q备机承担了所有读h?/strong> 在某些场景下Qؓ(f)了能使访问备机时也具备一定的写入能力Q曾l魔改过d逻辑Q但一切都昑־L不治本,且引入了更复杂的pȝҎ(gu),整个架构略显混ؕ。在机器裁撤、数据扩容过E中Q曾造成q几ơ严重故障,DApp不可用,严重影响用户体验。究其原因,是因为当时基设施q不完善Q缺高性能高可靠的Z致存储,MySQL也是手动搭徏的,q维成本和风险都非常高?/p> Zd解决q个历史包袱Q我们在2024下定军_对其q行重构?/strong>重构意味着要抛弃现有MySQLq套臃肿的存储方案,把数据迁Ud新的存储lg上?/p> q里涉及(qing)到的挑战点如下:(x) 背水一战,没有退路可a。在l历了多ơ论证后Q我们决定采用Paxosmemkv作ؓ(f)新的存储lgQ全内存、多副本、强一致的Ҏ(gu),很适合作ؓ(f)账号pȝ的底层存储?/p> 同时Q我们ؓ(f)整个q移q程制定了周密的Ҏ(gu)Q把每一步进行了分解Q且要求每个环节可灰度可回退Q同时要做好数据的一致性检查?/p> 在完成数据迁UdQ我们还需要对AccountSvrq行重构Q抛弃按h的̎号分配、\由、缓存逻辑Q以全新的视角设计更z的架构?/p> 以往微信M的搜索仅限于Z书名、作者等l度的文本召回,通过自徏的全内存索引服务实现书籍的检索?strong>全文(g)索则ZES搭徏Q采用规则分D늚方式建立索引Q能满M大部分场景的需要?/strong> 在大语言模型q速发展的q两q_(d)微信M作ؓ(f)一个庞大的内容知识库,h大量的书c原文资源。同Ӟ用户在微信读书也留下了大量的文字内容Q如书评、想法等Q这些内Ҏ(gu)成了AI问书的内容基矻I也是AI问书区别于其它问{工L(fng)核心优势?/p> Z微信M构徏RAG召回pȝQ核心挑战如下:(x) 1Q?/em>Z书籍原文构徏全文(g)索,Z辑ֈ最好的效果Q往往需要支持按语义q行D落切分Q在此基上构建embeddingq行语义召回。微信读书拥有百万书籍原文数据Q此外,对于用户导入书,更是辑ֈ亿别规模。现有架构无Z成本q是耗时上都无法解决?/p> 2Q?/em>Z支持更多l度的召回,需要对UGC内容q行召回Q部分UGC内容属于U密信息Qƈ不向全网公开Q只需要满用户个人检索即可。此时如果用常规的检索系l构建常ȝ引,讉K率太低,成本难以收敛?/p> 为此Q我们针对微信读书不同的RAG使用场景Q设计了如下召回架构Q?/strong> 我们把数据划分成两类Q?/strong>全局公开可搜以及(qing)用户个h可搜?/p> 1Q?/em>对于全局公开可搜索的数据Q?/span>如库内电(sh)子书的全文、书c大UӀ书评、h工知识库{,我们构徏了一套入库流E,能对源信息进行语义分Dc(din)生成正排倒排Q语义分D基于开源的chunk模型q行微调Q正排基于fkvQ倒排则基于ES构徏QES提供了DiskANNҎ(gu)Q通过讄合理的缓存和分片Q能在存储成本和召回效率之间取得不错的^衡。对?App 内主搜等低时延场景,Z满多种定制化检索需求,我们自徏了基于内存烦引的Searchsvr服务Q支持烦引落盘,可以在毫Uq回?sh)子书搜索结果?/p> 2Q?/em>对于用户个h数据Q?/span>如导入书全文、个人想法等Q特Ҏ(gu)数据量大但用频率不高,不需要针对全|用戯行检索,如果采用上述Ҏ(gu)Q会(x)带来成本NQ性h(hun)比极低。ؓ(f)此,我们按用户及(qing)物料的维度,ZUSearch、Xapian{方案构Z向量?qing)文本烦引,q些lg的优势在于可以把单个索引存储成文件的形式Q便于落盘,配合一些量化的Ҏ(gu)Q可以把大大压羃索引大小。在构徏索引阶段Q按用户+cd构徏Z同的索引Qƈ存储在低成本的COS上,当用户需要检索召回时Q采用读时加载的方式实时q行召回Q结合CFSq行预热可以大大提升(g)索速度。当(g)索完成后Q定时淘汰策略会(x)把长期不用的索引从CFS中清理,降低存储成本?/p> 虽然微信M已经发展了十个年_(d)但我们的脚步从未停止?/p> 在日怸务开发之余,我们也从未停止思考如何让pȝ能走得更q、更E_Q抓住每一个可能的优化点,随时做好准备Q迎接下一个精彩的十年?/p> [1] 腾讯资深架构师干货ȝQ一文读懂大型分布式pȝ设计的方斚w?/a> [2] 快速理解高性能HTTP服务端的负蝲均衡技术原?/a> [3] 子弹短信光鲜的背后:(x)|易云信首席架构师分享亿UIMq_的技术实?/a> [4] 知乎技术分享:(x)从单机到2000万QPSq发的Redis高性能~存实践之\ [5] 新手入门Q零基础理解大型分布式架构的演进历史、技术原理、最?jng)_?/a> [6] 阉K技术分享:(x)深度揭秘阉K数据库技术方案的10q变q史 [7] 阉K技术分享:(x)阉K自研金融U数据库OceanBase的艰辛成长之?/a> [8] 达达O2O后台架构演进实践Q从0?000高ƈ发请求背后的努力 [9] 优秀后端架构师必?x)知识?x)史上最全MySQL大表优化Ҏ(gu)ȝ [10] 米技术分享:(x)解密米抢购pȝ千万高ƈ发架构的演进和实?/a> [11] 一读懂分布式架构下的负蝲均衡技术:(x)分类、原理、算法、常见方案等 [12] 通俗易懂Q如何设计能支撑百万q发的数据库架构Q?/a> [13] 多维度对?ƾ主分布式MQ消息队列Q妈妈再也不担心我的技术选型?/a> [14] 从新手到架构师,一就够:(x)?00?000万高q发的架构演q之?/a> [16] 12306抢票带来的启C:(x)看我如何用Go实现百万QPS的秒杀pȝ(含源? 微信团队原创分nQAndroid版微信的臃肿之困与模块化实践之\ 微信异步化改造实践:(x)8亿月zR单机千万连接背后的后台解决Ҏ(gu) C交软gU包技术解?十三)Q微信团队首ơ揭U微信红包算法,Z你抢到的?.01?/a> 微信团队分nQ极致优化,iOS版微信编译速度3倍提升的实践ȝ IM“扫一?#8221;功能很好做?看看微信“扫一扫识?#8221;的完整技术实?/a> 微信团队分nQ微信支付代码重构带来的Ud端Y件架构上的思?/a> IM开发宝典:(x)史上最全,微信各种功能参数和逻辑规则资料汇?/a> 微信团队分nQ微信直播聊天室单房?500万在U的消息架构演进之\ 企业微信的IM架构设计揭秘Q消息模型、万人群、已d执、消息撤回等 IM全文(g)索技术专??Q微信iOS端的最新全文检索技术优化实?/a> 微信Windows端IM消息数据库的优化实践Q查询慢、体U大、文件损坏等 微信技术分享:(x)揭秘微信后台安全特征数据仓库的架构设?/a> 揭秘企业微信是如何支持超大规模IMl织架构?#8212;—技术解dl关p链 微信团队分nQ详解iOS版微信视频号直播中因帧率异常D的功耗问?/a> 微信团队分nQ微信后端v量数据查询从1000ms降到100ms的技术实?/a> IM技术干货:(x)假如你来设计微信的群聊,你该怎么设计Q?/a> 微信团队分nQ来看看微信十年前的IM消息收发架构Q你做到了吗 微信后团队分享:(x)微信后台ZRay的分布式AI计算技术实?/a> 一q撸完百万行代码Q企业微信的全新鸿蒙NEXT客户端架构演q之?/a> Q本文已同步发布于:(x)http://www.52im.net/thread-4839-1-1.htmlQ?/a>4、书c数据中台的演进
4.1 技术背?/h3>
4.2 数据中台
5、̎L(fng)l的高可用性重?/h1>
6、内容召回系l的架构设计
7、写在最?/h1>
8、相兌?/h1>
9、微信团队的其它_֍文章
本文p讯技术团队罗国佳分nQ原?#8220;微信M后台架构演进之\”Q下文有修订和重新排版?/p>
今年是微信读书上U?0周年Q后台技术架构也伴随着微信M的成长经历了多次q代与升U。每一ơ的lg升与架构突_(d)在一个运行了10q的pȝ上落地都不是一件容易的事情Q需要破釜沉舟的军_与胆大心l的业务联动?/p>
微信Ml过了多q的发展Q赢得了良好的用户口,后台pȝ的服务质量直接媄响着用户的体验?/strong>团队多年来始l保持着“而美”的基因,快速试错与q代成ؓ(f)常态?strong>后台团队在日怸务开发的同时Q需要主动寻求更多架构上的突_(d)提升后台服务的可用性、扩展性,以不断适应业务与团队的变化?/strong>
技术交:(x)
- Ud端IM开发入门文章:(x)?a rel="noopener nofollow" target="_blank" style="color: #1d58d1; text-decoration-line: none;">新手入门一就够:(x)从零开发移动端IM?/p>
- 开源IM框架源码Q?a rel="noopener nofollow" target="_blank" style="color: #1d58d1; text-decoration-line: none;">https://github.com/JackJiang2011/MobileIMSDKQ?a rel="noopener nofollow" target="_blank" style="color: #1d58d1; text-decoration-line: none;">备用地址Ҏ(gu)Q?/p>
微信M是独立于微信的AppQ且׃历史原因Q开发及(qing)q维环境均存在一定的差异与隔R因此,微信M的后台服务实C从接入层到存储层的一整套完整架构?/p>
架构上分解ؓ(f)典型的接入层、逻辑层和存储层:(x)
1Q?/em>接入层:(x)按业务划分ؓ(f)多个CGI服务Q实C资源隔离。在CGI层面q实C如\由、频控、接入层~存、长q接{?/p>
2Q?/em>逻辑层:(x)采用WRMesh框架构徏了多个微服务Q这些微服务按业务场景进行划分,实现了不同模块间的解耦。框架也提供了如RPC、\由发现、过载保护、限频控、监控上报等能力?/p>
3Q?/em>存储层:(x)主要采用PaxosStore存储用户数据Q分为K-V和K-Table两种cdQ具备高可用、强一致的Ҏ(gu),针对String和Table两种cd定制了缓存中间gQ以适配某些业务场景下对讉K存储的性能要求。BookStore提供书籍的存储服务,满M场景下对书籍的拆章、修攏V下载等需要。此外,也不同程度地使用了腾讯云的PaaS存储服务Q以灉|满更多场景需要?/p>
具体的业务逻辑不再赘述Q下面简单介l下微信Mq几q在后台架构上的一些演q?/p>
微信M后台微服务源于Hikit框架Q采用C++开发。该框架诞生于广研、QQ邮箱q代Q在性能、容灾、运l、监控层面都l受了线上的考验Q在微信M上线初期作ؓ(f)主要框架Q支撑了后台服务长达数年?/p>
随着微信M的发展,来多异构的系l发展v来。例如推荐算法系l是独立部v在TKE上的容器服务Q采用GO语言开发,好处是历史负担少Q运l更加方ѝ开发更加便捗?/p>
两套pȝ同时存在带来的问题是如何做好服务ȝQ推荐系l需要频J调用后台基模块获取用户数据Q必要有一套完善的路由理、容灾机Ӟ且考虑到是异构服务Q开发语a也不相同Q如果ؓ(f)每种语言都定制开发一套服务治理框Ӟ代h(hun)?x)非帔R?/p>
在这个阶D,我们开发了WRMesh框架Q采用Sidecar+Business的方式解册个问题?/p>
Sidecar专注于处理网l层的逻辑Q和Business业务层分开Z个进E,由WRMesh脚手架生成代码,上层业务无需感知?/p>
Sidecar集成了Hikit框架中用于服务治理的核心逻辑Q?/strong>通过UnixSocket与Businessq行通信Q代理Business的所有网l读写。当Businessq程中需要发L(fng)l请求时Q由WRMesh生成的Client代码?x)自动识别当前是否在mesh环境中,q{发请求给SidecarQ由Sidecar完成接下来的|络处理?/p> 因此Q?/strong>Businessq程可以׃Q意语aL框架开发,只要遵@Sidecar的通信协议Q只需要薄薄的一层网l协议{换即可接入到Hikit的服务治理框架中?/p> 另外Q?/strong>对于某些有特D\由逻辑的ClientQ如KV讉K、Batchh{,代理转发q不能满求,因此Sidecarq提供了插g能力集成q些Client逻辑Q最大限度ؓ(f)异构Business业务提供原生C++的能力?/p> 随着WXG容器q_P6N的徏设越来越完善Q许多微信的能力也是ZP6N提供Q我们也在思考如何逐步q移到P6N。由于微信读书后台运l目前依赖于企微团队Q有独立于P6N的一套运l体p,我们负责业务和架构开发?/p> 如果要一刀切把所有后台服务迁U至P6NQ将?x)面临几个问题?x) 1Q?/em>框架代码需要重新适配Q开发环境和现网环境都有巨大的改造成本?/p> 2Q?/em>q移不是一y而就Q后C百个服务在迁U过E中Q会(x)存在新旧服务互调的问题,׃q维环境不互通,微服务之间无法完成服务治理,q种互相调用最l只能通过Proxy来{发,不仅增加了网l的p|率,时g增加Q最关键的是q个q程?x)让容灾体系大打折扣?/p> 3Q?/em>存储模块的迁UL本和风险巨大Q如果不q移存储模块只迁UM逻辑模块Q那势必又会(x)存在2中的问题Q这个过E很难收?/p> 考虑Ch力成本及(qing)投入性h(hun)比,我们最l采用了折衷的方案:(x) 1Q?/em>一斚wQ我们保留了依赖于企微的q维环境Q保障绝大多数现成服务的E_q行?/p> 2Q?/em>另一面:(x)对于微信P6N中的服务Q我们搭Z比较完善的Proxy层,例如Svrkit代理、WQueue代理{,两套架构可以方便q行互通,最大限度的在原有基上接入微信的新能力?/p> 目前Q微信读书已利接入如WQueue、FKVOL、SimOL、TFCC{众多微信的能力?/p> 书籍是微信读书的内容根基Q书c数量的多少、书c质量的好坏Q很大程度上军_了用h否选择微信M作ؓ(f)阅读App?/p> q去Q?/strong>我们依托阅文集团提供?sh)子书资源,免去了书c上架前J琐的处理流E,包括排版、审校、元信息理、更新管理等Q后台服务只需要对接阅文API卛_方便获取书籍数据Q我们只需要关注书c在q_的存储管理和分发{卛_?/p> q几q_(d)(x)?sh)子书行业的大环境发生变化,一斚wQ用户对书籍品类多样性、内容质量有更高的诉求,另一斚wQ^台对成本、版权等行业因素也更为敏感。因此,我们也在U极探烦自签版权Q甚x自出品的模式Q尝试走更多不一L(fng)道\。从后台角度而言Q从q去单一依赖阅文集团API的模式,慢慢转ؓ(f)开放更多的书籍理接口QŞ成书c数据中台模式,Z层运营同学搭建内容管理^収ͼ让更多h可以方便参与到电(sh)子书的制作、排版、上下架、运营管理当中?/p> 以EPUBZQ从内容产出C架到微信MQ大致经历以下阶D:(x) 1Q?/em>排版审校Q这个阶D多Zh工或者部分机器自动化介入?/p> 2Q?/em>上架预处?/span>Q这个阶D需要创Zc信息,配置各种q营{略Q当q本书是重排版上架时Q内容发生改变,׃现网已经存在用户的划U笔记、进度等数据Q需要有完善指标评估是否适合覆盖上架Q当上架Ӟ需要对用户数据q行修复Q避免发生错位情况,严重影响用户体验?/p> 3Q?/em>EPUB解析Q当书籍上架后,׃EPUB是单一文gQ不适合解析和管理分发,因此后台?x)把源文件解析成自有格式Q包括EPUB拆章、图文分R样式分R按章生成离U包{等?/p> 4Q?/em>生成BookInfo和BookDataq落?/span>QEPUB文gl过解析后,BookInfo和BookData?x)存储到自徏的StoreSvr服务上,StoreSvr针对书籍存储、下载等场景q行了很多优化,具备高可用、低时g的特点,提供了书c信息获取、按章下载等核心接口?/p> 回到最初的目标Q我们希望把更多的书c管理能力开攑և来,对上层屏蔽电(sh)子书底层的后台逻辑Q让q营同学可以更专注于书籍的管理?/p> 因此Q我们构Z如下书籍数据中台Q?/strong> 后台服务拆分开StoreAPI和StoreSvrQ?/strong> 1Q?/em>StoreAPIQ提供书c管理的接口Q由q营同学搭徏的内容^CStoreAPI交互Q完成书c的理工作Q?/p> 2Q?/em>StoreSvrQ一斚w接受StoreAPI的请求,更新书籍数据Q另一斚w为现|用h供高可用的服务?/p> StoreAPI提供了如下接口能力:(x) 此外Q?/strong>如上所qͼ划线位置和阅读进度等核心UGC数据׃是按文g偏移记录Q当书籍文g替换后,q些数据?x)发生错位,如果不能及(qing)时修复Q将对用户体验造成巨大影响。尤其在一些热门书c里Q单本书里与位置相关的UGC数据往往能达CU别Q由于文件替换后位置的偏Ud有随机性,q不能采用简单的映射方式解决Q在q去Q我们开发了专门的修复服务来完成q个事情Q针Ҏ(gu)一个UGC内容Q采用全文模p查扄方式重新计算新的偏移Qƈ更新的UGC正排、书c倒排{多个存储中?/p> 但随着用户数据来多Q书c替换频率越来越频繁Q修复不?qing)时或者失败的问题逐渐暴露出来Q?/strong> 针对上面的问题:(x)我们重新设计了修复服务,目标是最大限度羃短修复时_(d)q且让整个过E是可靠的?/p> 为此Q我们先首手考虑业务程Q我们发现在书籍上架前,q营同学本来需要依赖UGC的修复情况做前置判断是否覆盖上架Q这个过E中虽然是对UGC抽样评估Q如果能对这个修复映结果进行缓存,在正式替换文件后Q也能一定程度提升修复速度?/p> 在核心修复流E中Q我们进行了较大的重构,把单本书的修复Q务拆解成多个子Q务,存储在Chubby上,多机器抢锁共同消费这些Q务,׃d有落盘,在服务上UK启过E中Q也能马上恢复。修复过E涉?qing)大量的KV写入Qƈ发太高时Ҏ(gu)命中单key的限频或者版本冲H,我们为此开发了针对K-Str和K-Table的写入中间gQ可以在内存中聚合一批请求进行批量合q写入,~解KV层面的失败?/p> 目前Q微信读书已通过内容q_完成了多家版权方自签Qƈ在探索自出品{内容创作新形式?/p> 账号是微信读书后台系l的基石Q?/strong>承担了登录、会(x)话密钥生成与z֏、用戯料管理等核心功能Q所有的用户h都需l过账号pȝq行鉴权验证用户w䆾Q但凡有一点系l抖动都?x)媄响到整个App的正怋用,严重者还?x)导致̎可t出无法再次d?/p> 账号pȝ的架构在微信M诞生之初便一直沿用,同一个号D늚账号服务AccountSvr和MySQL部v在同一台机器上Q备机采用主从同步的方式获取数据Q当L不可用时Q备机承担了所有读h?/strong> 在某些场景下Qؓ(f)了能使访问备机时也具备一定的写入能力Q曾l魔改过d逻辑Q但一切都昑־L不治本,且引入了更复杂的pȝҎ(gu),整个架构略显混ؕ。在机器裁撤、数据扩容过E中Q曾造成q几ơ严重故障,DApp不可用,严重影响用户体验。究其原因,是因为当时基设施q不完善Q缺高性能高可靠的Z致存储,MySQL也是手动搭徏的,q维成本和风险都非常高?/p> Zd解决q个历史包袱Q我们在2024下定军_对其q行重构?/strong>重构意味着要抛弃现有MySQLq套臃肿的存储方案,把数据迁Ud新的存储lg上?/p> q里涉及(qing)到的挑战点如下:(x) 背水一战,没有退路可a。在l历了多ơ论证后Q我们决定采用Paxosmemkv作ؓ(f)新的存储lgQ全内存、多副本、强一致的Ҏ(gu),很适合作ؓ(f)账号pȝ的底层存储?/p> 同时Q我们ؓ(f)整个q移q程制定了周密的Ҏ(gu)Q把每一步进行了分解Q且要求每个环节可灰度可回退Q同时要做好数据的一致性检查?/p> 在完成数据迁UdQ我们还需要对AccountSvrq行重构Q抛弃按h的̎号分配、\由、缓存逻辑Q以全新的视角设计更z的架构?/p> 以往微信M的搜索仅限于Z书名、作者等l度的文本召回,通过自徏的全内存索引服务实现书籍的检索?strong>全文(g)索则ZES搭徏Q采用规则分D늚方式建立索引Q能满M大部分场景的需要?/strong> 在大语言模型q速发展的q两q_(d)微信M作ؓ(f)一个庞大的内容知识库,h大量的书c原文资源。同Ӟ用户在微信读书也留下了大量的文字内容Q如书评、想法等Q这些内Ҏ(gu)成了AI问书的内容基矻I也是AI问书区别于其它问{工L(fng)核心优势?/p> Z微信M构徏RAG召回pȝQ核心挑战如下:(x) 1Q?/em>Z书籍原文构徏全文(g)索,Z辑ֈ最好的效果Q往往需要支持按语义q行D落切分Q在此基上构建embeddingq行语义召回。微信读书拥有百万书籍原文数据Q此外,对于用户导入书,更是辑ֈ亿别规模。现有架构无Z成本q是耗时上都无法解决?/p> 2Q?/em>Z支持更多l度的召回,需要对UGC内容q行召回Q部分UGC内容属于U密信息Qƈ不向全网公开Q只需要满用户个人检索即可。此时如果用常规的检索系l构建常ȝ引,讉K率太低,成本难以收敛?/p> 为此Q我们针对微信读书不同的RAG使用场景Q设计了如下召回架构Q?/strong> 我们把数据划分成两类Q?/strong>全局公开可搜以及(qing)用户个h可搜?/p> 1Q?/em>对于全局公开可搜索的数据Q?/span>如库内电(sh)子书的全文、书c大UӀ书评、h工知识库{,我们构徏了一套入库流E,能对源信息进行语义分Dc(din)生成正排倒排Q语义分D基于开源的chunk模型q行微调Q正排基于fkvQ倒排则基于ES构徏QES提供了DiskANNҎ(gu)Q通过讄合理的缓存和分片Q能在存储成本和召回效率之间取得不错的^衡。对?App 内主搜等低时延场景,Z满多种定制化检索需求,我们自徏了基于内存烦引的Searchsvr服务Q支持烦引落盘,可以在毫Uq回?sh)子书搜索结果?/p> 2Q?/em>对于用户个h数据Q?/span>如导入书全文、个人想法等Q特Ҏ(gu)数据量大但用频率不高,不需要针对全|用戯行检索,如果采用上述Ҏ(gu)Q会(x)带来成本NQ性h(hun)比极低。ؓ(f)此,我们按用户及(qing)物料的维度,ZUSearch、Xapian{方案构Z向量?qing)文本烦引,q些lg的优势在于可以把单个索引存储成文件的形式Q便于落盘,配合一些量化的Ҏ(gu)Q可以把大大压羃索引大小。在构徏索引阶段Q按用户+cd构徏Z同的索引Qƈ存储在低成本的COS上,当用户需要检索召回时Q采用读时加载的方式实时q行召回Q结合CFSq行预热可以大大提升(g)索速度。当(g)索完成后Q定时淘汰策略会(x)把长期不用的索引从CFS中清理,降低存储成本?/p> 虽然微信M已经发展了十个年_(d)但我们的脚步从未停止?/p> 在日怸务开发之余,我们也从未停止思考如何让pȝ能走得更q、更E_Q抓住每一个可能的优化点,随时做好准备Q迎接下一个精彩的十年?/p> [1] 腾讯资深架构师干货ȝQ一文读懂大型分布式pȝ设计的方斚w?/a> [2] 快速理解高性能HTTP服务端的负蝲均衡技术原?/a> [3] 子弹短信光鲜的背后:(x)|易云信首席架构师分享亿UIMq_的技术实?/a> [4] 知乎技术分享:(x)从单机到2000万QPSq发的Redis高性能~存实践之\ [5] 新手入门Q零基础理解大型分布式架构的演进历史、技术原理、最?jng)_?/a> [6] 阉K技术分享:(x)深度揭秘阉K数据库技术方案的10q变q史 [7] 阉K技术分享:(x)阉K自研金融U数据库OceanBase的艰辛成长之?/a> [8] 达达O2O后台架构演进实践Q从0?000高ƈ发请求背后的努力 [9] 优秀后端架构师必?x)知识?x)史上最全MySQL大表优化Ҏ(gu)ȝ [10] 米技术分享:(x)解密米抢购pȝ千万高ƈ发架构的演进和实?/a> [11] 一读懂分布式架构下的负蝲均衡技术:(x)分类、原理、算法、常见方案等 [12] 通俗易懂Q如何设计能支撑百万q发的数据库架构Q?/a> [13] 多维度对?ƾ主分布式MQ消息队列Q妈妈再也不担心我的技术选型?/a> [14] 从新手到架构师,一就够:(x)?00?000万高q发的架构演q之?/a> [16] 12306抢票带来的启C:(x)看我如何用Go实现百万QPS的秒杀pȝ(含源? 微信团队原创分nQAndroid版微信的臃肿之困与模块化实践之\ 微信异步化改造实践:(x)8亿月zR单机千万连接背后的后台解决Ҏ(gu) C交软gU包技术解?十三)Q微信团队首ơ揭U微信红包算法,Z你抢到的?.01?/a> 微信团队分nQ极致优化,iOS版微信编译速度3倍提升的实践ȝ IM“扫一?#8221;功能很好做?看看微信“扫一扫识?#8221;的完整技术实?/a> 微信团队分nQ微信支付代码重构带来的Ud端Y件架构上的思?/a> IM开发宝典:(x)史上最全,微信各种功能参数和逻辑规则资料汇?/a> 微信团队分nQ微信直播聊天室单房?500万在U的消息架构演进之\ 企业微信的IM架构设计揭秘Q消息模型、万人群、已d执、消息撤回等 IM全文(g)索技术专??Q微信iOS端的最新全文检索技术优化实?/a> 微信Windows端IM消息数据库的优化实践Q查询慢、体U大、文件损坏等 微信技术分享:(x)揭秘微信后台安全特征数据仓库的架构设?/a> 揭秘企业微信是如何支持超大规模IMl织架构?#8212;—技术解dl关p链 微信团队分nQ详解iOS版微信视频号直播中因帧率异常D的功耗问?/a> 微信团队分nQ微信后端v量数据查询从1000ms降到100ms的技术实?/a> IM技术干货:(x)假如你来设计微信的群聊,你该怎么设计Q?/a> 微信团队分nQ来看看微信十年前的IM消息收发架构Q你做到了吗 微信后团队分享:(x)微信后台ZRay的分布式AI计算技术实?/a> 一q撸完百万行代码Q企业微信的全新鸿蒙NEXT客户端架构演q之?/a> Q本文已同步发布于:(x)http://www.52im.net/thread-4839-1-1.htmlQ?/a>4、书c数据中台的演进
4.1 技术背?/h3>
4.2 数据中台
5、̎L(fng)l的高可用性重?/h1>
6、内容召回系l的架构设计
7、写在最?/h1>
8、相兌?/h1>
9、微信团队的其它_֍文章
RainbowChat-Web是一套基?a target="_blank" rel="noopener nofollow" style="color: #1d58d1; text-decoration-line: none;">MobileIMSDK-Web的网늫IMpȝ。不同于市面上某些开源练手或淘宝售卖的demoU代码,RainbowChat-Web的品代码演化自真正运营过的商业?/span>Q其所依赖的通信层核心SDK已在数年内经q大量客户及(qing)其辐的最l用L(fng)使用和验证。RainbowChat-Web同时也是Ud端IM应用RainbowChat的姊妹品?/p> ?源自真正q营的商业品:(x)RainbowChat-Web的技术源于真实运营的商业产品?br /> ?q行截图Q详见:(x)?a target="_blank" rel="noopener nofollow" style="color: #1d58d1; text-decoration-line: none;">RainbowChat-Web前端功能截图?br />?演示视频Q详见:(x)?a target="_blank" rel="noopener nofollow" style="color: #1d58d1; text-decoration-line: none;">RainbowChat-Webq行演示视频?/p> 1?/em>支持文本消息、查?span style="color: #a0522d;">语音留言消息 1Q?/em>轻量易用:(x)U原生JS~写Q坚?span style="color: #ff8c00;">不依赖Q何前端框?/span>Q?span style="color: #808080;">q些框架通常是指AngularJS、VUE、EmberJS、React{?/span>Q; 2Q?/em>模块化设计:(x)所有UI模块、数据逻辑均由独立装的JS对象理Q代码规范、低耦合Q有效防止代码复杂性扩散; 3Q?/em>览器跨域:(x)所有AJAX接口均ؓ(f)JSONP实现Q百分百支持跨域Q?/p> 4Q?/em>通信代码解偶Q得益于高内聚的MobileIMSDK-Web工程Q实CIM功能逻辑与网l通信的解?/span>Q利于持l升U、重用和l护Q?span style="color: #808080;">q是l验不的IM产品做不到的Q; 5Q?/em>支持WebSocketQƈ非某些品中q在使用的过?#8220;长轮?#8221;技术,真正?#8220;x通讯”Q?/p> 6Q?/em>|络兼容性好Q核心层ZMobileIMSDK-Web技术,?span style="color: #ff8c00;">不支持WebSocket的情况下仍可很好地工2、品质说?/h1>
?它不是个DemoQ?/strong>不同于市面上某些开源或淘宝售卖的demoU代码,RainbowChat-Web的品代码演化自真正运营过的商业品,其所依赖的通信层核心SDKQ即MobileIMSDK-WebQ已在数q内l过大量客户?qing)其辐射的最l用L(fng)使用和验证?br />
?z、精点{优化、原生:(x)RainbowChat-WebZ可能降?ơ开发时的上手门槛、兼Ҏ(gu)、可L、可l护性的隑ֺQ?span style="color: #ff00ff;">坚持不依赖Q何前端框?/span>Q?span style="color: #808080;">q些框架通常是指AngularJS、VUE、EmberJS、React{?/span>Q,q璞归真Q只使用原生JS+HTML+CSSQ?span style="color: #808080;">再无其它复杂?/span>Q,极大降低开发者的上手隑ֺ、兼Ҏ(gu)本,辑ֈ最z、最_、最灉|的目标(z、简单、回归本质的东西Q才能拥最强的生命?/span>Q?br />
截止目前Q?/strong>RainbowChat-Web努力保证在各Lpȝ、主浏览器、不同分辨率屏幕上的体验Q?/span>包括但不限于QChrome、Safari、FireFox、Edge?60览器、世界之H浏览器{?#9660;3、运行演C?/h1>
4、功能简?/h1>
2?/em>支持一对一陌生?/a>模式Q?br />3?/em>支持一对一正式好友聊天模式Q?br />4?/em>支持多对?a target="_blank" rel="noopener nofollow" style="color: #1d58d1; text-decoration-line: none;">聊聊天模式Q?br />5?/em>完善?a target="_blank" rel="noopener nofollow" style="color: #1d58d1; text-decoration-line: none;">组信息理Q徏、退、解散、{让、邀(g)诗踢人、群公告{;
6?/em>完整?a target="_blank" rel="noopener nofollow" style="color: #1d58d1; text-decoration-line: none;">注册、登陆、密码找回等{功能闭环;
7?/em>个h中心功能Q改基本信息、改个性签名、改头像、改密码{;
8?/em>支持查看个h相册、个音介l;
9?/em>完整的离U消?指o(h)拉取机制Q?br />10?/em>完整的历史消?指o(h)存取机制Q?br />11?/em>完整的好友关pȝ理:(x)查找好友、发求、处理请求、删除好友、好友备注等Q?br />12?/em>以及(qing)其它未提?qing)的功能和特性?/p>5、技术亮?nbsp;
7Q?/em>断网恢复能力Q拥?span style="color: #ff8c00;">|络状况自动(g)?/span>?span style="color: #ff8c00;">断网自动L的能力;
8Q?/em>L支持加密Q一个参数即可开?span style="color: #ff8c00;">SSL/TLS通信加密Q?/p> 9Q?/em>服务端慢io解偶QIM实例本n坚持不直接进行DB{慢io的读、写Q保证IM实时消息高吞吐和性能Q?/p> 10Q?/em>服务端逻辑解偶Q得益于MobileIMSDK-Web工程Q实C上层逻辑与网l通信核心的解?/span>Q底层数据通信全部通过低偶合的回调通知来实玎ͼ 11Q?/em>完善的log记录Q服务端使用log4js日志框架Q确?span style="color: #ff8c00;">每一关键步骤都有日志输出Q让(zhn)的q行调试更ؓ(f)便利Q?/p> 12Q?/em>聊天协议兼容Q实C?a target="_blank" rel="noopener nofollow" style="color: #1d58d1; text-decoration-line: none;">RainbowChat-APP产品完全兼容的协议模型; 13Q?/em>消息收发互通:(x)实现了与RainbowChat-APP产品的无~消息互通?/p> 聊天Z方聊天对象信息显C:(x)Q?a target="_blank" rel="noopener nofollow" style="color: #1d58d1; text-decoration-line: none;">查看视频Q?br /> 消息送达状态图标显C:(x)Q?a target="_blank" rel="noopener nofollow" style="color: #1d58d1; text-decoration-line: none;">查看视频Q?/p>6、支持的聊天消息cd
7、好友聊?/h1>
8、群聊聊?/h1>
9、发?#8220;名?#8221;消息
10、发?#8220;位置”消息
11?#8220;消息撤回”
12?#8220;消息转发”
12?#8220;消息引用”
14?#8220;@”功能
15、其它特性和l节