﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>语源科技BlogJava-Jack Jiang</title><link>http://www.blogjava.net/jb2011/</link><description>我的最新工程MobileIMSDK：http://git.oschina.net/jackjiang/MobileIMSDK</description><language>zh-cn</language><lastBuildDate>Sun, 08 Nov 2026 08:35:32 GMT</lastBuildDate><pubDate>Sun, 08 Nov 2026 08:35:32 GMT</pubDate><ttl>60</ttl><item><title>IM全文检索技术(五)：vivo敏感词匹配系统的技术实践</title><link>http://www.blogjava.net/jb2011/archive/2026/09/23/451802.html</link><dc:creator>Jack Jiang</dc:creator><author>Jack Jiang</author><pubDate>Wed, 23 Sep 2026 09:59:00 GMT</pubDate><guid>http://www.blogjava.net/jb2011/archive/2026/09/23/451802.html</guid><wfw:comment>http://www.blogjava.net/jb2011/comments/451802.html</wfw:comment><comments>http://www.blogjava.net/jb2011/archive/2026/09/23/451802.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jb2011/comments/commentRss/451802.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jb2011/services/trackbacks/451802.html</trackback:ping><description><![CDATA[<p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">本文作者vivo互联网服务器团队Liang Kangwu，有修订。</p><h1>1、引言</h1><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><strong>编者注：</strong>本文虽不是专门的全文检索技术文章，但文中涉及到的字词匹配算法等等都是一脉相承，所以也同样收录到了&#8220;IM全文检索技术&#8221;技术专题中，希望能给你启发。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">谛听系统是vivo的内容审核平台，保障了vivo各互联网产品持续健康的发展。谛听支持审核多种内容类型，但日常主要审核的内容是文本，下图是一个完整的文本审核流程，包括名单匹配、敏感词匹配、AI机器审核、人工审核四个环节。待审核文本需要顺次通过名单匹配、敏感词匹配、AI机器审核三个流程，若结果为嫌疑则需要人工审核，否则将直接给出确定的结果。</p><div img-uploading-status=""  image-package-1"="" data-index="1" style="font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><img alt="1" loading="lazy" data-src="https://img2024.cnblogs.com/blog/1834368/202609/1834368-20260921231239685-601998116.png" src="https://img2024.cnblogs.com/blog/1834368/202609/1834368-20260921231239685-601998116.png" lazyloaded=""  medium-zoom-image"="" style="border: 0px; max-width: 100%; height: auto !important; cursor: zoom-in; transition: transform 300ms cubic-bezier(0.2, 0, 0.2, 1) !important;" /></div><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">敏感词匹配功能可以迅速地匹配文本中的敏感词汇，算法平均耗时为50ms，因其简单、快速、直接、灵活的特点，成为了审核人员对抗垃圾文本的利器。然而身处信息爆炸时代的网民们非常&#8220;优秀&#8221;，他们源源不断的发明各种新词、谐音词来绕过敏感词检测。例如某些用户会使用&#8220;啋票&#8221;、&#8220;采漂&#8221;等词汇来规避敏感词&#8220;彩票&#8221;，其中&#8220;啋票&#8221;不仅是谐音词，还包含多音字，常规的模式匹配算法很难保证完全命中。这不仅给运营规则带来挑战，也对匹配算法的精准度、漏杀率提出了要求。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><strong>本文将从算法选型入手，结合两个实际场景来介绍谛听系统的敏感词匹配算法。包括底层算法选型思路和两种实际场景下提升敏感词精准度、降低漏杀率的方案。</strong></p><div img-uploading-status=""  image-package-2"="" data-index="2" style="font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><div><div><img alt="cover_opti" loading="lazy" data-src="https://img2024.cnblogs.com/blog/1834368/202609/1834368-20260921231657299-1805023871.png" src="https://img2024.cnblogs.com/blog/1834368/202609/1834368-20260921231657299-1805023871.png" lazyloaded=""  medium-zoom-image"="" style="border: 0px; max-width: 100%; height: auto !important; cursor: zoom-in; transition: transform 300ms cubic-bezier(0.2, 0, 0.2, 1) !important;" /></div></div></div><h1>2、系列文章</h1><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><strong>本文是专题系列文章中的第<em>5 </em>篇：</strong></p><ol style="margin-left: 2.5rem; padding-left: 0px; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><li style="list-style: inherit;">《<a href="http://www.52im.net/thread-1132-1-1.html" target="_blank" rel="noopener nofollow" style="color: #1d58d1; text-decoration: none;">IM全文检索技术(一)：微信移动端的全文检索优化之路</a>》</li><li style="list-style: inherit;">《<a href="http://www.52im.net/thread-1545-1-1.html" target="_blank" rel="noopener nofollow" style="color: #1d58d1; text-decoration: none;">IM全文检索技术(二)：微信移动端的全文检索多音字问题解决方案</a>》</li><li style="list-style: inherit;">《<a href="http://www.52im.net/thread-3651-1-1.html" target="_blank" rel="noopener nofollow" style="color: #1d58d1; text-decoration: none;">IM全文检索技术(三)：网易云信Web端IM的聊天消息全文检索技术实践</a>》</li><li style="list-style: inherit;">《<a href="http://www.52im.net/thread-3839-1-1.html" target="_blank" rel="noopener nofollow" style="color: #1d58d1; text-decoration: none;">IM全文检索技术(四)：微信iOS端的最新全文检索技术优化实践</a>》</li><li style="list-style: inherit;">《<a href="http://www.52im.net/thread-4923-1-1.html" target="_blank" rel="noopener nofollow" style="color: #1d58d1; text-decoration: none;">IM全文检索技术(五)：vivo敏感词匹配系统的技术实践</a>》（<span style="color: #ff0000;"><strong>* 本文</strong></span>）</li></ol><h1>3、敏感词匹配算法选型</h1><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">敏感词匹配功能依托于模式匹配算法。模式匹配的定义是，给定一个子串，在某个字符串中找出与该子串相同的所有子串。其中给定的子串被称为模式串，被匹配的字符串被称为目标串。基于多个模式串进行匹配的算法被称为多模式匹配算法，目前成熟的多模式匹配算法有AC自动机和WM。</p><h2>3.1 多模式匹配算法对比</h2><div img-uploading-status=""  image-package-3"="" data-index="3" style="font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><div><div><img alt="2" loading="lazy" data-src="https://img2024.cnblogs.com/blog/1834368/202609/1834368-20260921231245167-1824360154.png" src="https://img2024.cnblogs.com/blog/1834368/202609/1834368-20260921231245167-1824360154.png" lazyloaded=""  medium-zoom-image"="" style="border: 0px; max-width: 100%; height: auto !important; cursor: zoom-in; transition: transform 300ms cubic-bezier(0.2, 0, 0.2, 1) !important;" /></div></div></div><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><strong>谛听的敏感词匹配业务有如下特点：</strong></p><ul style="margin-left: 2.5rem; padding-left: 0px; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><li style="list-style: inherit;"><em>1）</em>词库量大，需要维护和加载百万级别的词库（模式串）；</li><li style="list-style: inherit;"><em>2）</em>敏感词与业务特性、国家政策相关性强，无法统一约定长度、前缀等特征。</li></ul><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">WM算法对模式串的长度和前缀存在一定的要求，可能会影响业务的使用。虽然AC自动机加载耗时长，内存占用大，但敏感词加载并不频繁，且服务器内存资源充足，所以我们最终选用AC自动机作为底层算法。</p><h2>3.2 AC自动机算法介绍</h2><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">AC自动机算法（Aho&#8211;Corasick算法）是一种字符串搜索算法，可以同时将目标串与所有模式串进行匹配，算法均摊情况下具有近似于线性的时间复杂度。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">AC自动机的匹配原理有两个核心概念：Trie字典树、Fail指针。下面以模式串集合{&#8220;she&#8221;, &#8220;he&#8221;, &#8220;shers&#8221;, &#8220;his&#8221;, &#8220;era&#8221;}为例，来介绍这两个概念。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">AC自动机算法启动时，需要将所有的模式串加载到内存中，构建成一个Trie字典树。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">例如下图是以模式串集合{&#8220;she&#8221;, &#8220;he&#8221;, &#8220;shers&#8221;, &#8220;his&#8221;, &#8220;era&#8221;}构建的字典树，树中每个节点代表一个字符，从根节点到某一个节点的路径，即可表示一个模式串，且红色节点表示一个字符串的终结，例如图中最右边子树上的三个节点，可代表模式串&#8220;era&#8221;。从字典树的根节点出发，可以快速的查找到某个模式串。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">此外，拥有相同前缀的模式串会合并到同一个子树中，例如中间子树表示模式串&#8220;he&#8221;、 &#8220;his&#8221;，这两个字符串分别是&#8220;h&#8221;节点的一个分支。AC自动机在搜索这类字符串时，可以节省匹配的次数。</p><div img-uploading-status=""  image-package-4"="" data-index="4" style="font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><div><div><p style="margin: 10px auto;"><img alt="3" loading="lazy" data-src="https://img2024.cnblogs.com/blog/1834368/202609/1834368-20260921231251804-1768606576.png" src="https://img2024.cnblogs.com/blog/1834368/202609/1834368-20260921231251804-1768606576.png" lazyloaded=""  medium-zoom-image"="" style="border: 0px; max-width: 100%; height: auto !important; cursor: zoom-in; transition: transform 300ms cubic-bezier(0.2, 0, 0.2, 1) !important;" /></p></div></div></div><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">AC自动机在Trie树的基础上，为每个节点加入了Fail指针，上图使用虚线画出了部分节点的Fail指针，未画出虚线的节点，其Fail指针指向根节点。算法在某个节点匹配失败时，可以通过该指针转移到其他包含相同前缀的分支上继续匹配。例如匹配目标串&#8220;shis&#8221;时，对于前两个字符&#8220;sh&#8221;，Trie字典树匹配到左边字数的&#8220;h&#8221;节点上，由于该节点的子节点是字符&#8220;e&#8221;，与目标串的下一个字符&#8220;i&#8221;不匹配，因此算法通过Fail指针转移到中间子树的&#8220;h&#8221;节点上继续匹配，最终命中字符串&#8220;his&#8221;。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">上述的Trie字典树与Fail指针组成了AC自动机的数据模型。AC自动机匹配目标串时，会按顺序从目标串中取出字符，从Trie字典树的根节点出发，在子结点中寻找与该字符匹配的结点，若能找到，则转移到该节点，若找不到，则转移到Fail指针指向的节点。当状态转移到图中的红色节点时，就是命中了一个模式串。下图展示了AC自动机对目标串&#8220;merashisnx&#8221;进行匹配的过程。</p><div img-uploading-status=""  image-package-5"="" data-index="5" style="font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><div><div><img alt="4" loading="lazy" data-src="https://img2024.cnblogs.com/blog/1834368/202609/1834368-20260921231258751-701494437.gif" src="https://img2024.cnblogs.com/blog/1834368/202609/1834368-20260921231258751-701494437.gif" medium-zoom-image=""  lazyloaded"="" style="border: 0px; max-width: 100%; height: auto !important; cursor: zoom-in; transition: transform 300ms cubic-bezier(0.2, 0, 0.2, 1) !important;" /></div></div></div><h1>4、vivo的谛听系统</h1><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">谛听系统基于AC自动机算法构建了一套敏感词匹配服务，将敏感词作为模式串，文本内容作为目标串，可以实现常用的中、英文敏感词匹配。但是实际的业务有很多细分的场景，普通的AC自动机算法已不能满足业务使用需求，因此我们探索了组合敏感词匹配和拼音敏感词匹配两种匹配方式，下面分别介绍。</p><h1>5、技术实践1：组合敏感词</h1><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">常规的敏感词匹配算法通常匹配单个词或者短句，但某些词单独出现时并不违规，只有在与几个特定的词同时出现时，才能判定为违规。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">组合敏感词的匹配算法依然基于AC自动机算法。由于AC自动机只能判断单个词的命中情况，因此我们将组合敏感词分割成单个敏感词，并维护各敏感词与组合间的映射关系，在AC自动机算法运行结束后，只有某个组合对应的敏感词全部命中时，才能判断该组合敏感词命中。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><strong>为此我们需要给AC自动机添加一些前置和后置的处理步骤，具体步骤如下：</strong></p><ul style="margin-left: 2.5rem; padding-left: 0px; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><li style="list-style: inherit;"><em>1）</em>将组合敏感词分割为单个敏感词，并记录敏感词与组合的映射关系；</li><li style="list-style: inherit;"><em>2）</em>将分割后的组合敏感词添加到AC自动机的Tire树中；</li><li style="list-style: inherit;"><em>3）</em>运行AC自动机，匹配文本；</li><li style="list-style: inherit;"><em>4）</em>遍历匹配结果，将匹配的结果根据映射关系映射到相应的组合上；</li><li style="list-style: inherit;"><em>5）</em>记录组合的命中情况，得到最终匹配结果。</li></ul><div img-uploading-status=""  image-package-6"="" data-index="6" style="font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><img alt="5" loading="lazy" data-src="https://img2024.cnblogs.com/blog/1834368/202609/1834368-20260921231304923-250651432.png" src="https://img2024.cnblogs.com/blog/1834368/202609/1834368-20260921231304923-250651432.png" lazyloaded=""  medium-zoom-image"="" style="border: 0px; max-width: 100%; height: auto !important; cursor: zoom-in; transition: transform 300ms cubic-bezier(0.2, 0, 0.2, 1) !important;" /></div><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">在步骤4中，算法将匹配的词映射到组合中，并标记对应的词命中。步骤5会根据各组合中单词的命中情况，来判断该组合是否命中，由于在步骤4中组合敏感词均被标记为命中，因此可判断该组合命中。</p><div img-uploading-status=""  image-package-7"="" data-index="7" style="font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><div><div><img alt="6" loading="lazy" data-src="https://img2024.cnblogs.com/blog/1834368/202609/1834368-20260921231311109-2041690379.png" src="https://img2024.cnblogs.com/blog/1834368/202609/1834368-20260921231311109-2041690379.png" lazyloaded=""  medium-zoom-image"="" style="border: 0px; max-width: 100%; height: auto !important; cursor: zoom-in; transition: transform 300ms cubic-bezier(0.2, 0, 0.2, 1) !important;" /></div></div></div><h1>6、技术实践2：拼音敏感词</h1><h2>6.1 概述</h2><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">在评论、弹幕等创作自由度很高的场景中，某些用户为了规避机器审核，会使用一些多音字、同音字来表达敏感词汇，例如用&#8220;啋票&#8221;来代表&#8220;彩票&#8221;等。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">由于多音字、同音字变化较多，将一个词的所有谐音词都穷举出来是很困难的。因此我们实现了拼音敏感词的匹配方案，将中文文本转换为拼音再匹配，通过读音匹配敏感词，即可保证命中所有的同音字，运营直接配置敏感词的拼音，例如&#8220;CAI PIAO&#8221;，即可命中&#8220;啋票&#8221;、&#8220;彩票&#8221;、&#8220;采漂&#8221;等词汇。</p><h2>6.2 匹配流程</h2><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">常规的AC自动机算法是逐字符匹配的，因此Trie树上每个节点存储一个字符，但拼音敏感词需要按照音节匹配，因此我们将Trie树的节点数据类型由char改为String。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><strong>示例如下：</strong></p><div img-uploading-status=""  image-package-8"="" data-index="8" style="font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><div><div><img alt="7" loading="lazy" data-src="https://img2024.cnblogs.com/blog/1834368/202609/1834368-20260921231318880-1772043676.png" src="https://img2024.cnblogs.com/blog/1834368/202609/1834368-20260921231318880-1772043676.png" lazyloaded=""  medium-zoom-image"="" style="border: 0px; max-width: 100%; height: auto !important; cursor: zoom-in; transition: transform 300ms cubic-bezier(0.2, 0, 0.2, 1) !important;" /></div></div></div><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">拼音敏感词的匹配关键在于将汉字准确的转换为拼音，这一点在多音字的场景下尤为重要。由于多音字的读音是受语境影响的，现有的技术条件很难确保能将多音字准确的转换为拼音，而上文提到同音词&#8220;啋票&#8221;是用户自行造的词，算法无法准确的识别语境，可能转换得到&#8220;CAI PIAO&#8221;、&#8220;XIAO PIAO&#8221;两种不同的结果。如果拼音转换不精准，则拼音敏感词也无法准确命中。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">因此我们不依赖算法识别多音字的读音，而是将文本内容的所有读音都列出来匹配一遍，就可以避免避免拼音转换不精准的问题。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">下图展示了文本内容与拼音的对应关系，由于存在多音字，因此存储拼音的数组从一维扩展到了二维，更像是&#8220;图&#8221;的数据结构，下文将其称为拼音图。拼音图的起始节点和终止节点之间存在多条路径，这些路径对应了多音字的所有排列组合情况，为了避免漏杀，我们需要使用AC自动机将这些路径都匹配一遍。</p><div img-uploading-status=""  image-package-9"="" data-index="9" style="font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><div><div><p style="margin: 10px auto;"><img alt="8" loading="lazy" data-src="https://img2024.cnblogs.com/blog/1834368/202609/1834368-20260921231326181-398050315.png" src="https://img2024.cnblogs.com/blog/1834368/202609/1834368-20260921231326181-398050315.png"  medium-zoom-image"="" style="border: 0px; max-width: 100%; height: auto !important; cursor: zoom-in; transition: transform 300ms cubic-bezier(0.2, 0, 0.2, 1) !important;" /></p></div></div></div><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">从第二节的匹配流程可以看出，目标串是一维数组，因此AC自动机在匹配文本时，通常采用顺序遍历的方式。而在拼音敏感词中，由于目标串采用二维数组存储，是一种类似于&#8220;图&#8221;的数据结构，不再适合使用顺序遍历的方式，因此需要采用图的遍历算法。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">图的遍历算法中，最常用的就是深度优先遍历（DFS）和广度优先遍历（BFS）。由于词语是前后关联的，为了使算法更符合人类思考习惯，我们选择了DFS。DFS算法使用栈存储节点信息，在当前分支遍历完成后，通过栈中的信息回溯到上一个分支处继续遍历。由于Trie树的状态位与拼音图的节点是相关的，在DFS回溯时，Trie树也需要同步回溯，因此需要将Trie树状态位与拼音图的节点信息一起保存到DFS栈中。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><strong>下图展示了拼音敏感词的匹配流程：</strong></p><div img-uploading-status=""  image-package-10"="" data-index="10" style="font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><div><div><img alt="9" loading="lazy" data-src="https://img2024.cnblogs.com/blog/1834368/202609/1834368-20260921231331925-831353181.gif" src="https://img2024.cnblogs.com/blog/1834368/202609/1834368-20260921231331925-831353181.gif"  medium-zoom-image"="" style="border: 0px; max-width: 100%; height: auto !important; cursor: zoom-in; transition: transform 300ms cubic-bezier(0.2, 0, 0.2, 1) !important;" /><p style="margin: 10px auto;">&nbsp;</p></div></div></div><h2>6.3 终止条件与剪枝策略</h2><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">DFS的终止条件是当所有节点都被遍历过，且算法会确保每个节点只会被遍历一次。但是DFS遍历时会在分支处回溯，所以往往终止的节点并不是待匹配文本的终点，很有可能AC自动机的匹配并未完成。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">例如在下图所示的匹配流程中，左图是基于待匹配文本&#8220;朱朝阳和朋友&#8221;构建的拼音图，右图是基于拼音敏感词&#8220;PENG YOU&#8221;、&#8220;ZHAO YANG&#8221;、&#8220;NI MA&#8221;、&#8220;MA DE&#8221;构建的Trie树。左图的拼音图采用DFS算法遍历，算法最后访问的节点是蓝色节点&#8220;ZHAO&#8221;，此时拼音图中所有节点均被遍历了一次，已经达到了DFS的终止条件。但右图中Trie树上的状态位处于蓝色节点&#8220;ZHAO&#8221;的位置，并没有达到终止状态，若此时停止匹配，则会导致无法命中敏感词&#8220;ZHAO YANG&#8221;，故算法应继续运行，直到AC自动机匹配失败为止。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">因此合适的终止条件是：拼音图所有节点均被遍历 且 AC自动机匹配失败。</p><div img-uploading-status=""  image-package-11"="" data-index="11" style="font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><div><div><img alt="10" loading="lazy" data-src="https://img2024.cnblogs.com/blog/1834368/202609/1834368-20260921231338180-818054310.png" src="https://img2024.cnblogs.com/blog/1834368/202609/1834368-20260921231338180-818054310.png" lazyloaded=""  medium-zoom-image"="" style="border: 0px; max-width: 100%; height: auto !important; cursor: zoom-in; transition: transform 300ms cubic-bezier(0.2, 0, 0.2, 1) !important;" /><p style="margin: 10px auto;"><img alt="11" loading="lazy" data-src="https://img2024.cnblogs.com/blog/1834368/202609/1834368-20260921231343633-1653593431.png" src="https://img2024.cnblogs.com/blog/1834368/202609/1834368-20260921231343633-1653593431.png" lazyloaded=""  medium-zoom-image"="" style="border: 0px; max-width: 100%; height: auto !important; cursor: zoom-in; transition: transform 300ms cubic-bezier(0.2, 0, 0.2, 1) !important;" /></p></div></div></div><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">由于算法需要结合DFS和AC自动机的状态来判断终止条件，因此会出现拼音图中一个节点和路径被遍历多次的情况，当待匹配文本中多音字数量增多时，DFS遍历的路径数量会以笛卡尔积的形式增加。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">而这些路径中会存在一部分重复的情况，因此在遍历的过程中需要采取合适的剪枝策略，避免搜索一些重复的路径。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">例如下面左图所示的遍历情况，路径&#9313;上&#8220;PENG&#8221;、&#8220; YOU&#8221;两个节点已被路径&#9312;遍历过，且对应的AC自动机状态位（参考右图）前缀并不包含当前遍历节点&#8220;HU&#8221;，所以&#8220;PENG&#8221;对应的敏感词与路径&#9313;无关，不必再搜索一次。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><strong>我们可以针对这种场景设计了剪枝策略，需要剪枝的路径需要满足两个条件：</strong></p><ul style="margin-left: 2.5rem; padding-left: 0px; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><li style="list-style: inherit;"><em>1）</em>首先当前节点的下一节点已被遍历过；</li><li style="list-style: inherit;"><em>2）</em>下一节点对应的AC自动机状态与当前节点无关。</li></ul><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">我们为拼音图中的每个节点标记一个分支路径长度B，表示当前节点与上一个最近的分支节点间的路径长度，例如节点&#8220;PENG&#8221;对应的分支路径长度为B = 2（从&#8220;HU&#8221;到&#8220;PENG&#8221;），节点&#8220;YOU&#8221;的分支路径长度为B = 3（&#8220;HU&#8221;、&#8220;PENG&#8221;、&#8220;YOU&#8221;）。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">在AC自动机的状态机中，记录Trie树上每个节点的深度D。例如状态机中&#8220;PENG&#8221;节点的深度D=1，&#8220;YOU&#8221;节点的深度D=2。从Trie树根节点到某一个节点的路径上经过的字符连接起来，为该节点对应的模式串，因此节点的深度D即为模式串的长度。当D &lt; B时，表明当前正在匹配的模式串长度短于拼音图中当前节点的分支路径长度，所以当前的模式串与当前的路径无关。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><strong>总结一下，剪枝所需的条件为：</strong></p><ul style="margin-left: 2.5rem; padding-left: 0px; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><li style="list-style: inherit;"><em>1）</em>拼音图中下一节点已被遍历；</li><li style="list-style: inherit;"><em>2）</em>拼音图的分支路径长度B &gt; Trie树节点的深度D。</li></ul><div img-uploading-status=""  image-package-13"="" data-index="13" style="font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">&nbsp;</div><div img-uploading-status=""  image-package-14"="" data-index="14" style="font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><div><div><img alt="12" loading="lazy" data-src="https://img2024.cnblogs.com/blog/1834368/202609/1834368-20260921231348709-1587269741.png" src="https://img2024.cnblogs.com/blog/1834368/202609/1834368-20260921231348709-1587269741.png" lazyloaded=""  medium-zoom-image"="" style="border: 0px; max-width: 100%; height: auto !important; cursor: zoom-in; transition: transform 300ms cubic-bezier(0.2, 0, 0.2, 1) !important;" /><p style="margin: 10px auto;"><img alt="13" loading="lazy" data-src="https://img2024.cnblogs.com/blog/1834368/202609/1834368-20260921231410758-163559836.png" src="https://img2024.cnblogs.com/blog/1834368/202609/1834368-20260921231410758-163559836.png" lazyloaded=""  medium-zoom-image"="" style="border: 0px; max-width: 100%; height: auto !important; cursor: zoom-in; transition: transform 300ms cubic-bezier(0.2, 0, 0.2, 1) !important;" /></p></div></div></div><h1>7、写在最后</h1><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">谛听系统基于AC自动机实现了普通敏感词、组合敏感词、拼音敏感词的匹配，其中组合敏感词和拼音敏感词还可以结合成为拼音组合敏感词，覆盖了大部分的文本审核场景，减轻了机审、人审的压力。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">另外，在政策风向发生变化时，敏感词匹配功能为运营同事提供了一种快速变更审核策略的手段，使谛听的文本审核能力更加灵活。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">目前谛听线上已经配置了数量超过100万的敏感词，极大程度的保障了公司的内容安全。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><strong>未来我们将结合业务使用场景继续优化敏感词匹配的能力，提升精准度和命中率：</strong></p><ul style="margin-left: 2.5rem; padding-left: 0px; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><li style="list-style: inherit;"><em>1）</em>一方面我们可以采用某种方式实现&#8220;非&#8221;的逻辑，这样可以在配置敏感词时排除bad case，提升命中的精准度；</li><li style="list-style: inherit;"><em>2）</em>另一方面，我们可以实现敏感词的模糊命中，提升敏感词的命中率。</li></ul><h1>8、相关资料</h1><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">[1] <a href="http://www.52im.net/thread-3065-1-1.html" target="_blank" rel="noopener nofollow" style="color: #1d58d1; text-decoration: none;">零基础IM开发入门(一)：什么是IM聊天系统？</a></p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">[2] <a href="http://www.52im.net/thread-464-1-1.html" target="_blank" rel="noopener nofollow" style="color: #1d58d1; text-decoration: none;">新手入门一篇就够：从零开发移动端IM</a></p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">[3] <a href="http://www.52im.net/thread-4378-1-1.html" target="_blank" rel="noopener nofollow" style="color: #1d58d1; text-decoration: none;">IM消息ID技术专题(七)：深度解密vivo的自研分布式ID服务(鲁班)</a></p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">[4] <a href="http://www.52im.net/thread-3856-1-1.html" target="_blank" rel="noopener nofollow" style="color: #1d58d1; text-decoration: none;">阿里IM技术分享(七)：某鱼IM的在线、离线聊天数据同步机制优化实践</a></p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">[5] <a href="http://www.52im.net/thread-3780-1-1.html" target="_blank" rel="noopener nofollow" style="color: #1d58d1; text-decoration: none;">探探的IM长连接技术实践：技术选型、架构设计、性能优化</a></p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">[6] <a href="http://www.52im.net/thread-3887-1-1.html" target="_blank" rel="noopener nofollow" style="color: #1d58d1; text-decoration: none;">IM开发干货分享：浅谈IM系统中离线消息、历史消息的最佳实践</a></p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">[7] <a href="http://www.52im.net/thread-4684-1-1.html" target="_blank" rel="noopener nofollow" style="color: #1d58d1; text-decoration: none;">得物自研移动端弱网诊断工具的技术实践分享</a></p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">[8] <a href="http://www.52im.net/thread-4887-1-1.html" target="_blank" rel="noopener nofollow" style="color: #1d58d1; text-decoration: none;">如何保障分布式IM聊天系统的消息有序性（即消息不乱）</a></p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">[9] <a href="http://www.52im.net/thread-4905-1-1.html" target="_blank" rel="noopener nofollow" style="color: #1d58d1; text-decoration: none;">社交场景下的统一即时通讯im消息流交互层模块化技术实践</a></p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">[10] <a href="http://www.52im.net/thread-3994-1-1.html" target="_blank" rel="noopener nofollow" style="color: #1d58d1; text-decoration: none;">直播系统聊天技术(八)：vivo直播系统中IM消息模块的架构实践</a></p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">[11] <a href="http://www.52im.net/thread-4153-1-1.html" target="_blank" rel="noopener nofollow" style="color: #1d58d1; text-decoration: none;">得物从0到1自研客服IM系统的技术实践之路</a></p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">[12] <a href="http://www.52im.net/thread-4404-1-1.html" target="_blank" rel="noopener nofollow" style="color: #1d58d1; text-decoration: none;">海量用户IM聊天室的架构设计与实践</a></p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">[13] <a href="http://www.52im.net/thread-4564-1-1.html" target="_blank" rel="noopener nofollow" style="color: #1d58d1; text-decoration: none;">一套分布式IM即时通讯系统的技术选型和架构设计</a></p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">[14] <a href="http://www.52im.net/thread-4627-1-1.html" target="_blank" rel="noopener nofollow" style="color: #1d58d1; text-decoration: none;">陌陌技术分享：陌陌IM在后端KV缓存架构上的技术实践</a></p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">[15] <a href="http://www.52im.net/thread-4636-1-1.html" target="_blank" rel="noopener nofollow" style="color: #1d58d1; text-decoration: none;">来看看某信十年前的IM消息收发架构，你做到了吗</a></p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">[16] <a href="http://www.52im.net/thread-4690-1-1.html" target="_blank" rel="noopener nofollow" style="color: #1d58d1; text-decoration: none;">携程技术分享：亿级流量的办公IM及开放平台技术实践</a></p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">[17] <a href="http://www.52im.net/thread-4764-1-1.html" target="_blank" rel="noopener nofollow" style="color: #1d58d1; text-decoration: none;">转转平台IM系统架构设计与实践(一)：整体架构设计</a></p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">[18] <a href="http://www.52im.net/thread-4789-1-1.html" target="_blank" rel="noopener nofollow" style="color: #1d58d1; text-decoration: none;">支持百万人超大群聊的Web端IM架构设计与实践</a></p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">[19] <a href="http://www.52im.net/thread-4874-1-1.html" target="_blank" rel="noopener nofollow" style="color: #1d58d1; text-decoration: none;">转转客服IM聊天系统背后的技术挑战和实践分享</a></p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">[20] <a href="http://www.52im.net/thread-4886-1-1.html" target="_blank" rel="noopener nofollow" style="color: #1d58d1; text-decoration: none;">B站IM消息系统的新架构升级实践</a></p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">[21] <a href="http://www.52im.net/thread-4887-1-1.html" target="_blank" rel="noopener nofollow" style="color: #1d58d1; text-decoration: none;">如何保障分布式IM聊天系统的消息有序性（即消息不乱）</a></p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">[22] <a href="http://www.52im.net/thread-4920-1-1.html" target="_blank" rel="noopener nofollow" style="color: #1d58d1; text-decoration: none;">即时通讯IM离线消息该怎么存？全面盘点主流存储方案</a></p><blockquote style="background-image: none; border-width: medium medium medium 3px; border-style: none none none solid; border-color: currentcolor currentcolor currentcolor #e2dfdf; margin: 10px 0px; background-color: #eeeeee; width: 896px; color: #555555; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif;"><p style="margin: 10px auto;"><strong>即时通讯技术学习：</strong></p><p style="margin: 10px auto;">- 移动端IM开发入门文章：《<a href="http://www.52im.net/thread-464-1-1.html" rel="noopener nofollow" target="_blank" style="color: #1d58d1; text-decoration: none;">新手入门一篇就够：从零开发移动端IM</a>》</p><p style="margin: 10px auto;">- 开源IM框架源码：<a href="https://github.com/JackJiang2011/MobileIMSDK" rel="noopener nofollow" target="_blank" style="color: #1d58d1; text-decoration: none;">https://github.com/JackJiang2011/MobileIMSDK</a>（<a href="https://gitee.com/jackjiang/MobileIMSDK" rel="noopener nofollow" target="_blank" style="color: #1d58d1; text-decoration: none;">备用地址点此</a>）</p></blockquote><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">（本文同步发布于： <a href="http://www.52im.net/thread-4923-1-1.html" target="_blank" rel="noopener nofollow" style="color: #1d58d1; text-decoration: none;">http://www.52im.net/thread-4923-1-1.html</a> ）</p><img src ="http://www.blogjava.net/jb2011/aggbug/451802.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jb2011/" target="_blank">Jack Jiang</a> 2026-09-23 17:59 <a href="http://www.blogjava.net/jb2011/archive/2026/09/23/451802.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Nginx生产级WebSocket实时长连接负载均衡，一文搞定</title><link>http://www.blogjava.net/jb2011/archive/2026/09/08/451796.html</link><dc:creator>Jack Jiang</dc:creator><author>Jack Jiang</author><pubDate>Tue, 08 Sep 2026 02:59:00 GMT</pubDate><guid>http://www.blogjava.net/jb2011/archive/2026/09/08/451796.html</guid><wfw:comment>http://www.blogjava.net/jb2011/comments/451796.html</wfw:comment><comments>http://www.blogjava.net/jb2011/archive/2026/09/08/451796.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jb2011/comments/commentRss/451796.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jb2011/services/trackbacks/451796.html</trackback:ping><description><![CDATA[<p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">本文作者银河技术，有修订和改动。</p><h1>1、引言</h1><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">WebSocket 是基于 HTTP/1.1 Upgrade 机制实现的全双工长连接通信协议，广泛应用于 IM即时通讯、实时通知、协同编辑、行情推送、游戏服务等场景。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">由于 WebSocket 是长连接 + 状态敏感的协议，在 Nginx 中做反向代理时，需要特别注意一些细节。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><strong>这些细节主要是：</strong></p><ul style="margin-left: 2.5rem; padding-left: 0px; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><li style="list-style: inherit;"><em>1）</em>协议升级（Upgrade）；</li><li style="list-style: inherit;"><em>2）</em>连接保持；</li><li style="list-style: inherit;"><em>3）</em>超时控制；</li><li style="list-style: inherit;"><em>4）</em>负载均衡策略；</li><li style="list-style: inherit;"><em>5）</em>云环境 / K8s 场景下的断连问题。</li></ul><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><strong>本文从基础配置、生产配置、Docker / K8s、安全、排障、性能调优，系统性讲清 WebSocket 在 Nginx 中的正确打开方式。</strong></p><div img-uploading-status=""  image-package-1"="" data-index="1" style="font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><div><div><img src="https://img2024.cnblogs.com/blog/1834368/202609/1834368-20260907161217653-1464950295.png" alt="cover-opti" loading="lazy" style="border: 0px; max-width: 100%; height: auto !important; cursor: zoom-in; transition: transform 300ms cubic-bezier(0.2, 0, 0.2, 1) !important;" /></div></div></div><h1>2、WebSocket如何建立长连接</h1><div img-uploading-status=""  image-package-2"="" data-index="2" style="font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><div><div><img src="https://img2024.cnblogs.com/blog/1834368/202607/1834368-20260728131727233-714256079.png" alt="5" loading="lazy" style="border: 0px; max-width: 100%; height: auto !important; cursor: zoom-in; transition: transform 300ms cubic-bezier(0.2, 0, 0.2, 1) !important;" /></div></div></div><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><strong>WebSocket 通过 HTTP/1.1 完成握手：</strong></p><blockquote style="background-image: none; border-width: medium medium medium 3px; border-style: none none none solid; border-color: currentcolor currentcolor currentcolor #e2dfdf; margin: 10px 0px; background-color: #eeeeee; width: 896px; color: #555555; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif;"><p style="margin: 10px auto;">GET /ws HTTP/1.1</p><p style="margin: 10px auto;">Upgrade: websocket</p><p style="margin: 10px auto;">Connection: Upgrade</p></blockquote><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">一旦升级成功，连接将不再遵循 HTTP 请求-响应模型，而是长期保持的双向 TCP 通道。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><strong><em>PS：</em></strong>这也是为什么 WebSocket 对 Nginx 超时 / FD / 内核参数 / LB 极度敏感。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><strong>更多WebSocket基础资料可以继续阅读：</strong></p><ol style="margin-left: 2.5rem; padding-left: 0px; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><li style="list-style: inherit;"><a href="http://www.52im.net/thread-3134-1-1.html" target="_blank" style="color: #1d58d1; text-decoration: none;">WebSocket从入门到精通，半小时就够！</a></li><li style="list-style: inherit;"><a href="http://www.52im.net/thread-1258-1-1.html" target="_blank" style="color: #1d58d1; text-decoration: none;">刨根问底HTTP与WebSocket的关系(上篇)</a></li><li style="list-style: inherit;"><a href="http://www.52im.net/thread-1273-1-1.html" target="_blank" style="color: #1d58d1; text-decoration: none;">刨根问底WebSocket与Socket的关系</a></li><li style="list-style: inherit;"><a href="http://www.52im.net/thread-3695-1-1.html" target="_blank" style="color: #1d58d1; text-decoration: none;">搞懂现代Web端即时通讯技术一文就够：WebSocket、socket.io、SSE</a></li><li style="list-style: inherit;"><a href="http://www.52im.net/thread-3098-1-1.html" target="_blank" style="color: #1d58d1; text-decoration: none;">Web端即时通讯实践干货：如何让你的WebSocket断网重连更快速？</a></li><li style="list-style: inherit;"><a href="http://www.52im.net/thread-1341-1-1.html" target="_blank" style="color: #1d58d1; text-decoration: none;">理论联系实际：从零理解WebSocket的通信原理、协议格式、安全性</a></li></ol><h1>3、基础WebSocket反向代理配置</h1><div img-uploading-status=""  image-package-3"="" data-index="3" style="font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><div><div><img src="https://img2024.cnblogs.com/blog/1834368/202609/1834368-20260907161229408-253480156.png" alt="2" loading="lazy" style="border: 0px; max-width: 100%; height: auto !important; cursor: zoom-in; transition: transform 300ms cubic-bezier(0.2, 0, 0.2, 1) !important;" /></div></div></div><blockquote style="background-image: none; border-width: medium medium medium 3px; border-style: none none none solid; border-color: currentcolor currentcolor currentcolor #e2dfdf; margin: 10px 0px; background-color: #eeeeee; width: 896px; color: #555555; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif;"><p style="margin: 10px auto;">http {</p><p style="margin: 10px auto;">&nbsp;&nbsp;&nbsp;&nbsp;# 基础 WebSocket 代理配置</p><p style="margin: 10px auto;">&nbsp;&nbsp;&nbsp;&nbsp;upstream websocket_backend {</p><p style="margin: 10px auto;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;server 192.168.1.100:8080;</p><p style="margin: 10px auto;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;server 192.168.1.101:8080;</p><p style="margin: 10px auto;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# 支持长连接</p><p style="margin: 10px auto;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;keepalive 10;</p><p style="margin: 10px auto;">&nbsp;&nbsp;&nbsp;&nbsp;}</p><p style="margin: 10px auto;">&nbsp;</p><p style="margin: 10px auto;">&nbsp;&nbsp;&nbsp;&nbsp;server {</p><p style="margin: 10px auto;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;listen 80;</p><p style="margin: 10px auto;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;server_name ws.example.com;</p><p style="margin: 10px auto;">&nbsp;</p><p style="margin: 10px auto;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;location /ws/ {</p><p style="margin: 10px auto;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# 核心 WebSocket 配置</p><p style="margin: 10px auto;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;proxy_pass http://websocket_backend;</p><p style="margin: 10px auto;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;proxy_http_version 1.1;</p><p style="margin: 10px auto;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;proxy_set_header Upgrade $http_upgrade;</p><p style="margin: 10px auto;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;proxy_set_header Connection "upgrade";</p><p style="margin: 10px auto;">&nbsp;</p><p style="margin: 10px auto;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# 重要：传递原始主机头和客户端 IP</p><p style="margin: 10px auto;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;proxy_set_header Host $host;</p><p style="margin: 10px auto;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;proxy_set_header X-Real-IP $remote_addr;</p><p style="margin: 10px auto;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;</p><p style="margin: 10px auto;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;proxy_set_header X-Forwarded-Proto $scheme;</p><p style="margin: 10px auto;">&nbsp;</p><p style="margin: 10px auto;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# 长连接超时设置</p><p style="margin: 10px auto;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;proxy_read_timeout 3600s;</p><p style="margin: 10px auto;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;proxy_send_timeout 3600s;</p><p style="margin: 10px auto;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;proxy_connect_timeout 30s;</p><p style="margin: 10px auto;">&nbsp;</p><p style="margin: 10px auto;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# 禁用缓冲，确保实时性</p><p style="margin: 10px auto;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;proxy_buffering off;</p><p style="margin: 10px auto;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;proxy_cache off;</p><p style="margin: 10px auto;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</p><p style="margin: 10px auto;">&nbsp;&nbsp;&nbsp;&nbsp;}</p><p style="margin: 10px auto;">}</p></blockquote><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><strong>补充说明：</strong></p><ul style="margin-left: 2.5rem; padding-left: 0px; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><li style="list-style: inherit;"><em>1）</em>proxy_http_version 1.1：WebSocket 必须；</li><li style="list-style: inherit;"><em>2）</em>Upgrade / Connection：完成协议升级；</li><li style="list-style: inherit;"><em>3）</em>proxy_buffering off：防止消息延迟；</li><li style="list-style: inherit;"><em>4）</em>proxy_read_timeout：防止 Nginx 主动断连。</li></ul><h1>4、生产环境必须补充的 Upgrade 头处理（关键）</h1><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><strong>注意：</strong>这是原始配置中最容易踩坑、但极其重要的一点。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><strong>推荐写法：</strong></p><blockquote style="background-image: none; border-width: medium medium medium 3px; border-style: none none none solid; border-color: currentcolor currentcolor currentcolor #e2dfdf; margin: 10px 0px; background-color: #eeeeee; width: 896px; color: #555555; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif;"><p style="margin: 10px auto;">map $http_upgrade $connection_upgrade {</p><p style="margin: 10px auto;">&nbsp;&nbsp;&nbsp;&nbsp;default upgrade;</p><p style="margin: 10px auto;">&nbsp;&nbsp;&nbsp;&nbsp;'' close;</p><p style="margin: 10px auto;">}</p></blockquote><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><strong>然后在 location 中：</strong></p><blockquote style="background-image: none; border-width: medium medium medium 3px; border-style: none none none solid; border-color: currentcolor currentcolor currentcolor #e2dfdf; margin: 10px 0px; background-color: #eeeeee; width: 896px; color: #555555; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif;"><p style="margin: 10px auto;">proxy_set_header Upgrade $http_upgrade;</p><p style="margin: 10px auto;">proxy_set_header Connection $connection_upgrade;</p></blockquote><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><strong>为什么这样更安全？</strong></p><ul style="margin-left: 2.5rem; padding-left: 0px; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><li style="list-style: inherit;"><em>1）</em>非 WebSocket 请求 &#8594; Connection: close；</li><li style="list-style: inherit;"><em>2）</em>WebSocket 请求 &#8594; Connection: upgrade。</li></ul><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><strong><em>PS：</em></strong>避免普通 HTTP 请求被错误升级。</p><h1>5、完整生产级WebSocket配置</h1><blockquote style="background-image: none; border-width: medium medium medium 3px; border-style: none none none solid; border-color: currentcolor currentcolor currentcolor #e2dfdf; margin: 10px 0px; background-color: #eeeeee; width: 896px; color: #555555; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif;"><p style="margin: 10px auto;">http {</p><p style="margin: 10px auto;">&nbsp;&nbsp;&nbsp;&nbsp;upstream websocket_cluster {</p><p style="margin: 10px auto;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ip_hash;</p><p style="margin: 10px auto;">&nbsp;</p><p style="margin: 10px auto;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;server 10.0.1.10:8080 weight=3;</p><p style="margin: 10px auto;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;server 10.0.1.11:8080 weight=2;</p><p style="margin: 10px auto;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;server 10.0.1.12:8080 backup;</p><p style="margin: 10px auto;">&nbsp;</p><p style="margin: 10px auto;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# 以下健康检查依赖 nginx_upstream_check_module（非官方）</p><p style="margin: 10px auto;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;check interval=3000 rise=2 fall=3 timeout=1000 type=http;</p><p style="margin: 10px auto;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;check_http_send "GET /health HTTP/1.0\r\n\r\n";</p><p style="margin: 10px auto;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;check_http_expect_alive http_2xx http_3xx;</p><p style="margin: 10px auto;">&nbsp;&nbsp;&nbsp;&nbsp;}</p><p style="margin: 10px auto;">&nbsp;</p><p style="margin: 10px auto;">&nbsp;&nbsp;&nbsp;&nbsp;server {</p><p style="margin: 10px auto;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;listen 443 ssl http2;</p><p style="margin: 10px auto;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;server_name ws.example.com;</p><p style="margin: 10px auto;">&nbsp;</p><p style="margin: 10px auto;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ssl_certificate /etc/nginx/ssl/example.com.crt;</p><p style="margin: 10px auto;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ssl_certificate_key /etc/nginx/ssl/example.com.key;</p><p style="margin: 10px auto;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ssl_protocols TLSv1.2 TLSv1.3;</p><p style="margin: 10px auto;">&nbsp;</p><p style="margin: 10px auto;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;location /chat/ {</p><p style="margin: 10px auto;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;proxy_pass http://websocket_cluster;</p><p style="margin: 10px auto;">&nbsp;</p><p style="margin: 10px auto;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# WebSocket 升级</p><p style="margin: 10px auto;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;proxy_http_version 1.1;</p><p style="margin: 10px auto;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;proxy_set_header Upgrade $http_upgrade;</p><p style="margin: 10px auto;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;proxy_set_header Connection $connection_upgrade;</p><p style="margin: 10px auto;">&nbsp;</p><p style="margin: 10px auto;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# 原始请求信息</p><p style="margin: 10px auto;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;proxy_set_header Host $host;</p><p style="margin: 10px auto;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;proxy_set_header X-Real-IP $remote_addr;</p><p style="margin: 10px auto;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;</p><p style="margin: 10px auto;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;proxy_set_header X-Forwarded-Proto $scheme;</p><p style="margin: 10px auto;">&nbsp;</p><p style="margin: 10px auto;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# ⚠️ 长连接超时</p><p style="margin: 10px auto;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;proxy_read_timeout 86400s;</p><p style="margin: 10px auto;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;proxy_send_timeout 86400s;</p><p style="margin: 10px auto;">&nbsp;</p><p style="margin: 10px auto;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# 实时性</p><p style="margin: 10px auto;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;proxy_buffering off;</p><p style="margin: 10px auto;">&nbsp;</p><p style="margin: 10px auto;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;# 连接限制</p><p style="margin: 10px auto;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;limit_conn ws_conn 1000;</p><p style="margin: 10px auto;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</p><p style="margin: 10px auto;">&nbsp;&nbsp;&nbsp;&nbsp;}</p><p style="margin: 10px auto;">}</p><p style="margin: 10px auto;">limit_conn_zone $binary_remote_addr zone=ws_conn:10m;</p></blockquote><h1>6、HTTP/2 与 WebSocket 的现实情况</h1><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><strong>基本配置：</strong></p><blockquote style="background-image: none; border-width: medium medium medium 3px; border-style: none none none solid; border-color: currentcolor currentcolor currentcolor #e2dfdf; margin: 10px 0px; background-color: #eeeeee; width: 896px; color: #555555; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif;"><p style="margin: 10px auto;">listen 443 ssl http2;</p></blockquote><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><strong>重要认知：</strong></p><ul style="margin-left: 2.5rem; padding-left: 0px; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><li style="list-style: inherit;"><em>1）</em>浏览器 WebSocket 仍使用 HTTP/1.1；</li><li style="list-style: inherit;"><em>2）</em>HTTP/2 WebSocket（RFC 8441）：浏览器支持有限、Nginx 支持不完整。</li></ul><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><strong><em>PS：</em></strong>这是正常现象，不是配置错误。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><strong>WebSocket location 必须显式：</strong></p><blockquote style="background-image: none; border-width: medium medium medium 3px; border-style: none none none solid; border-color: currentcolor currentcolor currentcolor #e2dfdf; margin: 10px 0px; background-color: #eeeeee; width: 896px; color: #555555; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif;"><p style="margin: 10px auto;">proxy_http_version 1.1;</p></blockquote><h1>7、Docker / K8s 场景</h1><div img-uploading-status=""  image-package-4"="" data-index="4" style="font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><div><div><img src="https://img2024.cnblogs.com/blog/1834368/202609/1834368-20260907161239570-982573325.png" alt="3" loading="lazy" style="border: 0px; max-width: 100%; height: auto !important; cursor: zoom-in; transition: transform 300ms cubic-bezier(0.2, 0, 0.2, 1) !important;" /></div></div></div><blockquote style="background-image: none; border-width: medium medium medium 3px; border-style: none none none solid; border-color: currentcolor currentcolor currentcolor #e2dfdf; margin: 10px 0px; background-color: #eeeeee; width: 896px; color: #555555; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif;"><p style="margin: 10px auto;">map $http_upgrade $connection_upgrade {</p><p style="margin: 10px auto;">&nbsp;&nbsp;&nbsp;&nbsp;default upgrade;</p><p style="margin: 10px auto;">&nbsp;&nbsp;&nbsp;&nbsp;'' close;</p><p style="margin: 10px auto;">}</p><p style="margin: 10px auto;">&nbsp;</p><p style="margin: 10px auto;">server {</p><p style="margin: 10px auto;">&nbsp;&nbsp;&nbsp;&nbsp;listen 80;</p><p style="margin: 10px auto;">&nbsp;</p><p style="margin: 10px auto;">&nbsp;&nbsp;&nbsp;&nbsp;location /ws/ {</p><p style="margin: 10px auto;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;proxy_pass http://websocket-service:8080;</p><p style="margin: 10px auto;">&nbsp;</p><p style="margin: 10px auto;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;proxy_http_version 1.1;</p><p style="margin: 10px auto;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;proxy_set_header Upgrade $http_upgrade;</p><p style="margin: 10px auto;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;proxy_set_header Connection $connection_upgrade;</p><p style="margin: 10px auto;">&nbsp;</p><p style="margin: 10px auto;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;proxy_read_timeout 7d;</p><p style="margin: 10px auto;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;proxy_send_timeout 7d;</p><p style="margin: 10px auto;">&nbsp;</p><p style="margin: 10px auto;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;proxy_buffering off;</p><p style="margin: 10px auto;">&nbsp;&nbsp;&nbsp;&nbsp;}</p><p style="margin: 10px auto;">}</p></blockquote><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><strong>K8s / 云环境的隐藏断连点：</strong></p><div img-uploading-status=""  image-package-5"="" data-index="5" style="font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><div><div><img src="https://img2024.cnblogs.com/blog/1834368/202609/1834368-20260907161246000-411426277.png" alt="4" loading="lazy" style="border: 0px; max-width: 100%; height: auto !important; cursor: zoom-in; transition: transform 300ms cubic-bezier(0.2, 0, 0.2, 1) !important;" /></div></div></div><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><strong><em>PS：</em></strong>Nginx 再怎么配都没用，必须应用层心跳</p><h1>8、WebSocket心跳保活（生产必做）</h1><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><strong>推荐 20~30 秒一次：</strong></p><blockquote style="background-image: none; border-width: medium medium medium 3px; border-style: none none none solid; border-color: currentcolor currentcolor currentcolor #e2dfdf; margin: 10px 0px; background-color: #eeeeee; width: 896px; color: #555555; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif;"><p style="margin: 10px auto;">{ "type": "ping" }</p></blockquote><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">否则云 LB、防火墙、NAT，都会主动断你连接。</p><h1>9、负载均衡策略的选择</h1><div img-uploading-status=""  image-package-6"="" data-index="6" style="font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><div><div><img src="https://img2024.cnblogs.com/blog/1834368/202609/1834368-20260907161251100-1403927043.png" alt="5" loading="lazy" style="border: 0px; max-width: 100%; height: auto !important; cursor: zoom-in; transition: transform 300ms cubic-bezier(0.2, 0, 0.2, 1) !important;" /></div></div></div><blockquote style="background-image: none; border-width: medium medium medium 3px; border-style: none none none solid; border-color: currentcolor currentcolor currentcolor #e2dfdf; margin: 10px 0px; background-color: #eeeeee; width: 896px; color: #555555; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif;"><p style="margin: 10px auto;">upstream websocket_backend {</p><p style="margin: 10px auto;">&nbsp;&nbsp;&nbsp;&nbsp;ip_hash;</p><p style="margin: 10px auto;">&nbsp;&nbsp;&nbsp;&nbsp;server 10.0.1.10:8080;</p><p style="margin: 10px auto;">&nbsp;&nbsp;&nbsp;&nbsp;server 10.0.1.11:8080;</p><p style="margin: 10px auto;">}</p></blockquote><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><strong>实战建议：</strong></p><div img-uploading-status=""  image-package-7"="" data-index="7" style="font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><div><div><img src="https://img2024.cnblogs.com/blog/1834368/202609/1834368-20260907161256545-1737476641.png" alt="6" loading="lazy" style="border: 0px; max-width: 100%; height: auto !important; cursor: zoom-in; transition: transform 300ms cubic-bezier(0.2, 0, 0.2, 1) !important;" /></div></div></div><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><strong><em>PS：</em></strong>WebSocket 本质上 不适合强依赖 LB 算法做会话保持</p><h1>10、优雅下线与灰度发布（生产增强）</h1><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><strong>K8s 必配：</strong></p><blockquote style="background-image: none; border-width: medium medium medium 3px; border-style: none none none solid; border-color: currentcolor currentcolor currentcolor #e2dfdf; margin: 10px 0px; background-color: #eeeeee; width: 896px; color: #555555; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif;"><p style="margin: 10px auto;">terminationGracePeriodSeconds: 60</p></blockquote><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><strong>后端逻辑：</strong></p><ul style="margin-left: 2.5rem; padding-left: 0px; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><li style="list-style: inherit;"><em>1）</em>收到 SIGTERM；</li><li style="list-style: inherit;"><em>2）</em>停止新 WS；</li><li style="list-style: inherit;"><em>3）</em>通知客户端重连；</li><li style="list-style: inherit;"><em>4）</em>平滑下线。</li></ul><h1>11、Nginx及Linux内核参数（高并发必调）</h1><div img-uploading-status=""  image-package-8"="" data-index="8" style="font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><div><div><img src="https://img2024.cnblogs.com/blog/1834368/202609/1834368-20260907161301768-1988712547.png" alt="7" loading="lazy" style="border: 0px; max-width: 100%; height: auto !important; cursor: zoom-in; transition: transform 300ms cubic-bezier(0.2, 0, 0.2, 1) !important;" /></div></div></div><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><strong>Nginx配置如下：</strong></p><blockquote style="background-image: none; border-width: medium medium medium 3px; border-style: none none none solid; border-color: currentcolor currentcolor currentcolor #e2dfdf; margin: 10px 0px; background-color: #eeeeee; width: 896px; color: #555555; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif;"><p style="margin: 10px auto;">worker_processes auto;</p><p style="margin: 10px auto;">worker_rlimit_nofile 200000;</p><p style="margin: 10px auto;">&nbsp;</p><p style="margin: 10px auto;">events {</p><p style="margin: 10px auto;">&nbsp;&nbsp;&nbsp;&nbsp;worker_connections 65535;</p><p style="margin: 10px auto;">&nbsp;&nbsp;&nbsp;&nbsp;use epoll;</p><p style="margin: 10px auto;">}</p></blockquote><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><strong>Linux操作系统的配置：</strong></p><blockquote style="background-image: none; border-width: medium medium medium 3px; border-style: none none none solid; border-color: currentcolor currentcolor currentcolor #e2dfdf; margin: 10px 0px; background-color: #eeeeee; width: 896px; color: #555555; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif;"><p style="margin: 10px auto;">net.core.somaxconn = 65535</p><p style="margin: 10px auto;">net.ipv4.tcp_tw_reuse = 1</p><p style="margin: 10px auto;">net.ipv4.tcp_fin_timeout = 15</p></blockquote><h1>12、写在最后</h1><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><strong>指令如下：</strong></p><blockquote style="background-image: none; border-width: medium medium medium 3px; border-style: none none none solid; border-color: currentcolor currentcolor currentcolor #e2dfdf; margin: 10px 0px; background-color: #eeeeee; width: 896px; color: #555555; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif;"><p style="margin: 10px auto;">wscat -c ws://domain/ws</p><p style="margin: 10px auto;">ss -an | grep ESTAB | wc -l</p></blockquote><h1>13、参考资料</h1><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">[1] <a href="https://www.rfc-editor.org/rfc/rfc6455.txt" target="_blank" style="color: #1d58d1; text-decoration: none;">RFC6455 协议文档</a>、<a href="https://developer.mozilla.org/zh-CN/docs/Web/API/WebSocket" target="_blank" style="color: #1d58d1; text-decoration: none;">WebSocket API文档</a>、<a href="https://developer.mozilla.org/zh-CN/docs/Web/API/EventSource" target="_blank" style="color: #1d58d1; text-decoration: none;">SSE API文档</a></p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">[2] <a href="http://www.52im.net/thread-338-1-1.html" target="_blank" style="color: #1d58d1; text-decoration: none;">新手入门贴：史上最全Web端即时通讯技术原理详解</a></p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">[3] <a href="http://www.52im.net/thread-336-1-1.html" target="_blank" style="color: #1d58d1; text-decoration: none;">Web端即时通讯技术盘点：短轮询、Comet、Websocket、SSE</a></p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">[4] <a href="http://www.52im.net/thread-1038-1-1.html" target="_blank" style="color: #1d58d1; text-decoration: none;">详解Web端通信方式的演进：从Ajax、JSONP 到 SSE、Websocket</a></p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">[5] <a href="http://www.52im.net/thread-3555-1-1.html" target="_blank" style="color: #1d58d1; text-decoration: none;">网页端IM通信技术快速入门：短轮询、长轮询、SSE、WebSocket</a></p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">[6] <a href="http://www.52im.net/thread-3695-1-1.html" target="_blank" style="color: #1d58d1; text-decoration: none;">搞懂现代Web端即时通讯技术一文就够：WebSocket、socket.io、SSE</a></p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">[7] <a href="http://www.52im.net/thread-1258-1-1.html" target="_blank" style="color: #1d58d1; text-decoration: none;">WebSocket详解（四）：刨根问底HTTP与WebSocket的关系(上篇)</a></p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">[8] <a href="http://www.52im.net/thread-1273-1-1.html" target="_blank" style="color: #1d58d1; text-decoration: none;">WebSocket详解（六）：刨根问底WebSocket与Socket的关系</a></p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">[9] <a href="http://www.52im.net/thread-3098-1-1.html" target="_blank" style="color: #1d58d1; text-decoration: none;">Web端即时通讯实践干货：如何让你的WebSocket断网重连更快速？</a></p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">[10] <a href="http://www.52im.net/thread-3134-1-1.html" target="_blank" style="color: #1d58d1; text-decoration: none;">WebSocket从入门到精通，半小时就够！</a></p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">[11] <a href="http://www.52im.net/thread-1341-1-1.html" target="_blank" style="color: #1d58d1; text-decoration: none;">理论联系实际：从零理解WebSocket的通信原理、协议格式、安全性</a></p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">[12] <a href="http://www.52im.net/thread-4748-1-1.html" target="_blank" style="color: #1d58d1; text-decoration: none;">浅谈网页端IM技术及相关测试方法实践（包括WebSocket性能测试）</a>》</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">[13] <a href="http://www.52im.net/thread-4636-1-1.html" target="_blank" style="color: #1d58d1; text-decoration: none;">微信团队分享：来看看微信十年前的IM消息收发架构，你做到了吗</a></p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">[14] <a href="http://www.52im.net/thread-3065-1-1.html" target="_blank" style="color: #1d58d1; text-decoration: none;">零基础IM开发入门(一)：什么是IM系统？</a></p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">[15] <a href="http://www.52im.net/thread-4860-1-1.html" target="_blank" style="color: #1d58d1; text-decoration: none;">转转客服IM系统的WebSocket集群架构设计和部署方案</a></p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">[16] <a href="http://www.52im.net/thread-4896-1-1.html" target="_blank" style="color: #1d58d1; text-decoration: none;">基于WebSocket的IM即时通信方案在H5游戏场景下的技术实践</a></p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">[17] <a href="http://www.52im.net/thread-4909-1-1.html" target="_blank" style="color: #1d58d1; text-decoration: none;">详解AI大模型实时通信为什么选SSE，而不是WebSocket和WebRTC</a></p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">[18] <a href="http://www.52im.net/thread-4918-1-1.html" target="_blank" style="color: #1d58d1; text-decoration: none;">都HTML5了，Web端即时通讯技术到底该用什么？一文即懂！</a></p><blockquote style="background-image: none; border-width: medium medium medium 3px; border-style: none none none solid; border-color: currentcolor currentcolor currentcolor #e2dfdf; margin: 10px 0px; background-color: #eeeeee; width: 896px; color: #555555; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif;"><p style="margin: 10px auto;"><strong>即时通讯技术学习：</strong></p><p style="margin: 10px auto;">- 移动端IM开发入门文章：《<a href="http://www.52im.net/thread-464-1-1.html" rel="noopener nofollow" target="_blank" style="color: #1d58d1; text-decoration: none;">新手入门一篇就够：从零开发移动端IM</a>》</p><p style="margin: 10px auto;">- 开源IM框架源码：<a href="https://github.com/JackJiang2011/MobileIMSDK" rel="noopener nofollow" target="_blank" style="color: #1d58d1; text-decoration: none;">https://github.com/JackJiang2011/MobileIMSDK</a>（<a href="https://gitee.com/jackjiang/MobileIMSDK" rel="noopener nofollow" target="_blank" style="color: #1d58d1; text-decoration: none;">备用地址点此</a>）</p></blockquote><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">（本文同步发布于： <a href="http://www.52im.net/thread-4921-1-1.html" target="_blank" style="color: #1d58d1; text-decoration: none;">http://www.52im.net/thread-4921-1-1.html</a>）</p><img src ="http://www.blogjava.net/jb2011/aggbug/451796.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jb2011/" target="_blank">Jack Jiang</a> 2026-09-08 10:59 <a href="http://www.blogjava.net/jb2011/archive/2026/09/08/451796.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>即时通讯IM离线消息该怎么存？全面盘点主流存储方案</title><link>http://www.blogjava.net/jb2011/archive/2026/08/25/451793.html</link><dc:creator>Jack Jiang</dc:creator><author>Jack Jiang</author><pubDate>Tue, 25 Aug 2026 13:02:00 GMT</pubDate><guid>http://www.blogjava.net/jb2011/archive/2026/08/25/451793.html</guid><wfw:comment>http://www.blogjava.net/jb2011/comments/451793.html</wfw:comment><comments>http://www.blogjava.net/jb2011/archive/2026/08/25/451793.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jb2011/comments/commentRss/451793.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jb2011/services/trackbacks/451793.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 本文作者饭后咖啡，有修订和改动。1、引言离线消息是IM系统的核心能力，当用户不在线时，消息必须可靠存储，待用户上线后完整推送。本文将对比主流的离线消息存储方案，帮你找到最适合业务场景的架构。2、离线消息的业务特征和主流存储方案概览离线消息的业务特征：方案对比总览：3、存储方案1：MySQL分库分表表结构设计：CREATE TABLE offline_message_$table (&nbsp;&n...&nbsp;&nbsp;<a href='http://www.blogjava.net/jb2011/archive/2026/08/25/451793.html'>阅读全文</a><img src ="http://www.blogjava.net/jb2011/aggbug/451793.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jb2011/" target="_blank">Jack Jiang</a> 2026-08-25 21:02 <a href="http://www.blogjava.net/jb2011/archive/2026/08/25/451793.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>移动端实时音视频聊天框架 RainbowAV v2.2.7发布</title><link>http://www.blogjava.net/jb2011/archive/2026/08/11/451792.html</link><dc:creator>Jack Jiang</dc:creator><author>Jack Jiang</author><pubDate>Tue, 11 Aug 2026 12:38:00 GMT</pubDate><guid>http://www.blogjava.net/jb2011/archive/2026/08/11/451792.html</guid><wfw:comment>http://www.blogjava.net/jb2011/comments/451792.html</wfw:comment><comments>http://www.blogjava.net/jb2011/archive/2026/08/11/451792.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jb2011/comments/commentRss/451792.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jb2011/services/trackbacks/451792.html</trackback:ping><description><![CDATA[<div id="cnblogs_post_body"  blogpost-body-html"="" style="margin-bottom: 20px; word-break: break-word; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><h1>1、v2.2.7 版更新内容</h1><strong>此版更新内容：</strong><br /><ul style="margin-left: 2.5rem; padding-left: 0px;"><li style="list-style: inherit;"><em>1）</em>[<span style="color: #00b050;">升级</span>] 提升targetSdkVersion至36，全面兼容Android 16；</li><li style="list-style: inherit;"><em>2）</em>[<span style="color: #909296;">优化</span>] 开发工程升级适配AGP 9.1最新版；</li><li style="list-style: inherit;"><em>3）</em>[<span style="color: #909296;">优化</span>] 升级权限框架以适配最新Android 16系统；</li><li style="list-style: inherit;"><em>4）</em>[<span style="color: #909296;">优化</span>] 针对全部界面适配系统强制的Edge to Edge全面屏特性；</li><li style="list-style: inherit;"><em>5）</em>[<span style="color: #909296;">优化</span>] 呼叫和聊天界面的ui优化等；</li></ul><strong>更多历史版本：</strong><br /><ul style="margin-left: 2.5rem; padding-left: 0px;"><li style="list-style: inherit;"><a href="http://www.52im.net/thread-1400-1-1.html" target="_blank" rel="noopener nofollow" style="color: #1d58d1; text-decoration: none;">音视频框架RainbowAV 的v2.1版已发布！</a></li><li style="list-style: inherit;"><a href="http://www.52im.net/thread-2672-1-1.html" target="_blank" rel="noopener nofollow" style="color: #1d58d1; text-decoration: none;">音视频框架RainbowAV 的v2.2版已发布！</a></li><li style="list-style: inherit;"><a href="http://www.52im.net/thread-2756-1-1.html" target="_blank" rel="noopener nofollow" style="color: #1d58d1; text-decoration: none;">音视频框架RainbowAV 的v2.2.1版已发布！</a></li><li style="list-style: inherit;"><a href="http://www.52im.net/thread-3367-1-1.html" target="_blank" rel="noopener nofollow" style="color: #1d58d1; text-decoration: none;">音视频框架RainbowAV 的v2.2.3版已发布！</a></li><li style="list-style: inherit;"><a href="http://www.52im.net/thread-3997-1-1.html" target="_blank" rel="noopener nofollow" style="color: #1d58d1; text-decoration: none;">音视频框架RainbowAV 的v2.2.5版已发布！</a></li><li style="list-style: inherit;"><a href="http://www.52im.net/thread-4721-1-1.html" target="_blank" rel="noopener nofollow" style="color: #1d58d1; text-decoration: none;">音视频框架RainbowAV 的v2.2.6版已发布！</a></li></ul><h1>2、关于RainbowAV</h1><p style="margin: 10px auto;"><strong><img alt="1" loading="lazy" data-src="https://img2024.cnblogs.com/blog/1834368/202608/1834368-20260802204325606-601481092.jpg" src="https://img2024.cnblogs.com/blog/1834368/202608/1834368-20260802204325606-601481092.jpg" medium-zoom-image="" ls-is-cached=""  lazyloaded"="" style="border: 0px; max-width: 100%; height: auto !important; cursor: zoom-in; transition: transform 300ms cubic-bezier(0.2, 0, 0.2, 1) !important;" /></strong></p><p style="margin: 10px auto;"><strong>🔥 RainbowAV是一套完整移动端实时音视频框架，不依赖第3方服务，使用方便，部署简单，轻量级、模块化设计。</strong></p><p style="margin: 10px auto;">📱 客户端历经多年、在大量最终用户的真机使用下，兼容性和适配能力强，它并不是个Demo；</p><p style="margin: 10px auto;">🌟 服务端轻量级、极少依赖、简单易用、3行指令即可部署；</p><p style="margin: 10px auto;">🌟 底层核心为C++编写，性能优先，CPU占用约17%（作为对比，同机型下手机QQ约为20%、微信约为19%）；</p><p style="margin: 10px auto;">🌟 客户端资源占用极少，持续运行时内存仅占 13MB 左右；</p><p style="margin: 10px auto;">🌟 实时视频聊天时上下行总流量约 30KB/S（作为对比，手机QQ和微信的实时音视频均约 60KB/S）；</p><p style="margin: 10px auto;">🌟 实时语音聊天时上下行总流量约 9KB/S（作为对比，手机QQ约 14KB/S、微信约 6KB/S）；</p><p style="margin: 10px auto;">🌟 可应用于3G、4G等弱网络，在跨洲际高延迟网络下做过大量测试。</p><h1><strong>3、RainbowAV的设计目标</strong></h1><p style="margin: 10px auto;">鉴于实时音视频技术的高门槛，RainbowAV技术从设计开始就希望能简化集成和使用，因而是以独立工程的方式进行迭代和演进，并不会与RainbowChat这样的IM发生代码耦合性，从而方便开发者自行改进甚至2次开发。</p><p style="margin: 10px auto;"><strong>具体就是：</strong></p><ul style="margin-left: 2.5rem; padding-left: 0px;"><li style="list-style: inherit;"><em>1）</em>与IM工程的解耦：独立工程，方便迭代和演进，甚至2次开发；</li><li style="list-style: inherit;"><em>2）</em>服务端部署便利：服务端编译成了清爽的可执行程序，3行指令即完成部署；</li><li style="list-style: inherit;"><em>3）</em>单实例拆分部署：共编译成3个程序，均可独立部署，互相无依赖，进一步提升单实例性能；</li><li style="list-style: inherit;"><em>4）</em>多实例分布式部署：鉴于实时音视频聊天的特殊性（只在聊天时才需要连接音视频服务器），多实例分布式部署变的简单；</li><li style="list-style: inherit;"><em>5）</em>服务端的高性能：得益于Linux epoll异步编程模型，服务端拥有极高的并发处理性能。</li><li style="list-style: inherit;"><em>6）</em>手机端高兼容性：受益于大量的兼容性测试，甚至在Android 5.0上仍可很好地工作，代码表现健壮；</li><li style="list-style: inherit;"><em>7）</em>手机低资源占用：Android客户端经过大量优化，资源占用低；</li><li style="list-style: inherit;"><em>8）</em>高压缩低码率：经过编码压缩后的音视频数据，只需很少的流量；</li><li style="list-style: inherit;"><em>9）</em>P2P通信支持：尽可能降低服务端性能和带宽压力；</li><li style="list-style: inherit;"><em>10）</em>弱网络的支持：降低弱网络高延迟环境带来的通信脆弱性，保证应用层的稳定运行。</li></ul><h1>4、RainbowAV的性能指标</h1><p style="margin: 10px auto;"><strong>客户端性能指标总结：</strong></p><ul style="margin-left: 2.5rem; padding-left: 0px;"><li style="list-style: inherit;"><em>1）</em>客户端运行稳定后，内存占用约<span style="color: #a0522d;"><span style="text-decoration: underline;">13M</span></span>左右（以MOTO G XT1077手机为例）；</li><li style="list-style: inherit;"><em>2）</em>实时音视频(视频+语音)时，CPU占用约<span style="color: #a0522d;"><span style="text-decoration: underline;">17%</span></span>（手机QQ的约为20%、微信的约为19%）；</li><li style="list-style: inherit;"><em>3）</em>实时语音(仅语音)时，CPU占用约<span style="text-decoration: underline;"><span style="color: #a0522d;">11%</span></span>（手机QQ的约为12%、微信的约为5%）；</li><li style="list-style: inherit;"><em>4）</em>实时音视频(视频+语音)时上下行总流量约<span style="color: #a0522d;"><span style="text-decoration: underline;">30KB/S</span></span>（<span style="font-size: small;">手机QQ和微信的均约60KB/S</span>）；</li><li style="list-style: inherit;"><em>5）</em>实时语音(仅语音)时上下行总流量约<span style="color: #a0522d;"><span style="text-decoration: underline;">9KB/S</span></span>（<span style="font-size: small;">手机QQ的约14KB/S、微信的约6KB/S</span>）.</li></ul><p style="margin: 10px auto;"><strong>服务端性能指标总结：</strong></p><p style="margin: 10px auto;">RainbowAV服务端基于高性能的Linux epoll，理论设计性能是：单机1000到10000人同时使用。鉴于实时音视频的复杂性（P2P、中转等混合发生），想要准确地测试统计非常困难。但鉴于实时音视频技术的高流量特性，通常单机瓶颈会首先出现在带宽上，所以生产部署时需要在单机性能和带宽分流上总体考虑。而也正是得益于实时音视频的特殊性，聊天时可同时部署多个服务端实例，只要引导该对聊天的用户同时连接同一台实例即可进行聊天，从而让分布式部署和负载均衡变的简单。</p><h1>5、关于RainbowChat</h1><p style="margin: 10px auto;">&nbsp;<img alt="1" lazyloaded=""  medium-zoom-image"="" loading="lazy" data-src="https://img2024.cnblogs.com/blog/1834368/202604/1834368-20260426210602156-1614496586.jpg" src="https://img2024.cnblogs.com/blog/1834368/202604/1834368-20260426210602156-1614496586.jpg" style="border: 0px; max-width: 100%; height: auto !important; cursor: zoom-in; transition: transform 300ms cubic-bezier(0.2, 0, 0.2, 1) !important;" /></p><p style="margin: 10px auto;">🔥⚡️ <a href="http://www.52im.net/thread-19-1-1.html" rel="noopener nofollow" style="color: #1d58d1; text-decoration: none;">详细介绍</a>・<a href="http://www.52im.net/thread-2735-1-1.html" rel="noopener nofollow" style="color: #1d58d1; text-decoration: none;">版本日志</a>・运行截图(<a href="http://www.52im.net/thread-20-1-1.html" rel="noopener nofollow" style="color: #1d58d1; text-decoration: none;">Android</a>、<a href="http://www.52im.net/thread-2730-1-1.html" rel="noopener nofollow" style="color: #1d58d1; text-decoration: none;">iOS</a>)・下载体验(<a href="http://www.52im.net/thread-4739-1-1.html" rel="noopener nofollow" style="color: #1d58d1; text-decoration: none;">Android</a>、<a href="https://apps.apple.com/cn/app/rainbowchat/id1423024212" rel="noopener nofollow" style="color: #1d58d1; text-decoration: none;">iOS</a>) ⚡️🔥</p><p style="margin: 10px auto;">RainbowChat是一套<strong>基于 <a href="http://www.52im.net/thread-1027-1-1.html" target="_blank" rel="noopener nofollow" style="color: #1d58d1; text-decoration: none;">RainbowAV</a> 音视频聊天框架 的产品级移动端IM系统</strong>。<strong>RainbowChat源于真实运营的产</strong>品，解决了大量的屏幕适配、细节优化、机器兼容问题。<strong>RainbowChat可能是市面上提供im即时通讯聊天源码的，唯一一款同时支持TCP、UDP、WebSocket三种通信协议的IM产品</strong>。与姊妹产品 <a href="http://www.52im.net/thread-4824-1-1.html" rel="noopener nofollow" target="_blank" style="color: #1d58d1; text-decoration: none;">RainbowTalk</a> 和 <a href="http://www.52im.net/thread-2483-1-1.html" rel="noopener nofollow" target="_blank" style="color: #1d58d1; text-decoration: none;">RainbowChat-Web</a> 技术同源，历经考验。</p><p style="margin: 10px auto;"><img alt="v121_all_in_one_75pct_h2000px" loading="lazy" data-src="https://img2024.cnblogs.com/blog/1834368/202607/1834368-20260706162801472-2142212900.jpg" src="https://img2024.cnblogs.com/blog/1834368/202607/1834368-20260706162801472-2142212900.jpg"  medium-zoom-image"="" style="border: 0px; max-width: 100%; height: auto !important; cursor: zoom-in; transition: transform 300ms cubic-bezier(0.2, 0, 0.2, 1) !important;" /></p><h1>6、运行演示截图</h1><p style="margin: 10px auto;"><strong><em>1）</em>RainbowAV独立体验版运行效果：</strong></p><p style="margin: 10px auto;"><img alt="3" loading="lazy" data-src="https://img2024.cnblogs.com/blog/1834368/202608/1834368-20260802205435915-618410098.jpg" src="https://img2024.cnblogs.com/blog/1834368/202608/1834368-20260802205435915-618410098.jpg"  medium-zoom-image"="" style="border: 0px; max-width: 100%; height: auto !important; cursor: zoom-in; transition: transform 300ms cubic-bezier(0.2, 0, 0.2, 1) !important;" /></p><p style="margin: 10px auto;"><strong><em>2）</em>RainbowAV集成到 <a href="http://www.52im.net/thread-19-1-1.html" target="_blank" rel="noopener nofollow" style="color: #1d58d1; text-decoration: none;">RainbowChat</a> 的实时语音运行效果：</strong>（<a href="http://www.52im.net/thread-19-1-1.html" target="_blank" rel="noopener nofollow" style="color: #1d58d1; text-decoration: none;">RainbowChat介绍</a>、<a href="http://www.52im.net/thread-20-1-1.html" target="_blank" rel="noopener nofollow" style="color: #1d58d1; text-decoration: none;">更多RainbowChat截图</a>）<br /><img alt="12_real_voice" loading="lazy" data-src="https://img2024.cnblogs.com/blog/1834368/202607/1834368-20260706164608158-851771880.jpg" src="https://img2024.cnblogs.com/blog/1834368/202607/1834368-20260706164608158-851771880.jpg"  medium-zoom-image"="" style="border: 0px; max-width: 100%; height: auto !important; cursor: zoom-in; transition: transform 300ms cubic-bezier(0.2, 0, 0.2, 1) !important;" /></p><p style="margin: 10px auto;"><strong><em>3）</em>RainbowAV集成到<a href="http://www.52im.net/thread-19-1-1.html" target="_blank" rel="noopener nofollow" style="color: #1d58d1; text-decoration: none;">RainbowChat</a> 后的实时视频运行效果：</strong>（<a href="http://www.52im.net/thread-19-1-1.html" target="_blank" rel="noopener nofollow" style="color: #1d58d1; text-decoration: none;">RainbowChat介绍</a>、<a href="http://www.52im.net/thread-20-1-1.html" target="_blank" rel="noopener nofollow" style="color: #1d58d1; text-decoration: none;">更多RainbowChat截图</a>）<br /><img alt="13_real_video" loading="lazy" data-src="https://img2024.cnblogs.com/blog/1834368/202607/1834368-20260706162910553-1710045370.jpg" src="https://img2024.cnblogs.com/blog/1834368/202607/1834368-20260706162910553-1710045370.jpg"  medium-zoom-image"="" style="border: 0px; max-width: 100%; height: auto !important; cursor: zoom-in; transition: transform 300ms cubic-bezier(0.2, 0, 0.2, 1) !important;" /></p></div><div id="MySignature" role="contentinfo" style="font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><div id="AllanboltSignature"></div></div><img src ="http://www.blogjava.net/jb2011/aggbug/451792.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jb2011/" target="_blank">Jack Jiang</a> 2026-08-11 20:38 <a href="http://www.blogjava.net/jb2011/archive/2026/08/11/451792.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>都HTML5了，Web端即时通讯技术到底该用什么？一文即懂！</title><link>http://www.blogjava.net/jb2011/archive/2026/08/04/451791.html</link><dc:creator>Jack Jiang</dc:creator><author>Jack Jiang</author><pubDate>Tue, 04 Aug 2026 10:19:00 GMT</pubDate><guid>http://www.blogjava.net/jb2011/archive/2026/08/04/451791.html</guid><wfw:comment>http://www.blogjava.net/jb2011/comments/451791.html</wfw:comment><comments>http://www.blogjava.net/jb2011/archive/2026/08/04/451791.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jb2011/comments/commentRss/451791.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jb2011/services/trackbacks/451791.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 本文作者京东物流技术团队卢旭，有修订和改动。1、引言在 Web端即时通讯技术的实践开发中，它的核心目标是实现客户端（浏览器）与服务器之间低延迟、双向 / 单向的动态数据交互，而非传统 HTTP 的 &#8220;请求 - 响应&#8221; 模式。本文分享的是 Web 端最常用即时通讯技术（包括 WebSocket、SSE、WebRTC、轮询等）的原理、优缺点与适用场景等，以及生产环境下的高并发场...&nbsp;&nbsp;<a href='http://www.blogjava.net/jb2011/archive/2026/08/04/451791.html'>阅读全文</a><img src ="http://www.blogjava.net/jb2011/aggbug/451791.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jb2011/" target="_blank">Jack Jiang</a> 2026-08-04 18:19 <a href="http://www.blogjava.net/jb2011/archive/2026/08/04/451791.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>基于开源MobileIMSDK框架，即时通讯IM产品RainbowChat v12.1发布</title><link>http://www.blogjava.net/jb2011/archive/2026/07/16/451789.html</link><dc:creator>Jack Jiang</dc:creator><author>Jack Jiang</author><pubDate>Thu, 16 Jul 2026 04:41:00 GMT</pubDate><guid>http://www.blogjava.net/jb2011/archive/2026/07/16/451789.html</guid><wfw:comment>http://www.blogjava.net/jb2011/comments/451789.html</wfw:comment><comments>http://www.blogjava.net/jb2011/archive/2026/07/16/451789.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jb2011/comments/commentRss/451789.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jb2011/services/trackbacks/451789.html</trackback:ping><description><![CDATA[<h1>1、v12.1 版更新内容</h1><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">此版本新增了短信验证码的注册和登录功能，解决了Android 16手机上发送文件失败等问题。<br /><br /><strong>详细更新内容</strong>（<a href="http://www.52im.net/thread-1217-1-1.html" target="_blank" rel="noopener nofollow" style="color: #1d58d1; text-decoration: none;">更多历史更新日志</a>）：</p><ul style="margin-left: 2.5rem; padding-left: 0px; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><li style="list-style: inherit;"><em>1）</em>[<span style="color: #00b050;">新增</span>] 新增了短信验证码的注册和登录功能；</li><li style="list-style: inherit;"><em>2）</em>[<span style="color: #ff4d4e;">bug</span>] 解决了Android 16手机上发送文件失败的问题（系统不允许读取DATE_MODIFIED字段）；</li><li style="list-style: inherit;"><em>3）</em>[<span style="color: #ff4d4e;">bug</span>] 解决了群聊中查看群公告时不显示编辑者头像的问题；</li><li style="list-style: inherit;"><em>4）</em>[<span style="color: #909296;">优化</span>] ui的细节美化和提升（包括图标黑化、标题栏/tab栏白化净化、列表横线净化等等）；</li><li style="list-style: inherit;"><em>5）</em>[<span style="color: #909296;">优化</span>] 优化了聊天界面中未读消息数的ui；</li><li style="list-style: inherit;"><em>6）</em>[<span style="color: #909296;">优化</span>] 个人相册、个人语音、文件查看、视频录制和播放、扫一扫等界面的ui优化；</li><li style="list-style: inherit;"><em>7）</em>[<span style="color: #909296;">优化</span>] 陌生人聊天界面标题栏小字被点击后弹出的提示框中增加了&#8220;加好友&#8221;按钮；</li><li style="list-style: inherit;"><em>8）</em>[<span style="color: #909296;">优化</span>] 解决targetSDKVersion=36时，不支持edge to edge全面屏的老旧手机状态栏跟标题栏颜色不一致的问题；</li><li style="list-style: inherit;"><em>9）</em>[<span style="color: #909296;">优化</span>] 个人中心增加了手机号的显示；</li><li style="list-style: inherit;"><em>10）</em>[<span style="color: #909296;">优化</span>] 视频播放界面增加视频转发功能；</li><li style="list-style: inherit;"><em>11）</em>[<span style="color: #909296;">优化</span>] 优化了查看用户头像的缓存加载逻辑；</li><li style="list-style: inherit;"><em>12）</em>[<span style="color: #909296;">优化</span>] 其它细节优化和提升；</li></ul><h1>2、关于MobileIMSDK开源工程</h1><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><img alt="a1-opti" loading="lazy" data-src="https://img2024.cnblogs.com/blog/1834368/202607/1834368-20260706163936672-1851199590.png" src="https://img2024.cnblogs.com/blog/1834368/202607/1834368-20260706163936672-1851199590.png" lazyloaded=""  medium-zoom-image"="" style="border: 0px; max-width: 100%; height: auto !important; cursor: zoom-in; transition: transform 300ms cubic-bezier(0.2, 0, 0.2, 1) !important;" /></p><div align="left" style="font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><p style="margin: 10px auto;"><strong>MobileIMSDK</strong> 是一套全平台开源IM即时通讯聊天框架，超轻量级、高度提炼，一套API优雅支持<strong>UDP</strong> 、<strong>TCP</strong> 、<strong>WebSocket</strong> 三种协议，客户端支持<strong>iOS、Android、H5、小程序、Uniapp、标准Java、纯血鸿蒙</strong>等，服务端基于Netty编写，性能卓越、易于扩展。</p><p style="margin: 10px auto;"><img alt="3" loading="lazy" data-src="https://img2024.cnblogs.com/blog/1834368/202604/1834368-20260426210620811-1338174721.png" src="https://img2024.cnblogs.com/blog/1834368/202604/1834368-20260426210620811-1338174721.png" lazyloaded=""  medium-zoom-image"="" style="border: 0px; max-width: 100%; height: auto !important; cursor: zoom-in; transition: transform 300ms cubic-bezier(0.2, 0, 0.2, 1) !important;" /></p></div><p data-pid="9Wt-ivaI" style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><strong>工程同步开源地址：</strong></p><ul style="margin-left: 2.5rem; padding-left: 0px; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><li style="list-style: inherit;">❶ <strong>GitHub：</strong><a href="https://github.com/JackJiang2011/MobileIMSDK" rel="noopener nofollow" target="_blank" style="color: #1d58d1; text-decoration: none;">https://github.com/JackJiang2011/MobileIMSDK</a></li><li style="list-style: inherit;">❷ <strong>码云gitee：</strong> <a href="https://gitee.com/jackjiang/MobileIMSDK" rel="noopener nofollow" target="_blank" style="color: #1d58d1; text-decoration: none;">https://gitee.com/jackjiang/MobileIMSDK</a></li><li style="list-style: inherit;">❸ <strong>Gitcode：</strong><a href="https://gitcode.com/hellojackjiang2011/MobileIMSDK" rel="noopener nofollow" target="_blank" style="color: #1d58d1; text-decoration: none;">https://gitcode.com/hellojackjiang2011/MobileIMSDK</a></li></ul><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><strong>仓库文件目录：</strong></p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><strong><img alt="a2-opti" loading="lazy" data-src="https://img2024.cnblogs.com/blog/1834368/202607/1834368-20260706164008917-1395347960.png" src="https://img2024.cnblogs.com/blog/1834368/202607/1834368-20260706164008917-1395347960.png"  medium-zoom-image"="" style="border: 0px; max-width: 100%; height: auto !important; cursor: zoom-in; transition: transform 300ms cubic-bezier(0.2, 0, 0.2, 1) !important;" /></strong></p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><strong>框架详细组成：</strong></p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><strong><img alt="a3-opto" loading="lazy" data-src="https://img2024.cnblogs.com/blog/1834368/202607/1834368-20260706164023803-1061257635.png" src="https://img2024.cnblogs.com/blog/1834368/202607/1834368-20260706164023803-1061257635.png"  medium-zoom-image"="" style="border: 0px; max-width: 100%; height: auto !important; cursor: zoom-in; transition: transform 300ms cubic-bezier(0.2, 0, 0.2, 1) !important;" /></strong></p><h1>3、关于RainbowChat</h1><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">&nbsp;<img alt="1" loading="lazy" data-src="https://img2024.cnblogs.com/blog/1834368/202604/1834368-20260426210602156-1614496586.jpg" src="https://img2024.cnblogs.com/blog/1834368/202604/1834368-20260426210602156-1614496586.jpg"  medium-zoom-image"="" style="border: 0px; max-width: 100%; height: auto !important; cursor: zoom-in; transition: transform 300ms cubic-bezier(0.2, 0, 0.2, 1) !important;" /></p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">🔥⚡️ <a href="http://www.52im.net/thread-19-1-1.html" rel="noopener nofollow" style="color: #1d58d1; text-decoration: none;">详细介绍</a>・<a href="http://www.52im.net/thread-2735-1-1.html" rel="noopener nofollow" style="color: #1d58d1; text-decoration: none;">版本日志</a>・运行截图(<a href="http://www.52im.net/thread-20-1-1.html" rel="noopener nofollow" style="color: #1d58d1; text-decoration: none;">Android</a>、<a href="http://www.52im.net/thread-2730-1-1.html" rel="noopener nofollow" style="color: #1d58d1; text-decoration: none;">iOS</a>)・下载体验(<a href="http://www.52im.net/thread-4739-1-1.html" rel="noopener nofollow" style="color: #1d58d1; text-decoration: none;">Android</a>、<a href="https://apps.apple.com/cn/app/rainbowchat/id1423024212" rel="noopener nofollow" style="color: #1d58d1; text-decoration: none;">iOS</a>) ⚡️🔥</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">RainbowChat是一套基于开源IM即时通讯聊天框架 <a href="http://www.52im.net/thread-52-1-1.html" rel="noopener nofollow" target="_blank" style="color: #1d58d1; text-decoration: none;">MobileIMSDK</a> 的<strong>产品级移动端IM系统</strong>。<strong>RainbowChat源于真实运营的产</strong>品，解决了大量的屏幕适配、细节优化、机器兼容问题。<strong>RainbowChat可能是市面上提供im即时通讯聊天源码的，唯一一款同时支持TCP、UDP、WebSocket三种通信协议的IM产品</strong>。与姊妹产品 <a href="http://www.52im.net/thread-4824-1-1.html" rel="noopener nofollow" target="_blank" style="color: #1d58d1; text-decoration: none;">RainbowTalk</a> 和 <a href="http://www.52im.net/thread-2483-1-1.html" rel="noopener nofollow" target="_blank" style="color: #1d58d1; text-decoration: none;">RainbowChat-Web</a> 技术同源，历经考验。</p><ul style="margin-left: 2.5rem; padding-left: 0px; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><li style="list-style: inherit;"><strong><strong>&#9758;</strong> 详细介绍：</strong><a href="http://www.52im.net/thread-19-1-1.html" rel="noopener nofollow" target="_blank" style="color: #1d58d1; text-decoration: none;">http://www.52im.net/thread-19-1-1.html</a></li><li style="list-style: inherit;"><strong><strong>&#9758;</strong> 版本日志：</strong><a href="http://www.52im.net/thread-2735-1-1.html" rel="noopener nofollow" target="_blank" style="color: #1d58d1; text-decoration: none;">http://www.52im.net/thread-2735-1-1.html</a></li><li style="list-style: inherit;"><strong><strong>&#9758;</strong> 运行截图：</strong><a href="http://www.52im.net/thread-20-1-1.html" rel="noopener nofollow" target="_blank" style="color: #1d58d1; text-decoration: none;">Android端</a>、<a href="http://www.52im.net/thread-2730-1-1.html" rel="noopener nofollow" target="_blank" style="color: #1d58d1; text-decoration: none;">iOS端</a></li><li style="list-style: inherit;"><strong><strong>&#9758;</strong> 下载体验：</strong><a href="https://apps.apple.com/cn/app/rainbowchat/id1423024212" rel="noopener nofollow" target="_blank" style="color: #1d58d1; text-decoration: none;">App Store安装地址</a> （另：Android端下载体验 <a href="http://www.52im.net/thread-4739-1-1.html" rel="noopener nofollow" target="_blank" style="color: #1d58d1; text-decoration: none;">点此查看</a>）</li></ul><h1>4、<strong>运行截图</strong></h1><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><strong>主要功能运行截图：</strong>（&#9758; <a href="http://www.52im.net/thread-20-1-1.html" target="_blank" rel="noopener nofollow" style="color: #1d58d1; text-decoration: none;">Android端完整截图</a>、<a href="http://www.52im.net/thread-2730-1-1.html" target="_blank" rel="noopener nofollow" style="color: #1d58d1; text-decoration: none;">iOS端完整截图</a>）&nbsp;</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><img alt="12_real_voice" loading="lazy" data-src="https://img2024.cnblogs.com/blog/1834368/202607/1834368-20260706164608158-851771880.jpg" src="https://img2024.cnblogs.com/blog/1834368/202607/1834368-20260706164608158-851771880.jpg" medium-zoom-image=""  lazyloaded"="" style="border: 0px; max-width: 100%; height: auto !important; cursor: zoom-in; transition: transform 300ms cubic-bezier(0.2, 0, 0.2, 1) !important;" /></p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><img alt="13_real_video" loading="lazy" data-src="https://img2024.cnblogs.com/blog/1834368/202607/1834368-20260706162910553-1710045370.jpg" src="https://img2024.cnblogs.com/blog/1834368/202607/1834368-20260706162910553-1710045370.jpg" medium-zoom-image=""  lazyloaded"="" style="border: 0px; max-width: 100%; height: auto !important; cursor: zoom-in; transition: transform 300ms cubic-bezier(0.2, 0, 0.2, 1) !important;" /></p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><img alt="27_revoke_e" loading="lazy" data-src="https://img2024.cnblogs.com/blog/1834368/202607/1834368-20260706162924954-1781243812.jpg" src="https://img2024.cnblogs.com/blog/1834368/202607/1834368-20260706162924954-1781243812.jpg" medium-zoom-image=""  lazyloaded"="" style="border: 0px; max-width: 100%; height: auto !important; cursor: zoom-in; transition: transform 300ms cubic-bezier(0.2, 0, 0.2, 1) !important;" /></p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><strong>全部功能拼合大图：</strong>（&#9758; <a href="http://www.52im.net/thread-20-1-1.html" target="_blank" rel="noopener nofollow" style="color: #1d58d1; text-decoration: none;"><span style="color: #0078fe;">点此查看清晰原图</span></a>）</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><img alt="v121_all_in_one_75pct_h2000px" loading="lazy" data-src="https://img2024.cnblogs.com/blog/1834368/202607/1834368-20260706162801472-2142212900.jpg" src="https://img2024.cnblogs.com/blog/1834368/202607/1834368-20260706162801472-2142212900.jpg"  medium-zoom-image"="" style="border: 0px; max-width: 100%; height: auto !important; cursor: zoom-in; transition: transform 300ms cubic-bezier(0.2, 0, 0.2, 1) !important;" /></p><h1>5、运行视频</h1><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">（&#9758; <a href="https://www.bilibili.com/video/BV1GfTD6nEWG/" target="_blank" rel="noopener nofollow" style="color: #1d58d1; text-decoration: none;">新窗口中查看运行视频</a>）</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><img alt="动态截图" loading="lazy" data-src="https://img2024.cnblogs.com/blog/1834368/202607/1834368-20260706162023013-1185320081.gif" src="https://img2024.cnblogs.com/blog/1834368/202607/1834368-20260706162023013-1185320081.gif" medium-zoom-image=""  lazyloaded"="" style="border: 0px; max-width: 100%; height: auto !important; cursor: zoom-in; transition: transform 300ms cubic-bezier(0.2, 0, 0.2, 1) !important;" /></p><img src ="http://www.blogjava.net/jb2011/aggbug/451789.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jb2011/" target="_blank">Jack Jiang</a> 2026-07-16 12:41 <a href="http://www.blogjava.net/jb2011/archive/2026/07/16/451789.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>IM千人群聊该不该用消息写扩散？详细算算成本账！</title><link>http://www.blogjava.net/jb2011/archive/2026/06/24/451788.html</link><dc:creator>Jack Jiang</dc:creator><author>Jack Jiang</author><pubDate>Wed, 24 Jun 2026 09:18:00 GMT</pubDate><guid>http://www.blogjava.net/jb2011/archive/2026/06/24/451788.html</guid><wfw:comment>http://www.blogjava.net/jb2011/comments/451788.html</wfw:comment><comments>http://www.blogjava.net/jb2011/archive/2026/06/24/451788.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jb2011/comments/commentRss/451788.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jb2011/services/trackbacks/451788.html</trackback:ping><description><![CDATA[<p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">本文作者拉丁解牛说技术，有修订和改动。</p><h1>1、引言</h1><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">本文将为你详解 IM 群聊消息的写扩散技术原理以及写扩散过程中的服务端详细性能成本，同时对比了市面上IM大厂的技术方案，给出分规模架构选型与以及性能优化策略等。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><img alt="cover-opti" loading="lazy" data-src="https://img2024.cnblogs.com/blog/1834368/202606/1834368-20260622205028744-1814609697.jpg" src="https://img2024.cnblogs.com/blog/1834368/202606/1834368-20260622205028744-1814609697.jpg" lazyloaded=""  medium-zoom-image"="" style="border: 0px; max-width: 100%; height: auto !important; cursor: zoom-in; transition: transform 300ms cubic-bezier(0.2, 0, 0.2, 1) !important;" /></p><h1>2、技术背景</h1><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">某天下午，你在一个 1000 人的项目群里发了一条 7 个字的消息：「今晚九点发版」。对你来说，这是一次点击、一段 7 字符的字符串、一次"已发送"的小对勾。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">但服务端为这条消息做了什么？</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><strong>按写扩散（Fan-out on Write）的实现思路，最直观的版本是这样的：</strong></p><div style="font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><img alt="0" loading="lazy" data-src="https://img2024.cnblogs.com/blog/1834368/202606/1834368-20260622205034690-381567404.jpg" src="https://img2024.cnblogs.com/blog/1834368/202606/1834368-20260622205034690-381567404.jpg" lazyloaded=""  medium-zoom-image"="" style="border: 0px; max-width: 100%; height: auto !important; cursor: zoom-in; transition: transform 300ms cubic-bezier(0.2, 0, 0.2, 1) !important;" /></div><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">仅消息副本本身就是 999 次扇出。加上路由查询、未读写入、三方推送触发，一条 7 字消息在服务端产生 3000~5000 次后端操作不是夸张。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">这就是"写扩散"这个词背后的真实账单。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><img alt="1" loading="lazy" data-src="https://img2024.cnblogs.com/blog/1834368/202606/1834368-20260622205041227-1542680421.png" src="https://img2024.cnblogs.com/blog/1834368/202606/1834368-20260622205041227-1542680421.png" lazyloaded=""  medium-zoom-image"="" style="border: 0px; max-width: 100%; height: auto !important; cursor: zoom-in; transition: transform 300ms cubic-bezier(0.2, 0, 0.2, 1) !important;" /></p><div style="font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">&nbsp;</div><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><span style="color: #888888;">&#9650; 群消息的扇出位置（群服务是「1 &#8594; N」的关键）</span></p><h1>3、群聊消息为什么要做扇出？</h1><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><strong>群消息这个功能在工程上有两条出路：</strong></p><div style="font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><img alt="2" loading="lazy" data-src="https://img2024.cnblogs.com/blog/1834368/202606/1834368-20260622205047638-907912165.png" src="https://img2024.cnblogs.com/blog/1834368/202606/1834368-20260622205047638-907912165.png" lazyloaded=""  medium-zoom-image"="" style="border: 0px; max-width: 100%; height: auto !important; cursor: zoom-in; transition: transform 300ms cubic-bezier(0.2, 0, 0.2, 1) !important;" /></div><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">中小 toB 项目大多选写扩散，因为 toB 场景里"已读回执 / 消息撤回 / 离线补全"是硬需求 &#8212; 没有每成员维度的"投递记录"，这三个功能都立不住。</p><h1>4、中小规横IM项目的典型设计目标</h1><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><strong>中小规模 toB IM 项目里，群消息扇出这一层通常要同时满足：</strong></p><ul style="margin-left: 2.5rem; padding-left: 0px; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><li style="list-style: inherit;"><em>1）</em>实时性：在线成员从发送到收到 P95 &lt; 100ms；</li><li style="list-style: inherit;"><em>2）</em>可靠性：离线成员上线后必须能补到这条消息；</li><li style="list-style: inherit;"><em>3）</em>可观测：每个副本的投递状态可追踪（用于 SRE 排障）；</li><li style="list-style: inherit;"><em>4）</em>业务能力：支撑已读回执、消息撤回、漫游、未读统计；</li><li style="list-style: inherit;"><em>5）</em>规模：单群默认 1000 人，少数业务场景 3000~5000 人。</li></ul><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">这些约束串起来，几乎一定走向写扩散。</p><h1>5、写扩散的消息副本生成时机</h1><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><strong>候选 3 种：</strong></p><div style="font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><img alt="3" loading="lazy" data-src="https://img2024.cnblogs.com/blog/1834368/202606/1834368-20260622205053097-1029188469.png" src="https://img2024.cnblogs.com/blog/1834368/202606/1834368-20260622205053097-1029188469.png" lazyloaded=""  medium-zoom-image"="" style="border: 0px; max-width: 100%; height: auto !important; cursor: zoom-in; transition: transform 300ms cubic-bezier(0.2, 0, 0.2, 1) !important;" /></div><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><strong>主流选择：</strong>群服务展开。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><strong>理由是：</strong>责任边界清晰 &#8212; 群成员、群属性、群配置全在群服务，扇出本来就应该是它的活。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><strong>伪代码大致是这样：</strong></p><blockquote style="background-image: none; border-width: medium medium medium 3px; border-style: none none none solid; border-color: currentcolor currentcolor currentcolor #e2dfdf; margin: 10px 0px; background-color: #eeeeee; width: 896px; color: #555555; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif;"><p style="margin: 10px auto;">on_group_message_arrive(msg):</p><p style="margin: 10px auto;">&nbsp;&nbsp;&nbsp;&nbsp;group = group_cache.load(msg.group_id)</p><p style="margin: 10px auto;">&nbsp;&nbsp;&nbsp;&nbsp;members = group.member_list # 1000 人</p><p style="margin: 10px auto;">&nbsp;&nbsp;&nbsp;&nbsp;members = filter_out_sender(members, msg.from) # 999 人</p><p style="margin: 10px auto;">&nbsp;&nbsp;&nbsp;&nbsp;for member in members:</p><p style="margin: 10px auto;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;copy = clone_with_target(msg, member.uid)</p><p style="margin: 10px auto;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;copy.uuid = msg.uuid + "|G" + member.short_id // 副本标识</p><p style="margin: 10px auto;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;publish_to_dispatcher(copy)</p></blockquote><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">注意最后那个 uuid + "|G" + member.short_id &#8212; 这是写扩散里的"副本指纹"，下游所有组件（历史库、离线、已读聚合）都靠这个区分"原消息"和"副本"。</p><h1>6、扇出执行方式</h1><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><strong>这是最容易踩坑的设计点。3 种执行方式的对比：</strong></p><div style="font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><img alt="4" loading="lazy" data-src="https://img2024.cnblogs.com/blog/1834368/202606/1834368-20260622205106796-1169789639.png" src="https://img2024.cnblogs.com/blog/1834368/202606/1834368-20260622205106796-1169789639.png" lazyloaded=""  medium-zoom-image"="" style="border: 0px; max-width: 100%; height: auto !important; cursor: zoom-in; transition: transform 300ms cubic-bezier(0.2, 0, 0.2, 1) !important;" /></div><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">中小项目早期常见的姿势是异步 MQ 逐条 &#8212; 简单、容易实现、文档好查。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">但当群规模到 1000 人级别时，MQ 写入次数会成为系统瓶颈：</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">单条 MQ 写入耗时 ~1~3ms，999 条串行 &#8776; 1~3 秒；并行能压到 100ms 内，但 broker 压力大</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">如果有 100 个千人群同时活跃，MQ broker 每秒要接收 ~10 万条扇出消息</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><strong>改进方向：</strong>MQ 批量化。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><strong>把 999 个目标用户分成 20 批，每批 50 人装在一条 MQ 消息里：</strong></p><blockquote style="background-image: none; border-width: medium medium medium 3px; border-style: none none none solid; border-color: currentcolor currentcolor currentcolor #e2dfdf; margin: 10px 0px; background-color: #eeeeee; width: 896px; color: #555555; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif;"><p style="margin: 10px auto;">on_group_message_arrive(msg):</p><p style="margin: 10px auto;">&nbsp;&nbsp;&nbsp;&nbsp;members = filter_out_sender(group.member_list, msg.from)</p><p style="margin: 10px auto;">&nbsp;&nbsp;&nbsp;&nbsp;for batch in chunk(members, batch_size=50): // 50 人一批</p><p style="margin: 10px auto;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;batch_msg = {</p><p style="margin: 10px auto;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"origin": msg,</p><p style="margin: 10px auto;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"targets": [m.uid for m in batch]</p><p style="margin: 10px auto;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}</p><p style="margin: 10px auto;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;publish_to_dispatcher(batch_msg) // 一次 MQ 写</p></blockquote><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">下游分发服务消费时再"展开"批次，对批内每个目标做路由 + 投递。MQ 写次数从 999 降到 ~20，吞吐能力提升一个数量级。</p><h1>7、副本指纹与双轨存储</h1><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">写扩散的一个隐蔽问题是：副本要不要进历史库？</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><strong>该怎么选？</strong></p><ul style="margin-left: 2.5rem; padding-left: 0px; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><li style="list-style: inherit;"><em>1）</em>进：千人群 1 条消息进历史库 999 条，分表空间爆炸</li><li style="list-style: inherit;"><em>2）</em>不进：那历史消息只存原消息，未读 / 已读怎么对账？</li></ul><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><strong>主流做法是双轨：</strong></p><div style="font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><img alt="5" loading="lazy" data-src="https://img2024.cnblogs.com/blog/1834368/202606/1834368-20260622205118858-167512196.png" src="https://img2024.cnblogs.com/blog/1834368/202606/1834368-20260622205118858-167512196.png" lazyloaded=""  medium-zoom-image"="" style="border: 0px; max-width: 100%; height: auto !important; cursor: zoom-in; transition: transform 300ms cubic-bezier(0.2, 0, 0.2, 1) !important;" /></div><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><span style="color: #888888;">&#9650; 写扩散的双轨存储：历史库只有 1 条，离线盒子可能有 N 条</span></p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><strong>判断规则：</strong></p><div style="font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><img alt="6" loading="lazy" data-src="https://img2024.cnblogs.com/blog/1834368/202606/1834368-20260622205125299-345106988.png" src="https://img2024.cnblogs.com/blog/1834368/202606/1834368-20260622205125299-345106988.png" lazyloaded=""  medium-zoom-image"="" style="border: 0px; max-width: 100%; height: auto !important; cursor: zoom-in; transition: transform 300ms cubic-bezier(0.2, 0, 0.2, 1) !important;" /></div><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">历史库消费者扫一眼 uuid 里有没有 |G 就知道丢弃还是入库。这是工程上极简但关键的判断。</p><h1>8、写扩散场景下的失败处理</h1><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><strong>写扩散场景下，"完全成功"是个奢侈品。需要承认部分失败常态，设计要点如下。</strong></p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><strong><em>1）</em></strong>失败必须可重试：副本本身就是 MQ 消息，失败 = 不 ACK，broker 自动重投。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><strong><em>2）</em></strong>重试要有上限：重试 3~5 次仍失败的进死信队列，由 SRE 人工处理。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><strong><em>3）</em></strong>不让发送方感知：发送方在原消息入库时就 ACK 了（"消息已发送"），扇出失败是后台事故，不回传到发送方。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><strong><em>4）</em></strong>失败可定位：每个副本带原消息 uuid + 目标 uid，死信里能精确知道"哪条消息没投到哪个人"。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><strong>伪代码：</strong></p><blockquote style="background-image: none; border-width: medium medium medium 3px; border-style: none none none solid; border-color: currentcolor currentcolor currentcolor #e2dfdf; margin: 10px 0px; background-color: #eeeeee; width: 896px; color: #555555; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif;"><p style="margin: 10px auto;">on_dispatcher_consume(copy_msg):</p><p style="margin: 10px auto;">&nbsp;&nbsp;&nbsp;&nbsp;try:</p><p style="margin: 10px auto;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;route_and_deliver(copy_msg)</p><p style="margin: 10px auto;">&nbsp;&nbsp;&nbsp;&nbsp;except RetryableError as e:</p><p style="margin: 10px auto;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if copy_msg.retry_count &lt; 5:</p><p style="margin: 10px auto;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;reject_and_requeue(copy_msg) // MQ 重投</p><p style="margin: 10px auto;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else:</p><p style="margin: 10px auto;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;send_to_dead_letter_queue(copy_msg) // 死信，SRE 处理</p><p style="margin: 10px auto;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;metrics.inc("group.fanout.dead_letter")</p><p style="margin: 10px auto;">&nbsp;&nbsp;&nbsp;&nbsp;except FatalError as e:</p><p style="margin: 10px auto;">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;send_to_dead_letter_queue(copy_msg)</p></blockquote><h1>9、按群规模进行分档</h1><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">写扩散有个无法跨越的物理上限：群越大，扇出代价越接近不可承受。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><strong>具体是：</strong></p><ul style="margin-left: 2.5rem; padding-left: 0px; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><li style="list-style: inherit;"><em>1）</em>100 人群：100 次副本，舒服；</li><li style="list-style: inherit;"><em>2）</em>1000 人群：999 次副本，已经要做批量化；</li><li style="list-style: inherit;"><em>3）</em>5000 人群：4999 次副本，需要专门优化策略；</li><li style="list-style: inherit;"><em>4）</em>10000 人群：写扩散根本走不通。</li></ul><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">工程上必须明确一条线：超过 N 人的群切换策略。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><strong>主流做法：</strong></p><div style="font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><img alt="7" loading="lazy" data-src="https://img2024.cnblogs.com/blog/1834368/202606/1834368-20260622205131581-344784550.png" src="https://img2024.cnblogs.com/blog/1834368/202606/1834368-20260622205131581-344784550.png" lazyloaded=""  medium-zoom-image"="" style="border: 0px; max-width: 100%; height: auto !important; cursor: zoom-in; transition: transform 300ms cubic-bezier(0.2, 0, 0.2, 1) !important;" /></div><h1>10、群消息扇出的时序流程</h1><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><strong>把上面 5 个设计点串起来：</strong></p><div style="font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><img alt="8" loading="lazy" data-src="https://img2024.cnblogs.com/blog/1834368/202606/1834368-20260622205141253-801372954.png" src="https://img2024.cnblogs.com/blog/1834368/202606/1834368-20260622205141253-801372954.png" lazyloaded=""  medium-zoom-image"="" style="border: 0px; max-width: 100%; height: auto !important; cursor: zoom-in; transition: transform 300ms cubic-bezier(0.2, 0, 0.2, 1) !important;" /></div><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><span style="color: #888888;">&#9650; 群消息扇出的完整时序</span></p><h1>11、主流大厂的大群消息投递方案</h1><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><img alt="9" loading="lazy" data-src="https://img2024.cnblogs.com/blog/1834368/202606/1834368-20260622205146938-242315385.png" src="https://img2024.cnblogs.com/blog/1834368/202606/1834368-20260622205146938-242315385.png" lazyloaded=""  medium-zoom-image"="" style="border: 0px; max-width: 100%; height: auto !important; cursor: zoom-in; transition: transform 300ms cubic-bezier(0.2, 0, 0.2, 1) !important;" /></p><div style="font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">&nbsp;</div><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">不同体量的 IM 系统在这一层的设计差异极大。写扩散不是唯一解 &#8212; 当规模到某个临界点，读扩散反而是更合理的选择。</p><h2>11.1 某钉IM</h2><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">钉IM，最早也走写扩散，但在万人群场景下扛不住，演进为读扩散为主 + 推拉结合 + 多级缓存。（相关资料请详读《深度解密钉钉即时消息服务DTIM的技术设计》一文中的&#8220;4.3、存储模型设计&#8221;章节）</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><strong>核心思路：</strong></p><ul style="margin-left: 2.5rem; padding-left: 0px; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><li style="list-style: inherit;"><em>1）</em>群消息只存一份（不再为每个成员复制）；</li><li style="list-style: inherit;"><em>2）</em>成员"读群"时按订阅关系拉取；</li><li style="list-style: inherit;"><em>3）</em>实时性靠"近期消息推送 + 历史消息客户端按需拉取"补足；</li><li style="list-style: inherit;"><em>4）</em>多级缓存（万人群成员缓存）让"反查群成员"快到毫秒级。</li></ul><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><img alt="10" loading="lazy" data-src="https://img2024.cnblogs.com/blog/1834368/202606/1834368-20260622205155047-1467411197.png" src="https://img2024.cnblogs.com/blog/1834368/202606/1834368-20260622205155047-1467411197.png" lazyloaded=""  medium-zoom-image"="" style="border: 0px; max-width: 100%; height: auto !important; cursor: zoom-in; transition: transform 300ms cubic-bezier(0.2, 0, 0.2, 1) !important;" /></p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><span style="color: #888888;">&#9650; 最终：他们用智能限流和万人群成员多级缓存来支撑超级大群的运营</span></p><h2>11.2 某信IM架构</h2><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">在群消息"存一份还是存多份"的存储架构权衡上，相关高级研发工程师在技术博客分享中提到，采用写扩散路线（详见《微信直播聊天室单房间1500万在线的消息架构演进之》一文中的&#8220;5、消息扩散方案选型：读扩散&#8221;章节）。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">即每条群消息按成员数复制成多份存储，换取读路径的极致简单（撤回、漫游、未读计数都只需操作单成员的消息流）。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">代价是写放大与存储成本随群规模线性上涨。</p><div style="font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><img alt="11" loading="lazy" data-src="https://img2024.cnblogs.com/blog/1834368/202606/1834368-20260622205202092-1543158627.png" src="https://img2024.cnblogs.com/blog/1834368/202606/1834368-20260622205202092-1543158627.png" lazyloaded=""  medium-zoom-image"="" style="border: 0px; max-width: 100%; height: auto !important; cursor: zoom-in; transition: transform 300ms cubic-bezier(0.2, 0, 0.2, 1) !important;" /></div><h2>11.3 企某信的IM架构</h2><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">企某信和总所周知的微信，是两个系统，企某信的设计目标是支持万人群 + 已读回执。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">它的做法是：仍然走写扩散，但投入更多硬件资源 + 各种局部优化（批量、缓存、异步）来支撑万人群的扇出成本。（相关资料可详读《企业微信的IM架构设计揭秘》一文中的&#8220;6、整体架构设计3：消息扩散写&#8221;章节）</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><img alt="12" loading="lazy" data-src="https://img2024.cnblogs.com/blog/1834368/202606/1834368-20260622205208390-853590937.png" src="https://img2024.cnblogs.com/blog/1834368/202606/1834368-20260622205208390-853590937.png" lazyloaded=""  medium-zoom-image"="" style="border: 0px; max-width: 100%; height: auto !important; cursor: zoom-in; transition: transform 300ms cubic-bezier(0.2, 0, 0.2, 1) !important;" /></p><h2>11.4 总结对比</h2><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><img alt="13" loading="lazy" data-src="https://img2024.cnblogs.com/blog/1834368/202606/1834368-20260622205213465-1782053107.png" src="https://img2024.cnblogs.com/blog/1834368/202606/1834368-20260622205213465-1782053107.png" lazyloaded=""  medium-zoom-image"="" style="border: 0px; max-width: 100%; height: auto !important; cursor: zoom-in; transition: transform 300ms cubic-bezier(0.2, 0, 0.2, 1) !important;" /></p><h1>12、性能优化思考</h1><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">中小规模 toB IM 在群扇出这一层有一条清晰的演进路径 &#8212; 但具体怎么走，要从你的产品定位、规模分布、工程团队能力倒推。下面是几个值得反复思考的点。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><strong><em>1）</em></strong>群规模上限：你的产品定位决定了上限的硬约束。如果业务场景就是大企业、需要万人群（如政府客户、大型集团内部沟通），那从 day 1 就应该认真评估读扩散方案 &#8212; 等到业务跑起来再切，技术债的复利会让人后悔。但如果只是一个中小企业协作工具，500 人甚至 1000 人上限其实没问题（参考微信群限制 500 人的判断）。先决定群规模的产品上限，再决定架构 &#8212; 这个顺序反过来就麻烦。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><strong><em>2）</em></strong>MQ 批量化：观察过的几乎所有中小规模 toB IM 项目都在 MQ broker 上付过血泪学费。Broker 的瓶颈往往不是磁盘 IO，而是连接数和单 partition 的串行化处理。批量化（batch=20~50）能让 MQ 写入次数降一个数量级，是收益明显的优化方向。但要注意批量化引入的复杂性 &#8212; 一批 50 个目标，其中 3 个失败该怎么处理？个人在中等规模 IM 项目里观察到的常见做法是"批内失败拆分重投"（把失败的 3 个重新打包成新的小批次发回 MQ）。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><strong><em>3）</em></strong>副本瘦身：副本带不带完整 payload 是个分歧点。带 payload 简单（下游消费者不需要反查原消息）但浪费带宽（千人群 1 条 1KB 消息 = 1MB 流量）；不带 payload 省带宽但下游消费者要做一次 KV 反查。比"完全瘦身"更工程化的做法是分档：消息体 &lt; 1KB 时带 payload；超过就拆 &#8212; 副本只带 uid + uuid + 摘要（首 100 字符做消息预览），下游展开时按 uuid 反查全文。这种"内嵌摘要 + 按需反查"的混合方案，既能保留消息列表的预览体验，又能控制带宽峰值。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><strong><em>4）</em></strong>可观测体系：很多中小项目的扇出层处于"出问题时翻日志、平时不看"的状态，这是个隐患 &#8212; 当你发现"群消息延迟变高"时，往往已经在客服工单里出现了。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">最值得加的三个指标分别是：</p><ul style="margin-left: 2.5rem; padding-left: 0px; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><li style="list-style: inherit;"><em>a）</em>单条群消息的扇出 RT P99（衡量端到端时长，是不是有慢扇出）；</li><li style="list-style: inherit;"><em>b）</em>副本投递失败率按时间窗口分桶（衡量是否有阶段性故障）；</li><li style="list-style: inherit;"><em>c）</em>批内部分失败率（如果做了批量化，衡量批是不是被"少数失败拖累整批"）。</li></ul><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">这三个指标加起来，P0 故障定位时间能从"翻半小时日志"压缩到"看一眼大盘"。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><em>5）</em>大群临界点：如果业务真的开始需要 5000 人以上的群，参考某钉从写扩散切到读扩散的演进经验，关键经验是 &#8212; 切换不是一蹴而就的。中间过渡期通常是混合模式：千人以下继续写扩散（保留已读 / 撤回的低成本实现），千人以上的群单独走读扩散通道（客户端读消息时按 uuid 范围拉取，已读用 bitmap 聚合）。这种"按规模分流"的混合策略可以让团队渐进切换，不需要一刀切的大重构。关键是分流的判断点要明确（在群创建时就标记类型），而不是在每次消息扇出时动态判断 &#8212; 后者会让代码路径越来越复杂。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">写扩散不是终点，是某个规模下的最优解。真正的工程能力，是知道什么时候该走，什么时候该停。</p><h1>13、参考资料</h1><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">[1] IM单聊和群聊中的在线状态同步应该用&#8220;推&#8221;还是&#8220;拉&#8221;？</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">[2] IM群聊消息如此复杂，如何保证不丢不重？</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">[3] 移动端IM中大规模群消息的推送如何保证效率、实时性？</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">[4] 现代IM系统中聊天消息的同步和存储方案探讨</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">[5] 关于IM即时通讯群聊消息的乱序问题讨论</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">[6] IM群聊消息的已读回执功能该怎么实现？</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">[7] IM群聊消息究竟是存1份(即扩散读)还是存多份(即扩散写)？</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">[8] 一套高可用、易伸缩、高并发的IM群聊、单聊架构方案设计实践</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">[10] IM群聊机制，除了循环去发消息还有什么方式？如何优化？</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">[11] 云信技术分享：IM中的万人群聊技术方案实践总结</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">[13] IM群聊消息的已读未读功能在存储空间方面的实现思路探讨</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">[15] 企微的IM架构设计揭秘：消息模型、万人群、已读回执、消息撤回等</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">[16] 融云IM技术分享：万人群聊消息投递方案的思考和实践</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">[18] 海量用户IM聊天室的架构设计与实践</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">[20] 支持百万人超大群聊的Web端IM架构设计与实践</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">[21] IM千人群聊该不该用消息写扩散？详细算算成本账！</p><blockquote style="background-image: none; border-width: medium medium medium 3px; border-style: none none none solid; border-color: currentcolor currentcolor currentcolor #e2dfdf; margin: 10px 0px; background-color: #eeeeee; width: 896px; color: #555555; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif;"><p style="margin: 10px auto;"><strong>即时通讯技术学习：</strong></p><p style="margin: 10px auto;">- 移动端IM开发入门文章：《<a href="http://www.52im.net/thread-464-1-1.html" rel="noopener nofollow" target="_blank" style="color: #1d58d1; text-decoration: none;">新手入门一篇就够：从零开发移动端IM</a>》</p><p style="margin: 10px auto;">- 开源IM框架源码：<a href="https://github.com/JackJiang2011/MobileIMSDK" rel="noopener nofollow" target="_blank" style="color: #1d58d1; text-decoration: none;">https://github.com/JackJiang2011/MobileIMSDK</a>（<a href="https://gitee.com/jackjiang/MobileIMSDK" rel="noopener nofollow" target="_blank" style="color: #1d58d1; text-decoration: none;">备用地址点此</a>）</p></blockquote><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">（本文同步发布于： <a href="http://www.52im.net/thread-4915-1-1.html" target="_blank" rel="noopener nofollow" style="color: #1d58d1; text-decoration: none;">http://www.52im.net/thread-4915-1-1.html</a>）</p><img src ="http://www.blogjava.net/jb2011/aggbug/451788.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jb2011/" target="_blank">Jack Jiang</a> 2026-06-24 17:18 <a href="http://www.blogjava.net/jb2011/archive/2026/06/24/451788.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>直播系统聊天技术(十)：基于实时消息总线的活动系统架构设计</title><link>http://www.blogjava.net/jb2011/archive/2026/06/08/451786.html</link><dc:creator>Jack Jiang</dc:creator><author>Jack Jiang</author><pubDate>Mon, 08 Jun 2026 03:52:00 GMT</pubDate><guid>http://www.blogjava.net/jb2011/archive/2026/06/08/451786.html</guid><wfw:comment>http://www.blogjava.net/jb2011/comments/451786.html</wfw:comment><comments>http://www.blogjava.net/jb2011/archive/2026/06/08/451786.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jb2011/comments/commentRss/451786.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jb2011/services/trackbacks/451786.html</trackback:ping><description><![CDATA[<p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">本文由云音乐技术团队燕十三分享，有修订和改动。</p><h1>1、引言</h1><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">本文分享的是网易云音乐技术团队基于实时消息总线技术，解决了直播活动系统的模块灵活组合、消息治理与异步履约等问题，希望能给你带来启发。</p><div img-uploading-status=""  image-package-1"="" data-index="1" style="font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><div><div><img alt="cover-opti" loading="lazy" data-src="https://img2024.cnblogs.com/blog/1834368/202606/1834368-20260607220850523-776800620.png" src="https://img2024.cnblogs.com/blog/1834368/202606/1834368-20260607220850523-776800620.png"  medium-zoom-image"="" style="border: 0px; max-width: 100%; height: auto !important; cursor: zoom-in; transition: transform 300ms cubic-bezier(0.2, 0, 0.2, 1) !important;" /></div></div></div><h1>2、系列文章</h1><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><strong>本文是系列文章中的第 <em>10</em> 篇：</strong></p><ol style="margin-left: 2.5rem; padding-left: 0px; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><li style="list-style: inherit;">《<a href="http://www.52im.net/thread-1236-1-1.html" target="_blank" rel="noopener nofollow" style="color: #1d58d1; text-decoration: none;">直播系统聊天技术(一)：百万在线的美拍直播弹幕系统的实时推送技术实践之路</a>》</li><li style="list-style: inherit;">《<a href="http://www.52im.net/thread-3252-1-1.html" target="_blank" rel="noopener nofollow" style="color: #1d58d1; text-decoration: none;">直播系统聊天技术(二)：阿里电商IM消息平台，在群聊、直播场景下的技术实践</a>》</li><li style="list-style: inherit;">《<a href="http://www.52im.net/thread-3376-1-1.html" target="_blank" rel="noopener nofollow" style="color: #1d58d1; text-decoration: none;">直播系统聊天技术(三)：微信直播聊天室单房间1500万在线的消息架构演进之路</a>》</li><li style="list-style: inherit;">《<a href="http://www.52im.net/thread-3515-1-1.html" target="_blank" rel="noopener nofollow" style="color: #1d58d1; text-decoration: none;">直播系统聊天技术(四)：百度直播的海量用户实时消息系统架构演进实践</a>》</li><li style="list-style: inherit;">《<a href="http://www.52im.net/thread-3594-1-1.html" target="_blank" rel="noopener nofollow" style="color: #1d58d1; text-decoration: none;">直播系统聊天技术(五)：微信小游戏直播在Android端的跨进程渲染推流实践</a>》</li><li style="list-style: inherit;">《<a href="http://www.52im.net/thread-3799-1-1.html" target="_blank" rel="noopener nofollow" style="color: #1d58d1; text-decoration: none;">直播系统聊天技术(六)：百万人在线的直播间实时聊天消息分发技术实践</a>》</li><li style="list-style: inherit;">《<a href="http://www.52im.net/thread-3835-1-1.html" target="_blank" rel="noopener nofollow" style="color: #1d58d1; text-decoration: none;">直播系统聊天技术(七)：直播间海量聊天消息的架构设计难点实践</a>》</li><li style="list-style: inherit;">《<a href="http://www.52im.net/thread-3994-1-1.html" target="_blank" rel="noopener nofollow" style="color: #1d58d1; text-decoration: none;">直播系统聊天技术(八)：vivo直播系统中IM消息模块的架构实践</a>》</li><li style="list-style: inherit;">《<a href="http://www.52im.net/thread-4299-1-1.html" target="_blank" rel="noopener nofollow" style="color: #1d58d1; text-decoration: none;">直播系统聊天技术(九)：千万级实时直播弹幕的技术实践</a>》</li><li style="list-style: inherit;">《<a href="http://www.52im.net/thread-4914-1-1.html" target="_blank" rel="noopener nofollow" style="color: #1d58d1; text-decoration: none;">直播系统聊天技术(十)：基于实时消息总线的活动系统架构设计</a>》（<span style="color: #ff0000;"><strong>* 本文</strong></span>）</li></ol><h1>3、技术背景</h1><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">所谓组装，就离不开老生常谈的复用，我们可以对大部分认为比较共性的场景做好系统级别的封装，封装成一个个复用度较高的服务，然后通过接口和扩展点的方式进行一部分的能力开放，但是有一种场景是解决不了的，就是当一个功能级别的代码执行结束后，希望触发到另外一个功能，同时希望这个功能是可以通过配置去解决的，并且不需要通过开发的手段去解决这类问题。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">例如，用户送了一个礼物给一个主播，直播间的贡献榜上对该用户做了积分 +1，这是一个很典型的「履约」类场景，与我们在直播间内下单购买，履约给仓储系统道理是一样的，但是这都建立在这个流程模式是固化的。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">而活动往往不是这样的，活动相比这些固化的流程是更为灵活的。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><strong>笔者的团队曾经开发过这样一个场景：</strong></p><blockquote style="background-image: none; border-width: medium medium medium 3px; border-style: none none none solid; border-color: currentcolor currentcolor currentcolor #e2dfdf; margin: 10px 0px; background-color: #eeeeee; width: 896px; color: #555555; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif;"><p style="margin: 10px auto;">用户通过送礼，去帮助主播完成一个直播间虚拟能量条的冲击，而每充满这个能量条都希望做一件事情，这个事情就彰显出业务侧的脑洞大开，第一次的活动是希望给某个榜单加上分数，第二次的活动希望是给主播掉落一个虚拟的宝箱，第三次的活动是给用户发送一些抽奖券，依次类推，只要是做过的功能，他都希望这个事情可以去用，时间久了，就会面临频繁去修改这个模块的代码，当它「结束」后，if 条件式的去触发各个代码，或者策略模式的去魔改代码，对于长期建设来看这种方式并不友好，就我看来这只是这个模块结束后要做这么多事情，那么下一个模块如果从这么多事情挑两件岂不是还要再写一堆代码？</p></blockquote><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">因此我们想到了一个相对比较原始的解决方案：总线式服务。</p><h1>4、信鸽服务的组合能力</h1><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">与其说组合，更倾向于用「履约」这个词形容会比较恰当一点，因为对于活动来说，信鸽只做「履约」这一侧的功能比较重要，他要解决的是异步场景的分发类问题，而不是对一些系统做一些 adapter 组合集成的能力。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">这里以一个活动场景来做示例：</p><div img-uploading-status=""  image-package-2"="" data-index="2" style="font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><div><div><img alt="1" loading="lazy" data-src="https://img2024.cnblogs.com/blog/1834368/202606/1834368-20260607220857544-2079633592.png" src="https://img2024.cnblogs.com/blog/1834368/202606/1834368-20260607220857544-2079633592.png" lazyloaded=""  medium-zoom-image"="" style="border: 0px; max-width: 100%; height: auto !important; cursor: zoom-in; transition: transform 300ms cubic-bezier(0.2, 0, 0.2, 1) !important;" /><p style="margin: 10px auto;"><strong>音乐人活动的一个简单的页面主要包含了几个模块功能：</strong></p></div></div></div><ul style="margin-left: 2.5rem; padding-left: 0px; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><li style="list-style: inherit;"><em>1）</em>用户通过送礼、观看等行为完成相关任务；</li><li style="list-style: inherit;"><em>2）</em>为喜爱的音乐人加进度条积分；</li><li style="list-style: inherit;"><em>3）</em>当进度条积分完成某个档位后，触发宝箱的掉落、飘屏送礼等。每个档位的类型是不同的；</li><li style="list-style: inherit;"><em>4）</em>幸运锦鲤的模块。</li></ul><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">对于这样一个活动，从开发的角度来看，其实它是由几个模块进行组装的，除了 4 是需要独立开发的，1、2、3 都可以通过现有的系统进行组装，这里 1 抽象为任务系统，2 抽象为进度条系统，3 也可以抽象为宝箱系统、送礼系统等。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">下图是对场景抽象化模块的概念：</p><div img-uploading-status=""  image-package-3"="" data-index="3" style="font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><div><div><img alt="2" loading="lazy" data-src="https://img2024.cnblogs.com/blog/1834368/202606/1834368-20260607220904408-23033239.png" src="https://img2024.cnblogs.com/blog/1834368/202606/1834368-20260607220904408-23033239.png" lazyloaded=""  medium-zoom-image"="" style="border: 0px; max-width: 100%; height: auto !important; cursor: zoom-in; transition: transform 300ms cubic-bezier(0.2, 0, 0.2, 1) !important;" /><p style="margin: 10px auto;">那么难点来了，通过什么手段可以来将这些模块进行组装呢？</p></div></div></div><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">通过图中可以看到，当一个模块完成了他的生命周期，可以发送一份数据，路由系统收到了这个数据之后，会帮我们做一层路由的转发，决定数据会路由到下一个系统上去。下一个系统可能是「奖励系统」也可以是「进度条系统」。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">同时可以对这个行为进一步细化的抽象，我们希望这个路由系统充当一个「总线」的角色，「信件」代表了每一个系统希望收到的数据，同时对每一个系统都抽象化成一个目的地，如果我们配置了一份路由关系（抽象为信鸽配置），那么这只「信鸽」可以作为将数据信件为我们带到我们想去的任何目的地，那么对于系统的好处是，系统只需要提供自己接入这个路由系统的能力即可，下一次随便是什么活动，可以直接做一些组合关系。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><strong>有了信鸽路由这种思路，针对音乐人活动这种场景，我们可以将一个流程的完整链路梳理出来：</strong></p><div img-uploading-status=""  image-package-4"="" data-index="4" style="font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><div><div><img alt="3" loading="lazy" data-src="https://img2024.cnblogs.com/blog/1834368/202606/1834368-20260607220911532-500319752.png" src="https://img2024.cnblogs.com/blog/1834368/202606/1834368-20260607220911532-500319752.png" lazyloaded=""  medium-zoom-image"="" style="border: 0px; max-width: 100%; height: auto !important; cursor: zoom-in; transition: transform 300ms cubic-bezier(0.2, 0, 0.2, 1) !important;" /><p style="margin: 10px auto;">图中可以看到，我们对任务、进度条等基础模块，做了一些扩展点（EXT-POINT）来满足业务流程的编排，这在中台里是比较常规的解决问题的手段之一，而在系统模块组组合的场景中，多了一层信鸽服务的概念，在【2】、【3】、【4】的处理流程中，都可以由信鸽来决定数据流向哪个系统，事实证明这个方案是可行也并且有效的。</p></div></div></div><h1>5、整体架构设计</h1><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">那么如何设计这样一个组合能力的架构呢？</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><strong>研发的重心可以分为四个层面：</strong></p><ul style="margin-left: 2.5rem; padding-left: 0px; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><li style="list-style: inherit;"><em>1）</em>履约能力：当代码结束后做到末端的触发。</li><li style="list-style: inherit;"><em>2）</em>SDK 接入能力：Interface 级别的包装，天然的 Autoconfigure 能力。</li><li style="list-style: inherit;"><em>3）</em>全局的标识字典：一份数据如何让所有接入的系统都可以达成共识。</li><li style="list-style: inherit;"><em>4）</em>系统的自动注册能力：接入 SDK 后，自动上报到信鸽服务的统一管理，自动激活，不需要人工的介入开启。</li></ul><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><strong>基于这四个层面，架构设计如下图：</strong></p><div img-uploading-status=""  image-package-5"="" data-index="5" style="font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><div><div><img alt="4" loading="lazy" data-src="https://img2024.cnblogs.com/blog/1834368/202606/1834368-20260607220918134-803980143.png" src="https://img2024.cnblogs.com/blog/1834368/202606/1834368-20260607220918134-803980143.png" lazyloaded=""  medium-zoom-image"="" style="border: 0px; max-width: 100%; height: auto !important; cursor: zoom-in; transition: transform 300ms cubic-bezier(0.2, 0, 0.2, 1) !important;" /><p style="margin: 10px auto;"><strong>从图中可以看到：</strong>左侧虚线框代表了一个系统的触发，右边虚线框代表了最终另外一个系统的触达。信鸽系统充当了代理的服务，触发的系统只需要接入信鸽 SDK，当执行完自己的职责之后，对数据做一层组装发送给信鸽系统，信鸽系统会根据发送的信鸽 id，寻找到信鸽的相关配置，信鸽 id 决定了数据会流转到那个接入的子系统上，这个流转可以是同步的也可以是异步的（当然大部分都是异步场景），异步主要依赖「RocketMQ」的投递能力，当转发失败后，会对投递的数据结果集进行备份存储，用于定时步长的重试操作。在以往的实践过程中，大部分场景都是异步的链路，不需要获得下一个子系统提供的返回的结果集，并且「RocketMQ」本身投递消息的出错率也是小概率事件（毕竟4台 broker，出错3台的可能性是极低的），相比 RPC 这类通信级别的接口有绝对的优势。</p></div></div></div><h1>6、提供的SDK能力</h1><h2>6.1 路由触发</h2><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">在上图中，我们可以看到对于子系统分成了大概 2 类场景，一种是活动业务域，另外一种是非活动业务域，这本身与业务的场景有关，我们希望所有的子系统都可以按照标准去接入 SDK，但是并不能保证每个子系统提供能力都依靠 SDK，对于一些非活动业务域使用了定制化开发的模式来进行桥接工作，这种桥接工作更像是传统的 adapter 和 ESB 总线思路。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">而活动业务域的子系统都可以采取接入 SDK 的模式，这里主要会介绍一下异步的设计思路，当一个子系统接入 SDK 后，会在 Spring 容器创建 bean 的时候，默认创建一个 PushConsumer 的 bean ，添加监听信鸽 「fly」 的 「Listener」 ，这样能做到自动消费到路由的消息，对消息进行解析，假设这个系统可以承担的模块能力分别是 S1 / S2 ..., SN 等功能，那么整体实现图如下图所示。</p><div img-uploading-status=""  image-package-6"="" data-index="6" style="font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><div><div><img alt="5" loading="lazy" data-src="https://img2024.cnblogs.com/blog/1834368/202606/1834368-20260607220924083-1773808322.png" src="https://img2024.cnblogs.com/blog/1834368/202606/1834368-20260607220924083-1773808322.png" lazyloaded=""  medium-zoom-image"="" style="border: 0px; max-width: 100%; height: auto !important; cursor: zoom-in; transition: transform 300ms cubic-bezier(0.2, 0, 0.2, 1) !important;" /></div></div></div><h2>6.2 自动注册</h2><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">每一个 Provider 的 Server 都是一个独立的应用服务集群，对于每一个 Provider 来说他提供的能力并不是单一的，正如上文所说，一个领域服务（活动 TOY 服务：主要提供各类积木式玩法领域），他能够提供的模块是非常多样的，诸如宝箱、进度条、留言板等等，「act-toy」 服务他具备了许多功能，当 「act-toy」 服务接入 SDK 后，就需要把自己子域需要发布成 Provider 的功能注册到信鸽上，注册的方案如下图。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">当一个 Server 拉取 SDK 的启动后，会定时的拉取定义好的 Interface ，对实现的 Class ，获取自定义注解的 Type 类型，通过顺序消息的方式注册到信鸽服务上，采用了启动 + 定时推送的方式，信鸽服务收到相关的注册信息可以后会将其存储。</p><div img-uploading-status=""  image-package-7"="" data-index="7" style="font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><div><div><img alt="6" loading="lazy" data-src="https://img2024.cnblogs.com/blog/1834368/202606/1834368-20260607220929979-857766167.png" src="https://img2024.cnblogs.com/blog/1834368/202606/1834368-20260607220929979-857766167.png" lazyloaded=""  medium-zoom-image"="" style="border: 0px; max-width: 100%; height: auto !important; cursor: zoom-in; transition: transform 300ms cubic-bezier(0.2, 0, 0.2, 1) !important;" /></div></div></div><h1>7、与ESB消息总线方案的比较</h1><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">从整个组合的能力上看，整体的设计思路是符合总线式服务，而总线式服务业内比较经典的，就是 ESB 总线。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">ESB 总线这个技术用今天互联网的角度来看是比较过时的，因为他本身更适应用于大型 IT 企业内部的一些跨语言类服务架构方案，而他本身承接了系统和系统之间的桥接能力。但是信鸽本身的设计不同于 ESB 总线，他更注重的特点是「哑管道」的概念，忽略集成的适配转换，也不适合做中心化同步的集成。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><strong>那么具体的比较如下：</strong></p><div img-uploading-status=""  image-package-8"="" data-index="8" style="font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><div><div><img alt="7" loading="lazy" data-src="https://img2024.cnblogs.com/blog/1834368/202606/1834368-20260607220935469-861389729.png" src="https://img2024.cnblogs.com/blog/1834368/202606/1834368-20260607220935469-861389729.png" lazyloaded=""  medium-zoom-image"="" style="border: 0px; max-width: 100%; height: auto !important; cursor: zoom-in; transition: transform 300ms cubic-bezier(0.2, 0, 0.2, 1) !important;" /><p style="margin: 10px auto;"><strong>那么可以从2个 ESB 场景来介绍信鸽的优势所在，笔者理解的 ESB 总线技术大致分两类：</strong></p></div></div></div><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><em>1）</em>开源的 ESB 解决方案：这类是提供开源的一种框架技术，部署在同一个 Tomcat 容器中，开发若干个 Bundle 可以运行在容器中，并且能做到热替换的作用，但是每个 bundle 需要通信的模式需要定制私有协议。由于这类开源框架较早，提供的通信协议大部分是 WebService 类的，因此在开发过程中，开发的成本会非常高，例如 Apache 早期开源的 ServiceMix 。关于协议，需要写大量的 「wsdl」 做通信，大多数也是依赖 WebService 发布的接口。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><em>2）</em>自研的 ESB 集成能力：笔者曾经参加过一个企业级的项目，大致是 ESB 的总线集成了各路系统，包括了 Rest 协议接口、C++ 服务发布的 WebService 协议、海外第三方公司发布的 WebService 协议，为了打通公司内部 C++ 服务、Java Web 服务与海外第三方系统，采用的就是做一个集成的总线，这里需要太多的协议转换，包括如何解析 「wsdl」 文件读取节点数据，转换成 Json 等等，这类场景在企业级服务是常见的事情，本身不适用互联网场景，侧重点更偏向于同步接口协议的转换，同时还不知道编排的能力，大部分依靠硬编码来解决。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">无论 1 还是 2 与我们信鸽设计思路都是不同的，信鸽本质上强调的是异步去做末端的事件，选用轻量的协议结构，在技术上属于同语言系，因此关于字典的定义也是标准化的，也就是说，userId、anchorId 分别代表了用户id和主播id，并不需要任何一方突发奇想定义 uid、aid 这类的字样，由信鸽来定义统一化的字典，同时编排统一收拢到信鸽服务来确定，是可视化的，不需要编写复杂的 XML 节点文件。</p><h1>8、与Pipeline流水线方案的比较</h1><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">从总线这个概念来看，或多或少同「管道」是类似的，Pipeline 的思想被广泛应用在诸多技术领域中。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><strong>比如：</strong></p><ul style="margin-left: 2.5rem; padding-left: 0px; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><li style="list-style: inherit;"><em>1）</em>CI/CD 持续集成的场景；</li><li style="list-style: inherit;"><em>2）</em>开源框架中的流水线设计模式，例如 Netty框架中的网络字节流处理等；</li><li style="list-style: inherit;"><em>3）</em>业务自定义的一些工作流流转技术。</li></ul><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><strong>第一种场景：</strong>更倾向于 DevOps 的解决方案，从持续集成，持续交付，持续部署，为了快速、自动化、可重复的方式的去处理工程，与我们今天要解决的上层业务编排场景是完全不同的两个领域。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><strong>第二种场景：</strong>本质上是一种代码实现的设计模式，像 Netty 中，采用的是「责任链」的设计模式去实现，网络字节流经过「工厂流水线」后，进行包装，最后得到一个成品，与我们今天要解决的业务同样不是一个领域。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><strong>第三种场景：</strong>是业务开发过程中经常遇到的问题，尤其是有复杂流程的场景中，这里包含了对流程的编排、服务的编排，每个代码块和服务都可能作为一种处理的「节点」，在整个流水线中进行串排完成业务的实现。与我们的信鸽有什么不同呢？</p><div img-uploading-status=""  image-package-9"="" data-index="9" style="font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><div><div><img alt="8" loading="lazy" data-src="https://img2024.cnblogs.com/blog/1834368/202606/1834368-20260607220941960-470757752.png" src="https://img2024.cnblogs.com/blog/1834368/202606/1834368-20260607220941960-470757752.png" lazyloaded=""  medium-zoom-image"="" style="border: 0px; max-width: 100%; height: auto !important; cursor: zoom-in; transition: transform 300ms cubic-bezier(0.2, 0, 0.2, 1) !important;" /><p style="margin: 10px auto;">在我看来，两种技术方案是可以同时存在的，我们对已经稳定的领域场景，做一些灵活自定义的一些流程编排，这些流程可以作为「流水线」的思路去实现，在「流水线」末尾的一个流程节点上可以定位为「信鸽」的节点，这个节点可以再继续自由组合定制化的活动场景。</p></div></div></div><h1>9、信鸽服务的消息转发能力</h1><h2>9.1 面临的问题</h2><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">直播的活动与营销活动的不同，大部分触发的场景偏向于平台的下游，因此需要监听许多 topic，去实现自己的业务编码，而活动在非成熟的形式背景下，必然要面临大量的短期代码，短期代码的生命周期往往只局限于活动周期内，这类代码代表了探索，代表了拓荒。直播活动在领域建模上是具备双面性的，一方面要在历史的经验去做经验复制和沉淀，另一方面要具备快速展开短期代码的能力。而随着服务数量的增多，就面临着许多服务要监听 topic，而这些 topic 对于 A 服务可能是监听过的，对于 B 服务可能也是监听过的，面临着这类问题，我们需要把 topic 接入的代码做一次代码的 Copy 或者做一些包来解决，但是这并不是一个友好的解决方案。同时，这也面临着另外一个问题，另外一个问题就是当一个代码块完成他的使命后，再也没有开启的那天，他接入的 topic 会一直进行空转的消费，我们不可能经常的对 「Nydus」（云音乐版 RocketMQ ）管控平台去做一些消费下线，时间久了，消息治理就变得比较棘手起来，就如同我们去分层解决服务循环依赖，没成想有一天异步链路中也出现了一团乱麻。下面这个图代表了 「dev」 过程中遇到的问题：</p><div img-uploading-status=""  image-package-10"="" data-index="10" style="font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><div><div><img alt="9" loading="lazy" data-src="https://img2024.cnblogs.com/blog/1834368/202606/1834368-20260607220947393-1150952851.png" src="https://img2024.cnblogs.com/blog/1834368/202606/1834368-20260607220947393-1150952851.png"  medium-zoom-image"="" style="border: 0px; max-width: 100%; height: auto !important; cursor: zoom-in; transition: transform 300ms cubic-bezier(0.2, 0, 0.2, 1) !important;" /></div></div></div><h2>9.2 解决思路</h2><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">我们希望信鸽可以继续发挥他的优势，它不仅仅是一个只做业务末端履约的一个总线服务，他更应该帮助我们活动域内的服务做好消息治理这方面的工作，首先需要有一个研发思路的转变，就是开发同学需要为自己 「dev」 的模块去提供他的 topic，这个 topic 与自己 「dev」 的模块是一个技术闭环的，如果每一个 「dev」 的模块都具备这样的能力，信鸽只需要发挥他的优势，对本来需要监听的 topic 变成由信鸽转发给模块的 topic。</p><div img-uploading-status=""  image-package-11"="" data-index="11" style="font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><div><div><img alt="10" loading="lazy" data-src="https://img2024.cnblogs.com/blog/1834368/202606/1834368-20260607220952870-1482314690.png" src="https://img2024.cnblogs.com/blog/1834368/202606/1834368-20260607220952870-1482314690.png" lazyloaded=""  medium-zoom-image"="" style="border: 0px; max-width: 100%; height: auto !important; cursor: zoom-in; transition: transform 300ms cubic-bezier(0.2, 0, 0.2, 1) !important;" /></div></div></div><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">按照这个解决思路的前提下，我们希望信鸽需要具备的就是消息转发的能力，而这个转发的场景可以抽象为三种。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><strong>具体是：</strong></p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><em>1）</em>业务自定义的分发场景：这个场景是一定要做一些特定业务处理的，通过原始消息，做一些业务清洗工作，再去转发到一些业务场景中，属于定制化的场景。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><em>2）</em>注册上报自动分发的场景：这个场景只要保证信鸽服务的 receiver 监听的 topic 足够，那么信鸽就可以自动分发到各个业务模块的 topic 上，其中分发的消息结构是具备异样的，可以通过 tag 的不同让 consumer 自住选择性拉取，根据 tag 的区分，同时也能解决某类 topic 消息过多，导致饿死的场景，犹如上图提到的一样。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><em>3）</em>消息存储的场景：并不是所有的消息都需要存储，在活动中我们认为较为重要的消息是需要做备份，方便后期去做回放，例如礼物消息，是任何场景使用率较高的，为了提升写入的能力，可以采用批量消费的消费方式，做batch的写入，在写入这里初步选型是用TiDB，TiDB相对DDB（网易分布式数据库）比较适合去存这类消息，同时，这类消息大部分时候是不需要做读操作。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><strong>按照提到的三个场景，整体的架构如下：</strong></p><div img-uploading-status=""  image-package-12"="" data-index="12" style="font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><div><div><img alt="11" loading="lazy" data-src="https://img2024.cnblogs.com/blog/1834368/202606/1834368-20260607220959994-40099209.png" src="https://img2024.cnblogs.com/blog/1834368/202606/1834368-20260607220959994-40099209.png" lazyloaded=""  medium-zoom-image"="" style="border: 0px; max-width: 100%; height: auto !important; cursor: zoom-in; transition: transform 300ms cubic-bezier(0.2, 0, 0.2, 1) !important;" /><p style="margin: 10px auto;">我们的 receiver 可以根据配置过的 topic 动态的在 spring 容器里创建 consumer 的 bean，兼容了新接入 topic，需要修改信鸽服务代码的问题，同时在收到了 topic 消息的那一刻，消息转发如图中所描述一样，分成了三条路。</p></div></div></div><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><strong>这三条路代表了：</strong>自动转发、自定义转发、消息存储，这里选用三个不同的 consumer，保证消费线程池的足够宽，和转发 topic 队列足够可消费，自动转发收到消息后会根据源 topic 的类型再一次做 Tag 区分的转发到配置的 topic 关系上，同时这个转发关系是可以让研发自助管理的，也可以配置他的存活周期，非常适用于活动短期场景，在活动结束后，减少了服务的空转消费的情况。当然毕竟也要考虑到另外一个问题，多了一跳的操作会导致到转发的失败，对于这种场景，我们会对失败的消息做 exception 的存储，进行重试处理。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><strong>同时：</strong>我们对信鸽的转发能力做了压力测试，队列的长度设置的足够宽，不考虑写表链路的场景下，单纯的转发能力，消耗 io 的点主要还是集中在 broker 通信的场景上，如果考虑消息都采用异步落盘的情况下，系统的吞吐量会更优，选用了 「8U16G」 的服务器配置，在 32 台 docker 云容器的支撑下，receiver 是可以承担到 300w/min 的消息量，并且 cpu 还能保持到 45% 左右。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">虽然信鸽的转发能力解决了我们的问题，但并不代表这是个最优解，我希望的最优解是可以让信鸽搭载 FaaS 平台，毕竟 FaaS 可以提供很多关于消息清洗的场景，而且 FaaS 在机器资源调度上会有更好表现。FaaS + BaaS 这样的组合，是未来系统技术转型的趋势。</p><h1>10、本文小结</h1><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">花费时间做一个系统到底带来什么样的好处，又遇到什么难点呢？</p><h2>10.1 开发维护性</h2><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">这里用一个 case 来描述研发在使用信鸽服务做业务开发后会带来怎样的好处，大勇作为一名业务研发同学，今天他需要开发一个活动，活动涉及到榜单晋级、直播间杀怪、直播间飘屏、主播任务。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><strong>这个活动的流程思路是：</strong></p><ul style="margin-left: 2.5rem; padding-left: 0px; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><li style="list-style: inherit;"><em>1）</em>主播完成了 「xx」 任务后在直播间掉落一个「怪物」，并发送飘屏通知。</li><li style="list-style: inherit;"><em>2）</em>主播完成了 「xx」 任务后给榜单加上一些分数。</li><li style="list-style: inherit;"><em>3）</em>榜单跨日晋级 topN，topN 发送飘屏通知。</li></ul><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">很幸运的是、以上涉及到的功能，以前都开发过了，这一次只需要完成组合，很不幸的是，大勇需要开发这类组合能力。直到他遇到了信鸽，一切迎刃而解了，每个功能都接入了信鸽，那么大勇只需要通过信鸽后台，配置好任务完成要飞向「杀怪」、「飘屏」等等信鸽，对于大勇可能只需要很短的时间提测了，发布流程也减少了，一次性的胶水组装代码也不需要，毕竟完成任务掉落怪物，这个逻辑写在任务系统好像也不是很合适。</p><h2>10.2 遇到的困难</h2><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">在做消息管理这类问题处理的时候，实现业务覆盖的时候遇到了很多难点。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">我们要对现有系统已经接入的 topic 做一些改造，在新业务场景中是屡试不爽的，但是在旧系统中（例如任务系统），新提供了一个任务的 topic，收发路由的旧消息，虽然我们也按照 SDK 的方式做了根据 tag（源 topic）做一些不同 service 的区分，但是这里依然避免不了关于数据清洗和数据结构的协议转换问题，这类问题可能与任务系统本身的清洗思路是有问题的，而这类问题最佳的解决方案一般可以选用脚本语言去做消息清洗会更加灵活一点。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">同时在做容量评估的时候，初期的压测并不是很顺利，由于写表链路与信鸽服务存在一个服务中进行压测，如果对某些消息进行数据写入 TiDB 的话，即便是批量消费写入整体服务的吞吐量也是难以压上去的，因此对写TiDB链路的服务单独进行独立，单独进行这方面的压测，信鸽原始服务只做转发，而写存储这一块可以单独去做写能力的评估。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">去掉了写 TiDB 链路的场景，单独对服务的进行吞吐量压测，起初选用的 「4U8G」 的服务器资源，由于整体的转发性能较为吃 cpu ，当提升了规格之后，整体的吞吐量有了很明显翻倍，而介于线上消息量的评估，100w/min 的消息可能是我们现有业务的极限状况，我们分别按照不同消息量做了压测，最后输出了一个压测结果集，会根据不同的消息量区间做适当的扩容和缩减。</p><h2>10.3 未来展望</h2><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">本文就云音乐大直播活动中台技术团队在日常研发过程中遇到关于业务场景组合、消息管理这类问题，提供了一种系统设计的思路，希望可以帮助读者在日常开发提供一些参考的意见。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">目前主要还是围绕着解决现有技术侧问题所展开的，后期会考虑对消息回放这一块作为修复数据的一个重要手段和解决方案，站在异常处理的视角上，如何帮助研发同学快速修复线上问题。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">同时，面对未来国际化的场景下，对于消息用户地区机房不够敏感的场景下，希望可以通过一些手段来帮助业务侧消息转发到相关机房，协助 「Nydus」国际化后，解决业务侧路由的不清晰之处，而在未来的国际化路由机房的基础上，如果做到模块之间消息可以准确的路由到用户所在机房也是我们需要更加深入思考的问题。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">我们希望信鸽可以作为直播相关产品在活动业务域的重要解决手段之一，帮助更多相关同学解决「复用」、「组合」的烦恼，同时希望它可以国际化，适应更多的产品场景之中。</p><h1>11、参考资料</h1><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">[0] <a href="http://www.52im.net/thread-853-1-1.html" target="_blank" rel="noopener nofollow" style="color: #1d58d1; text-decoration: none;">移动端实时音视频直播技术详解（一）：开篇</a>》</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">[1] <a href="http://www.52im.net/thread-1562-1-1.html" target="_blank" rel="noopener nofollow" style="color: #1d58d1; text-decoration: none;">海量实时消息的视频直播系统架构演进之路(视频+PPT)</a></p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">[2] <a href="http://www.52im.net/thread-1236-1-1.html" target="_blank" rel="noopener nofollow" style="color: #1d58d1; text-decoration: none;">百万在线的美拍直播弹幕系统的实时推送技术实践之路</a></p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">[3] <a href="http://www.52im.net/thread-3252-1-1.html" target="_blank" rel="noopener nofollow" style="color: #1d58d1; text-decoration: none;">阿里电商IM消息平台，在群聊、直播场景下的技术实践</a></p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">[4] <a href="http://www.52im.net/thread-3376-1-1.html" target="_blank" rel="noopener nofollow" style="color: #1d58d1; text-decoration: none;">微信直播聊天室单房间1500万在线的消息架构演进之路</a></p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">[5] <a href="http://www.52im.net/thread-3515-1-1.html" target="_blank" rel="noopener nofollow" style="color: #1d58d1; text-decoration: none;">百度直播的海量用户实时消息系统架构演进实践</a></p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">[6] <a href="http://www.52im.net/thread-3799-1-1.html" target="_blank" rel="noopener nofollow" style="color: #1d58d1; text-decoration: none;">百万人在线的直播间实时聊天消息分发技术实践</a></p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">[7] <a href="http://www.52im.net/thread-3835-1-1.html" target="_blank" rel="noopener nofollow" style="color: #1d58d1; text-decoration: none;">直播间海量聊天消息的架构设计难点实践</a></p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">[8] <a href="http://www.52im.net/thread-3994-1-1.html" target="_blank" rel="noopener nofollow" style="color: #1d58d1; text-decoration: none;">vivo直播系统中IM消息模块的架构实践</a></p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">[9] <a href="http://www.52im.net/thread-3687-1-1.html" target="_blank" rel="noopener nofollow" style="color: #1d58d1; text-decoration: none;">万人群聊消息投递方案的思考和实践</a></p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">[10] <a href="http://www.52im.net/thread-1562-1-1.html" target="_blank" rel="noopener nofollow" style="color: #1d58d1; text-decoration: none;">海量实时消息的视频直播系统架构演进之路(视频+PPT)[附件下载]</a></p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">[11] <a href="http://www.52im.net/thread-4905-1-1.html" target="_blank" rel="noopener nofollow" style="color: #1d58d1; text-decoration: none;">社交场景下的统一即时通讯im消息流交互层模块化技术实践</a></p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">[12] <a href="http://www.52im.net/thread-4012-1-1.html" target="_blank" rel="noopener nofollow" style="color: #1d58d1; text-decoration: none;">阿里IM技术分享(八)：深度解密钉钉即时消息服务DTIM的技术设计</a></p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">[13] <a href="http://www.52im.net/thread-4886-1-1.html" target="_blank" rel="noopener nofollow" style="color: #1d58d1; text-decoration: none;">B站IM消息系统的新架构升级实践</a></p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">[14] <a href="http://www.52im.net/thread-3875-1-1.html" target="_blank" rel="noopener nofollow" style="color: #1d58d1; text-decoration: none;">视频直播技术干货(九)：千万级直播系统后端架构设计的方方面面</a></p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">[15] <a href="http://www.52im.net/thread-3922-1-1.html" target="_blank" rel="noopener nofollow" style="color: #1d58d1; text-decoration: none;">视频直播技术干货(十)：一文读懂主流视频直播系统的推拉流架构、传输协议等</a></p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">[16] <a href="http://www.52im.net/thread-4785-1-1.html" target="_blank" rel="noopener nofollow" style="color: #1d58d1; text-decoration: none;">视频直播技术干货(十三)：B站实时视频直播技术实践和音视频知识入门</a></p><blockquote style="background-image: none; border-width: medium medium medium 3px; border-style: none none none solid; border-color: currentcolor currentcolor currentcolor #e2dfdf; margin: 10px 0px; background-color: #eeeeee; width: 896px; color: #555555; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif;"><p style="margin: 10px auto;"><strong>即时通讯技术学习：</strong></p><p style="margin: 10px auto;">- 移动端IM开发入门文章：《<a href="http://www.52im.net/thread-464-1-1.html" rel="noopener nofollow" target="_blank" style="color: #1d58d1; text-decoration: none;">新手入门一篇就够：从零开发移动端IM</a>》</p><p style="margin: 10px auto;">- 开源IM框架源码：<a href="https://github.com/JackJiang2011/MobileIMSDK" rel="noopener nofollow" target="_blank" style="color: #1d58d1; text-decoration: none;">https://github.com/JackJiang2011/MobileIMSDK</a>（<a href="https://gitee.com/jackjiang/MobileIMSDK" rel="noopener nofollow" target="_blank" style="color: #1d58d1; text-decoration: none;">备用地址点此</a>）</p></blockquote><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">（本文同步发布于：<a href="http://www.52im.net/thread-4914-1-1.html" target="_blank" rel="noopener nofollow" style="color: #1d58d1; text-decoration: none;">http://www.52im.net/thread-4914-1-1.html</a>）</p><img src ="http://www.blogjava.net/jb2011/aggbug/451786.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jb2011/" target="_blank">Jack Jiang</a> 2026-06-08 11:52 <a href="http://www.blogjava.net/jb2011/archive/2026/06/08/451786.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>轻量级Web端IM即时通讯框架MobileIMSDK-Web，基于Socket.io库</title><link>http://www.blogjava.net/jb2011/archive/2026/06/01/451784.html</link><dc:creator>Jack Jiang</dc:creator><author>Jack Jiang</author><pubDate>Mon, 01 Jun 2026 02:51:00 GMT</pubDate><guid>http://www.blogjava.net/jb2011/archive/2026/06/01/451784.html</guid><wfw:comment>http://www.blogjava.net/jb2011/comments/451784.html</wfw:comment><comments>http://www.blogjava.net/jb2011/archive/2026/06/01/451784.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jb2011/comments/commentRss/451784.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jb2011/services/trackbacks/451784.html</trackback:ping><description><![CDATA[<h1>一、基本介绍</h1><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><img src="https://img2024.cnblogs.com/blog/1834368/202605/1834368-20260531223405684-1587595240.jpg" alt="1" loading="lazy" style="border: 0px; max-width: 100%; height: auto !important; cursor: zoom-in; transition: transform 300ms cubic-bezier(0.2, 0, 0.2, 1) !important;" /></p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">MobileIMSDK-Web是一套纯JS编写的Web端IM即时通讯框架(含服务端)：</p><ul style="margin-left: 2.5rem; padding-left: 0px; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><li style="list-style: inherit;"><em>1）</em>超轻量级、极少依赖；</li><li style="list-style: inherit;"><em>2）</em>纯JS编写、高度提炼，简单易用；</li><li style="list-style: inherit;"><em>3）</em>基于著名的socket.io网络库实现，浏览器兼容性好、服务端并发性能好；</li><li style="list-style: inherit;"><em>4）</em>支持运行于iOS、Android等移动端浏览器和各种PC端浏览器；</li><li style="list-style: inherit;"><em>5）</em>能与<a href="https://gitee.com/jackjiang/MobileIMSDK" target="_blank" style="color: #1d58d1; text-decoration: none;">MobileIMSDK的APP版</a>（原生移动端代码编写）完美互通；</li><li style="list-style: inherit;"><em>6）</em>可应用于手机端/PC端的网页聊天应用、企业OA、Web端消息推送等场景。</li></ul><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">&#9758; 补充说明：MobileIMSDK-Web是 <a href="https://gitee.com/jackjiang/MobileIMSDK" target="_blank" style="color: #1d58d1; text-decoration: none;">MobileIMSDK</a> 的姊妹工程，MobileIMSDK-Web专注于Web端网页聊天（或推送），而MobileIMSDK用于原生代码编写的移动端IM（或推送）应用，但二者可完美互通&#8212;&#8212;从而实现原生代码编写的移动端与基于html的网页聊天完美互通。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">&#9758; 关于为何使用的是Socket.io而不是Netty作为MobileIMSDK-Web的网络层，详见：<span style="color: gray;">《</span><a href="http://www.52im.net/thread-1248-1-1.html" target="_blank" style="color: #1d58d1; text-decoration: none;">MobileIMSDK-Web的网络层框架为何使用的是Socket.io而不是Netty？</a><span style="color: gray;">》。</span></p><h1>二、与MobileIMSDK的区别</h1><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><img src="https://img2024.cnblogs.com/blog/1834368/202604/1834368-20260426210610330-1388464167.jpg" alt="2" loading="lazy" style="border: 0px; max-width: 100%; height: auto !important; cursor: zoom-in; transition: transform 300ms cubic-bezier(0.2, 0, 0.2, 1) !important;" /></p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><strong>&#9758; 关于<a href="https://gitee.com/jackjiang/MobileIMSDK" target="_blank" style="color: #1d58d1; text-decoration: none;">MobileIMSDK</a>：</strong></p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">MobileIMSDK主要使用原生代码编写，应用于非Web网页方式的移动端即时通讯场景下（<span style="color: #808080;">当然最新的MobileIMSDK框架也支持基于HTML5的WebSocket客户端</span>）。</p><strong style="font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">⭐️ 同步开源地址：</strong><ul style="margin-left: 2.5rem; padding-left: 0px; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><li style="list-style: inherit;">❶ <strong>GitHub：</strong><a href="https://github.com/JackJiang2011/MobileIMSDK" rel="noopener nofollow" target="_blank" style="color: #1d58d1; text-decoration: none;">https://github.com/JackJiang2011/MobileIMSDK</a></li><li style="list-style: inherit;">❷ <strong>码云gitee：</strong><a href="https://gitee.com/jackjiang/MobileIMSDK" rel="noopener nofollow" target="_blank" style="color: #1d58d1; text-decoration: none;">https://gitee.com/jackjiang/MobileIMSDK</a></li><li style="list-style: inherit;">❸ <strong>Gitcode：</strong><a href="https://gitcode.com/hellojackjiang2011/MobileIMSDK" rel="noopener nofollow" target="_blank" style="color: #1d58d1; text-decoration: none;">https://gitcode.com/hellojackjiang2011/MobileIMSDK</a></li></ul><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><strong>&#9758; 关于MobileIMSDK-Web：</strong><br />MobileIMSDK-Web完全使用JavaScript编写，主要应用于不支持HTML5的需要兼容旧式浏览器的Web网页方式的即时通讯场景下（包括但不限于手机端、PC端的网页聊天（或消息推送）等）。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><strong>&#9758; MobileIMSDK与MobileIMSDK-Web的互通：</strong></p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">基于MobileIMSDK-Web开发的开发的网页聊天等和基于MobileIMSDK开发的移动端IM等<strong>可以无缝地进行消息互通，两个框架之间的通信协议完全兼容</strong>，从而实现您的网页聊天（或推送）与手机端原生代码开发的IM（或推送）进行完美协作，实现多端通信。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><strong>&#9758; 我该如何选择？</strong></p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><strong>选择一：</strong>如果您的应用是用原生代码编写，如移动端是原生代码编写或者不需要兼容旧式浏览器，那么您可以将 <a href="https://gitee.com/jackjiang/MobileIMSDK" target="_blank" style="color: #1d58d1; text-decoration: none;">MobileIMSDK</a> 引入到您的项目中从而实现IM（或推送）应用；</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><strong>选择二：</strong>如果您的应用是基于Web网页且需要兼容旧式浏览器，那么您的最佳选择就是使用MobileIMSDK-Web来开发您的网页端聊天（或消息推送）。</p><h1>三、设计目标&nbsp;</h1><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">原生的WebSocket代码或者原始的socket.io代码，使得网络通信代码与大量前端UI界面代码混在一起，使得UI界面的重构、维护、改版都非常困难。而MobileIMSDK-Web工程将让开发者专注于UI应用层的开发，网络通信层专业的代码交由SDK开发人员，从而解偶Web端IM的UI前端和通信层的耦合性，同时大大降低复杂性。<br /><br /><strong>总结一下，MobileIMSDK-Web的设计目标是为您的Web端IM带来以下便利：</strong></p><ul style="margin-left: 2.5rem; padding-left: 0px; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><li style="list-style: inherit;"><em>1）</em>前端UI代码与网络通信代码解耦：UI界面的重构、维护、改版都非常容易和优雅；</li><li style="list-style: inherit;"><em>2）</em>服务端网络通信代码与业务代码解耦：使得服务端的业务逻辑实现起来清晰简单；</li><li style="list-style: inherit;"><em>3）</em>浏览器端的高兼容性：受益于socket.io框架，MobileIMSDK-Web在不支持WebSocket的旧式浏览器上仍可很好地工作；</li><li style="list-style: inherit;"><em>4）</em>服务端的高并发、高性能：得益于Nodejs的异步编程模型和高并发特性，基于MobileIMSDK-Web编写的IM服务端拥有极高的并发处理性能。</li></ul><h1>四、框架组成&nbsp;</h1><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">整套MobileIMSDK-Web框架由以下2部分组成：</p><ul style="margin-left: 2.5rem; padding-left: 0px; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><li style="list-style: inherit;"><em>1）</em>浏览器端SDK：用于开发浏览器端页面，纯JS编写，极少依赖，方便对接基于原生JS、Angular、EmberJS、VUE等各种前端框架；</li><li style="list-style: inherit;"><em>2）</em>服务器端SDK：用于开发Web端IM的服务端，支持高性能和高并发。</li></ul><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><img src="https://img2024.cnblogs.com/blog/1834368/202605/1834368-20260531224502945-759635755.jpg" alt="目录+精编源码" width="1421" height="1220" loading="lazy" style="border: 0px; max-width: 100%; height: auto !important; cursor: zoom-in; transition: transform 300ms cubic-bezier(0.2, 0, 0.2, 1) !important;" /></p><h1>五、技术亮点</h1><ul style="margin-left: 2.5rem; padding-left: 0px; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><li style="list-style: inherit;">✅️ 轻量易使用：超轻量级&#8212;&#8212;纯JS编写且极少依赖，高度提炼&#8212;&#8212;简单易用；</li><li style="list-style: inherit;">✅️ 兼容性好：基于socket.io网络框架，浏览器兼容性好，在不支持WebSocket的旧式浏览器上仍可很好地工作；</li><li style="list-style: inherit;">✅️ QoS机制：完善的消息送达保证机制（<span style="color: sienna;">真正ACK应答机制</span>），确保不漏过每一条消息；</li><li style="list-style: inherit;">✅️ 断网恢复能力：拥有网络状况自动检测、断网自动治愈的能力；</li><li style="list-style: inherit;">✅️ 支持多种设备：支持运行于iOS、Android等移动端浏览器和各种PC端浏览器；</li><li style="list-style: inherit;">✅️ 封装的通信协议：实现了一个对上层透明的即时通讯通信协议模型；</li><li style="list-style: inherit;">✅️ 身份认证机制：实现了简单合理的身份认证机制（socket.io官方并未实现之，资料也几乎没有）；</li><li style="list-style: inherit;">✅️ 全消息路径：实现了client to server、server to client、client to client 共3种消息路径（socket.io官方只演示了广播消息，一对一发送无资料）；</li><li style="list-style: inherit;">✅️ 服务端慢io解偶：开发者可通过使用MQ进行DB等慢io的读、写解偶，保证IM实时消息高吞吐和性能；</li><li style="list-style: inherit;">✅️ 服务端代码解偶：实现了上层应用代码与sdk核心代码的解偶，上线、下线、c2s消息、c2c消息、身份认证等的回调通知；</li><li style="list-style: inherit;">✅️ 实现了在线列表：服务端实现了一个高性能的在线用户列表机制；</li><li style="list-style: inherit;">✅️ 完善的log记录：服务端接入了log4js日志框架，确保MobileIMSDK-Web中的每一个关键步骤都有日志输出，让您的运行调试更为便利；</li><li style="list-style: inherit;">✅️ 浏览器端代码解耦：实现了UI前端代码与sdk网络通信代码解偶，防止前端代码跟IM核心代码混在一起，不利于持续升级、重用和维护；</li><li style="list-style: inherit;">✅️ 轻松开启数据加密：一个参数即可开启SSL/TLS通信加密；</li><li style="list-style: inherit;">✅️ 聊天协议兼容：实现了与<a href="https://gitee.com/jackjiang/MobileIMSDK" target="_blank" style="color: #1d58d1; text-decoration: none;">MobileIMSDK</a> 完全兼容的协议模型。</li></ul><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><strong>MobileIMSDK-Web的浏览器兼容性：</strong></p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><strong><img src="https://img2024.cnblogs.com/blog/1834368/202605/1834368-20260531224628339-940085843.png" alt="x1" loading="lazy" style="border: 0px; max-width: 100%; height: auto !important; cursor: zoom-in; transition: transform 300ms cubic-bezier(0.2, 0, 0.2, 1) !important;" /></strong></p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><span style="color: gray;">（</span>&#9758; <span style="color: gray;">MobileIMSDK-Web的兼容性由socket.io网络框架决定：</span><a href="https://socket.io/docs/v4/client-installation/#browser-support" target="_blank" style="color: #1d58d1; text-decoration: none;">点此查看兼容性说明</a><span style="color: gray;">）</span></p><h1>六、性能负载</h1><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">得益于socket.io网络框架的高性能和Nodejs的异步编程模型，MobileIMSDK-Web可支持单机数万甚至上十万并发连接。当然，每种应用场景都有各自的特点和差异，请视具体场景具体评估之，性能数据仅供参考。<span style="color: gray;">（关于为何使用的是Socket.io而不是Netty作为MobileIMSDK-Web的网络层，详见《</span><a href="http://www.52im.net/thread-1248-1-1.html" target="_blank" style="color: #1d58d1; text-decoration: none;">MobileIMSDK-Web的网络层框架为何使用的是Socket.io而不是Netty？</a><span style="color: gray;">》）</span><br /><br /><strong>&#9758; socket.io性能测试讨论：</strong><a href="https://cnodejs.org/topic/5492ba8b61491ead0cc7c018" target="_blank" style="color: #1d58d1; text-decoration: none;">socket.io 高并发实战</a>、<a href="https://www.zhihu.com/question/31950731" target="_blank" style="color: #1d58d1; text-decoration: none;">socket.io保持6万+连接测试？</a>、<a href="https://www.zhihu.com/question/20831000" target="_blank" style="color: #1d58d1; text-decoration: none;">如何实现单服务器300万个长连接的？</a>。</p><h1>七、开发者手册</h1><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><img src="https://img2024.cnblogs.com/blog/1834368/202605/1834368-20260531225035199-1551909552.jpg" alt="缩略清单-无阴影" width="897" height="890" loading="lazy" style="border: 0px; max-width: 100%; height: auto !important; cursor: zoom-in; transition: transform 300ms cubic-bezier(0.2, 0, 0.2, 1) !important;" /></p><h1>八、Demo运行截图</h1><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><img src="https://img2024.cnblogs.com/blog/1834368/202605/1834368-20260531224933909-2000002215.jpg" alt="运行效果all_in_one拼合图-opti" loading="lazy" style="border: 0px; max-width: 100%; height: auto !important; cursor: zoom-in; transition: transform 300ms cubic-bezier(0.2, 0, 0.2, 1) !important;" /></p><h1>九、产品案例</h1><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">以下为基于MobileIMSDK-Web的Web端IM产品案例 <a href="http://www.52im.net/thread-2483-1-1.html" target="_blank" style="color: #1d58d1; text-decoration: none;">RainbowChat-Web</a> 的产品情况。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><img src="https://img2024.cnblogs.com/blog/1834368/202511/1834368-20251101000357185-1361468844.png" alt="rbpw_tb_main1" loading="lazy" style="border: 0px; max-width: 100%; height: auto !important; cursor: zoom-in; transition: transform 300ms cubic-bezier(0.2, 0, 0.2, 1) !important;" /></p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><strong>下图为RainbowChat-Web的主界面</strong>（<a href="http://www.52im.net/thread-2470-1-1.html" target="_blank" style="color: #1d58d1; text-decoration: none;">更多截图</a>、<a href="http://www.52im.net/thread-2491-1-1.html" target="_blank" style="color: #1d58d1; text-decoration: none;">更多演示视频</a>）：</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><img src="https://img2024.cnblogs.com/blog/1834368/202605/1834368-20260531225851689-770087619.jpg" alt="main1" loading="lazy" style="border: 0px; max-width: 100%; height: auto !important; cursor: zoom-in; transition: transform 300ms cubic-bezier(0.2, 0, 0.2, 1) !important;" /></p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><strong>下图为RainbowChat-Web的主界面[聊天窗全屏时]</strong> （<a href="http://www.52im.net/thread-2470-1-1.html" target="_blank" style="color: #1d58d1; text-decoration: none;">更多截图</a>、<a href="http://www.52im.net/thread-2491-1-1.html" target="_blank" style="color: #1d58d1; text-decoration: none;">更多演示视频</a>）：</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><em><img src="https://img2024.cnblogs.com/blog/1834368/202605/1834368-20260531225901053-419797023.jpg" alt="main2" loading="lazy" style="border: 0px; max-width: 100%; height: auto !important; cursor: zoom-in; transition: transform 300ms cubic-bezier(0.2, 0, 0.2, 1) !important;" /></em></p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">（<strong>本文内容引用自：</strong><a href="http://www.52im.net/thread-959-1-1.html" target="_blank" style="color: #1d58d1; text-decoration: none;">http://www.52im.net/thread-959-1-1.html</a>）</p><img src ="http://www.blogjava.net/jb2011/aggbug/451784.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jb2011/" target="_blank">Jack Jiang</a> 2026-06-01 10:51 <a href="http://www.blogjava.net/jb2011/archive/2026/06/01/451784.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>详解AI大模型实时通信为什么选SSE，而不是WebSocket和WebRTC</title><link>http://www.blogjava.net/jb2011/archive/2026/05/28/451783.html</link><dc:creator>Jack Jiang</dc:creator><author>Jack Jiang</author><pubDate>Thu, 28 May 2026 03:57:00 GMT</pubDate><guid>http://www.blogjava.net/jb2011/archive/2026/05/28/451783.html</guid><wfw:comment>http://www.blogjava.net/jb2011/comments/451783.html</wfw:comment><comments>http://www.blogjava.net/jb2011/archive/2026/05/28/451783.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/jb2011/comments/commentRss/451783.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/jb2011/services/trackbacks/451783.html</trackback:ping><description><![CDATA[<p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">本文由ArchSynapse AI分享，有修订和重新排版。</p><h1>1、引言</h1><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">在为大型语言模型（LLM）应用构建实时前后端通信系统时，选择正确的底层技术至关重要。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><strong>本章节将深入剖析三种主流技术的核心原理：</strong></p><ul style="margin-left: 2.5rem; padding-left: 0px; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><li style="list-style: inherit;"><em>1）</em>Server-Sent Events (SSE)：它作为服务器主导的单向数据流的黄金标准；</li><li style="list-style: inherit;"><em>2）</em>WebSocket：作为通用的全双工通信解决方案；</li><li style="list-style: inherit;"><em>3）</em>WebRTC：专注于媒体流和点对点数据交换。</li></ul><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">理解它们的技术设计哲学和技术细节，是做出明智技术选型的关键基础。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><strong>本文将为读者剖析 SSE、WebSocket、WebRTC 的技术原理，并对比三者在性能、安全与架构方面的优劣势，详解了AI大模型（LLM）在实时通信协议方面的综合技术考量以及最终选择。</strong></p><div img-uploading-status=""  image-package-1"="" data-index="1" style="font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><div><div><img src="https://img2024.cnblogs.com/blog/1834368/202605/1834368-20260526180712892-706354511.jpg" alt="cover-opti2" loading="lazy" style="border: 0px; max-width: 100%; height: auto !important; cursor: zoom-in; transition: transform 300ms cubic-bezier(0.2, 0, 0.2, 1) !important;" /></div></div></div><h1>2、AI大模型实时通信技术专题</h1><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><strong>技术专题系列文章目录如下，本文是第&nbsp;<em>5</em>&nbsp;篇：</strong></p><ul style="margin-left: 2.5rem; padding-left: 0px; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><li style="list-style: inherit;">《<a href="http://www.52im.net/thread-4797-1-1.html" target="_blank" style="color: #1d58d1; text-decoration: none;">全民AI时代，大模型客户端和服务端的实时通信到底用什么协议？</a>》</li><li style="list-style: inherit;">《<a href="http://www.52im.net/thread-4831-1-1.html" target="_blank" style="color: #1d58d1; text-decoration: none;">大模型时代多模型AI网关的架构设计与实现</a>》</li><li style="list-style: inherit;">《<a href="http://www.52im.net/thread-4856-1-1.html" target="_blank" style="color: #1d58d1; text-decoration: none;">通俗易懂：AI大模型基于SSE的实时流式响应技术原理和实践示例</a>》</li><li style="list-style: inherit;">《<a href="http://www.52im.net/thread-4872-1-1.html" target="_blank" style="color: #1d58d1; text-decoration: none;">ChatGPT如何实现聊天一样的实时交互？快速读懂SSE实时&#8220;推&#8221;技术</a>&nbsp;》</li><li style="list-style: inherit;">《<a href="http://www.52im.net/thread-4885-1-1.html" target="_blank" style="color: #1d58d1; text-decoration: none;">AI大模型爆火的SSE技术到底是什么？万字长文，一篇读懂SSE！</a>&nbsp;》</li><li style="list-style: inherit;">《<a href="http://www.52im.net/thread-4909-1-1.html" target="_blank" style="color: #1d58d1; text-decoration: none;">详解AI大模型实时通信为什么选SSE，而不是WebSocket和WebRTC</a>》（<span style="color: red;">&#9756; 本文</span>）</li></ul><h1>3、SSE是什么？</h1><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">Server-Sent Events (SSE) 是一种基于标准 HTTP 协议的技术，专为服务器向客户端推送单向事件流而设计。</p><div img-uploading-status=""  image-package-2"="" data-index="2" style="font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><div><div><img src="https://img2024.cnblogs.com/blog/1834368/202605/1834368-20260526180723207-320310494.png" alt="1" loading="lazy" style="border: 0px; max-width: 100%; height: auto !important; cursor: zoom-in; transition: transform 300ms cubic-bezier(0.2, 0, 0.2, 1) !important;" /><p style="margin: 10px auto;">其工作流程始于客户端创建一个&nbsp;EventSource&nbsp;对象，该对象会自动发起一个持久的 HTTP GET 请求。服务器接收到请求后，不立即关闭连接，而是保持响应打开，并以特定格式发送数据。</p></div></div></div><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">这个格式要求服务器设置 Content-Type 头部为&nbsp;<em>text/event-stream</em>。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><strong>每个事件由一系列字段组成，包括：</strong></p><ul style="margin-left: 2.5rem; padding-left: 0px; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><li style="list-style: inherit;"><em>1）</em>必需的&nbsp;<em>data:&nbsp;</em>字段用于承载消息内容；</li><li style="list-style: inherit;"><em>2）</em>可选的&nbsp;<em>event:&nbsp;</em>字段用于定义事件类型；</li><li style="list-style: inherit;"><em>3）</em>id: 字段用于标识事件以便在连接中断后恢复；</li><li style="list-style: inherit;"><em>4）</em>以及&nbsp;<em>retry:&nbsp;</em>字段用于指定重新连接前的等待时间。</li></ul><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">消息之间必须以两个换行符&nbsp;<em>\n\n</em>&nbsp;分隔。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">这种机制使得服务器能够在一个长连接上持续不断地推送增量数据，非常适合 LLM 流式传输等场景。SSE 的一大优势在于其天然地融入了现有的 HTTP 生态，能够无缝通过反向代理、负载均衡器和防火墙，无需特殊配置。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><strong>&#9758; 进一步学习：</strong></p><ul style="margin-left: 2.5rem; padding-left: 0px; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><li style="list-style: inherit;"><a href="http://www.52im.net/thread-336-1-1.html" target="_blank" style="color: #1d58d1; text-decoration: none;">Web端即时通讯技术盘点：短轮询、Comet、Websocket、SSE</a></li><li style="list-style: inherit;"><a href="http://www.52im.net/thread-335-1-1.html" target="_blank" style="color: #1d58d1; text-decoration: none;">SSE技术详解：一种全新的HTML5服务器推送事件技术</a></li><li style="list-style: inherit;"><a href="http://www.52im.net/thread-907-1-1.html" target="_blank" style="color: #1d58d1; text-decoration: none;">使用WebSocket和SSE技术实现Web端消息推送</a></li><li style="list-style: inherit;"><a href="http://www.52im.net/thread-1038-1-1.html" target="_blank" style="color: #1d58d1; text-decoration: none;">详解Web端通信方式的演进：从Ajax、JSONP 到 SSE、Websocket</a></li><li style="list-style: inherit;"><a href="http://www.52im.net/thread-907-1-1.html" target="_blank" style="color: #1d58d1; text-decoration: none;">使用WebSocket和SSE技术实现Web端消息推送</a></li><li style="list-style: inherit;"><a href="http://www.52im.net/thread-3555-1-1.html" target="_blank" style="color: #1d58d1; text-decoration: none;">网页端IM通信技术快速入门：短轮询、长轮询、SSE、WebSocket</a></li><li style="list-style: inherit;"><a href="http://www.52im.net/thread-3695-1-1.html" target="_blank" style="color: #1d58d1; text-decoration: none;">搞懂现代Web端即时通讯技术一文就够：WebSocket、socket.io、SSE</a></li></ul><h1>4、WebSocket是什么？</h1><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">WebSocket&nbsp;则提供了一种更为强大和灵活的全双工通信协议。它通过一次性的 HTTP 握手来&#8220;升级&#8221;一个标准的 TCP 连接。</p><div img-uploading-status=""  image-package-3"="" data-index="3" style="font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><div><div><img src="https://img2024.cnblogs.com/blog/1834368/202605/1834368-20260526180730137-813513241.png" alt="2" loading="lazy" style="border: 0px; max-width: 100%; height: auto !important; cursor: zoom-in; transition: transform 300ms cubic-bezier(0.2, 0, 0.2, 1) !important;" /><p style="margin: 10px auto;">握手过程涉及客户端发送一个包含&nbsp;<em>Upgrade: websocket</em>&nbsp;和<em>&nbsp;Connection: Upgrade</em>&nbsp;等特定头部的 HTTP 请求。如果服务器支持 WebSocket，它会返回一个状态码为 101 (Switching Protocols) 的响应，从而完成协议切换。</p></div></div></div><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">一旦连接建立，客户端和服务器就可以随时独立地向对方发送消息，而无需像 HTTP 那样每次都发起新的请求。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">WebSocket 消息被封装在轻量级的帧中进行传输，支持文本和二进制数据，极大地降低了网络开销。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">这种持久且双向的特性使其成为聊天应用、在线游戏和实时协作工具的理想选择。然而，其复杂性也远超 SSE，因为它是一个独立的协议栈，需要专门的服务器库和客户端处理逻辑。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><strong>&#9758; 进一步学习：</strong></p><ul style="margin-left: 2.5rem; padding-left: 0px; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><li style="list-style: inherit;"><a href="http://www.52im.net/thread-831-1-1.html" target="_blank" style="color: #1d58d1; text-decoration: none;">新手快速入门：WebSocket简明教程</a></li><li style="list-style: inherit;"><a href="http://www.52im.net/thread-3134-1-1.html" target="_blank" style="color: #1d58d1; text-decoration: none;">WebSocket从入门到精通，半小时就够！</a></li><li style="list-style: inherit;"><a href="http://www.52im.net/thread-331-1-1.html" target="_blank" style="color: #1d58d1; text-decoration: none;">初步认识WebSocket技术</a></li><li style="list-style: inherit;"><a href="http://www.52im.net/thread-1258-1-1.html" target="_blank" style="color: #1d58d1; text-decoration: none;">刨根问底HTTP与WebSocket的关系(上篇)</a></li><li style="list-style: inherit;"><a href="http://www.52im.net/thread-1273-1-1.html" target="_blank" style="color: #1d58d1; text-decoration: none;">刨根问底WebSocket与Socket的关系</a></li></ul><h1>5、WebRTC是什么？</h1><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">WebRTC (Web Real-Time Communication) 是一个更为复杂的生态系统，旨在实现浏览器间的直接音视频通话和任意数据交换。</p><div img-uploading-status=""  image-package-4"="" data-index="4" style="font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><div><div><img src="https://img2024.cnblogs.com/blog/1834368/202605/1834368-20260526180736611-509078980.png" alt="3" loading="lazy" style="border: 0px; max-width: 100%; height: auto !important; cursor: zoom-in; transition: transform 300ms cubic-bezier(0.2, 0, 0.2, 1) !important;" /><p style="margin: 10px auto;">它的核心思想是尽可能地建立点对点（Peer-to-Peer, P2P）连接，从而绕过中间服务器传输大量媒体数据，以达到最低的延迟。</p></div></div></div><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><strong>WebRTC 的整个通信过程分为三个阶段：</strong></p><ul style="margin-left: 2.5rem; padding-left: 0px; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><li style="list-style: inherit;"><em>1）</em>首先是通过信令服务器交换初始信息；</li><li style="list-style: inherit;"><em>2）</em>其次是通过 ICE (Interactive Connectivity Establishment) 框架进行 NAT 和防火墙穿越；</li><li style="list-style: inherit;"><em>3）</em>最后才是建立 P2P 数据通道。</li></ul><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">ICE&nbsp;框架依赖于 STUN (Session Traversal Utilities for NAT) 服务器来帮助设备发现自己的公网 IP 地址，如果直接连接失败，则会降级到 TURN (Traversal Using Relays around NAT) 服务器进行中继。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">TURN&nbsp;服务器虽然能保证连接成功，但会消耗大量带宽，因为所有流量都需要经过它转发。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">WebRTC 的另一个关键组件是&nbsp;RTCDataChannel API，它允许在两个浏览器之间建立一个类似 WebSocket 的 P2P 数据通道，用于传输非媒体数据。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">由于其架构的复杂性，WebRTC 通常需要一个额外的信令层（常由 WebSocket 或 SSE 实现）来协调连接的建立。</p><div img-uploading-status=""  image-package-5"="" data-index="5" style="font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><div><div><img src="https://img2024.cnblogs.com/blog/1834368/202605/1834368-20260526180745318-1967992419.png" alt="4" loading="lazy" style="border: 0px; max-width: 100%; height: auto !important; cursor: zoom-in; transition: transform 300ms cubic-bezier(0.2, 0, 0.2, 1) !important;" /><p style="margin: 10px auto;">&nbsp;</p></div></div></div><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><strong>&#9758; 进一步学习：</strong></p><ol style="margin-left: 2.5rem; padding-left: 0px; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><li style="list-style: inherit;"><a href="http://www.52im.net/thread-227-1-1.html" target="_blank" style="color: #1d58d1; text-decoration: none;">访谈WebRTC标准之父：WebRTC的过去、现在和未来</a></li><li style="list-style: inherit;"><a href="http://www.52im.net/thread-284-1-1.html" target="_blank" style="color: #1d58d1; text-decoration: none;">WebRTC实时音视频技术的整体架构介绍</a></li><li style="list-style: inherit;"><a href="http://www.52im.net/thread-356-1-1.html" target="_blank" style="color: #1d58d1; text-decoration: none;">新手入门：到底什么是WebRTC服务器，以及它是如何联接通话的？</a></li><li style="list-style: inherit;"><a href="http://www.52im.net/thread-442-1-1.html" target="_blank" style="color: #1d58d1; text-decoration: none;">WebRTC实时音视频技术基础：基本架构和协议栈</a></li><li style="list-style: inherit;"><a href="http://www.52im.net/thread-3804-1-1.html" target="_blank" style="color: #1d58d1; text-decoration: none;">实时音视频入门学习：开源工程WebRTC的技术原理和使用浅析</a></li><li style="list-style: inherit;"><a href="http://www.52im.net/thread-4184-1-1.html" target="_blank" style="color: #1d58d1; text-decoration: none;">零基础快速入门WebRTC：基本概念、关键技术、与WebSocket的区别等</a></li></ol><h1>6、兼容性、性能与开发复杂度对比</h1><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">在为 LLM 应用选择实时通信技术时，必须在兼容性、性能和开发复杂度这三个关键维度上进行权衡。本章节将对 Server-Sent Events (SSE)、WebSocket 和 WebRTC 进行全面的横向对比，以揭示它们在不同方面的优劣，从而为技术选型提供数据驱动的依据。</p><h2>6.1 兼容性与平台支持</h2><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">首先，在兼容性与平台支持方面，SSE 和 WebSocket 拥有非常广泛的浏览器支持，几乎覆盖了所有现代浏览器，包括 Chrome、Firefox、Safari 和 Edge。Opera Mini 是少数不支持 WebSocket 和 SSE 的例外。IE 浏览器则完全不支持这两种技术。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">相比之下，WebRTC 的支持范围稍窄一些，IE 不支持，旧版的 Edge 也不支持，但同样广泛应用于其他现代浏览器及其移动端版本。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">对于 LLM 应用而言，这意味着 SSE 和 WebSocket 能够触及更广泛的用户群体。然而，值得注意的是，随着 HTTPS 成为网页标配，HTTP/2 得到了普及，这彻底解决了过去 SSE 在 HTTP/1.1 下因浏览器并发连接数限制（通常是6个）而导致的性能瓶颈，使得 SSE 在现代 Web 架构中表现得更加稳健和高效。</p><h2>6.2 延迟性能</h2><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">其次，延迟性能是衡量实时通信技术优劣的核心指标。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">理论上，WebSocket 具有最低的延迟，因为它在握手完成后就建立了一个纯粹的、无头开销的数据通道。WebRTC 在 P2P 模式下可以实现极低的延迟，因为它避免了服务器中转。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">然而，WebRTC 的延迟受到 NAT/防火墙穿越过程的影响，可能需要 fallback 到较慢的 TURN 中继服务器。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">SSE 的延迟取决于底层的 HTTP 版本。在 HTTP/1.1 下，由于队头阻塞（Head-of-Line Blocking），多个 SSE 连接可能会相互阻塞。但在 HTTP/2 下，得益于其强大的多路复用能力，SSE 的性能得到了极大提升，可以与常规 HTTP 请求并行，延迟接近 WebSocket。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">一项针对真实世界数据流的测试表明，SSE 和 WebSocket 在 EPS（每秒事件数）方面表现出相当的性能，WebSocket 在高并发下略占优势，但差异在实践中往往可以忽略不计。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">因此，对于大多数 LLM 文本流式传输场景，SSE 在 HTTP/2 下已经提供了足够低的延迟。</p><h2>6.3 开发复杂度</h2><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">最后，开发复杂度是决定项目成本和上线速度的关键因素。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">在这三者中，SSE 的开发复杂度最低。它基于标准的 HTTP，开发者可以利用现有的 Web 服务器和工具链，客户端代码也极为简洁，只需几行 JavaScript 即可启动 EventSource 并监听事件。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">WebSocket 的复杂度显著更高。除了协议本身，开发者还需要处理连接管理、状态同步、手动实现心跳包和自动重连逻辑、应对粘性会话（Sticky Sessions）带来的负载均衡挑战，以及在分布式系统中使用 Redis Pub/Sub 等消息队列来广播消息。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">WebRTC 的开发复杂度最高，它不仅包含了上述 WebSocket 的所有挑战，还引入了信令、ICE 候选者收集、STUN/TURN 服务器的配置和维护等一系列全新的难题。此外，WebRTC 的安全模型也更为复杂，需要同时保护信令通道和媒体通道。</p><div img-uploading-status=""  image-package-6"="" data-index="6" style="font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><div><div><img src="https://img2024.cnblogs.com/blog/1834368/202605/1834368-20260526180753070-318268009.png" alt="5" loading="lazy" style="border: 0px; max-width: 100%; height: auto !important; cursor: zoom-in; transition: transform 300ms cubic-bezier(0.2, 0, 0.2, 1) !important;" /><p style="margin: 10px auto;"><strong>综上所述：</strong>SSE 在兼容性、性能和开发复杂度之间取得了最佳平衡，尤其是在 HTTP/2 得到普及的今天。WebSocket 提供了更高的灵活性和更低的理论延迟，但代价是巨大的开发和运维复杂性。WebRTC 则因其固有的复杂性，仅适用于特定的 P2P 和媒体流场景。</p></div></div></div><h1>7、安全性考量与风险缓解策略</h1><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">在 LLM 应用中采用实时通信技术时，安全性是不可忽视的核心要素。本章节将深入探讨 Server-Sent Events (SSE)、WebSocket 和 WebRTC 在安全性方面的关键考量、潜在风险及相应的缓解策略。</p><h2>7.1 Server-Sent Events</h2><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">对于 Server-Sent Events (SSE)，其安全性很大程度上继承自标准的 HTTP 安全模型。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">首要的安全措施是强制使用 HTTPS，因为 SSE 的长期连接窗口使其更容易受到中间人攻击（Man-in-the-Middle），窃听或篡改流中的数据。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">身份验证是另一个关键环节。由于 EventSource API 不支持自定义 HTTP 头部，传统的 JWT 令牌传递变得困难。常见的解决方案是通过 URL 查询参数传递短时效的访问令牌，但这存在安全隐患，因为令牌可能被记录在服务器日志或浏览器历史中。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">另一种更安全的方式是利用带有 SameSite=Strict 属性的 Cookie 来进行认证，这种方式能自动随请求发送，但需要注意 CSRF（跨站请求伪造）攻击的风险，可以通过检查 Origin 头部来缓解。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">此外，SSE 端点容易受到 DoS（拒绝服务）攻击，攻击者可以通过建立大量连接耗尽服务器资源。对此，应实施严格的速率限制，限制来自同一 IP 或用户的并发连接数。</p><h2>7.2 WebSocket</h2><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">WebSocket 的安全性挑战更为复杂。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">虽然 WSS (WebSocket Secure) 使用 TLS 加密来保护数据传输，但其状态化的性质带来了新的攻击面。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">首先，WebSocket 缺乏标准化的身份验证机制，开发者必须自行实现，例如在握手阶段通过 Cookie 或查询参数传递凭证。如果未正确验证 Origin 头部，应用将面临 Cross-Site WebSocket Hijacking (CSWSH) 攻击，恶意网站可以在未经授权的情况下建立 WebSocket 连接并访问敏感数据。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">其次，WebSocket 容易受到 DoS 攻击，特别是通过 Flood 攻击（发送大量小消息或建立海量连接）来耗尽服务器 CPU 或内存。有效的防御措施包括要求连接前进行认证、限制消息大小和频率、以及实施精细的速率控制 [89]。输入数据也可能导致注入攻击，如 SQL 注入或 XSS，因此所有传入的消息都必须经过严格的验证和清理。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">最后，由于 WebSocket 连接是持久的，如果令牌在连接期间过期，可能会导致会话劫持，因此需要实现 token 刷新机制。</p><h2>7.3 WebRTC</h2><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">WebRTC 的安全性设计更为严格，其核心理念是端到端加密。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">所有媒体流都默认使用 SRTP (Secure Real-time Transport Protocol) 加密，而数据通道则使用 DTLS (Datagram Transport Layer Security) 加密，确保只有通信双方可以解密数据。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">然而，WebRTC 的安全性并非万无一失，其脆弱性主要集中在基础设施层面。最著名的安全问题是 IP 地址泄露。由于 ICE 协商需要交换候选者的 IP 地址，即使用户使用了 VPN，其真实的本地和公网 IP 仍可能暴露给通信的另一方，这严重损害了隐私。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">缓解此问题的方法是在网络拓扑中强制使用 TURN 服务器中继，从而隐藏客户端的真实 IP。信令通道的安全性至关重要，如果信令服务器未使用 WSS (WebSocket Secure)&nbsp;或 HTTPS，攻击者可以拦截信令消息，从而发起会话劫持或拒绝服务攻击。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">此外，TURN 服务器若配置不当，可能被滥用进行 DDoS 攻击或数据窃取。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">最后，尽管 WebRTC 协议本身很安全，但其浏览器实现可能存在漏洞，需要及时更新浏览器以修补已知的安全问题。</p><div img-uploading-status=""  image-package-7"="" data-index="7" style="font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><div><div><img src="https://img2024.cnblogs.com/blog/1834368/202605/1834368-20260526180759305-467863608.png" alt="6" loading="lazy" style="border: 0px; max-width: 100%; height: auto !important; cursor: zoom-in; transition: transform 300ms cubic-bezier(0.2, 0, 0.2, 1) !important;" /><p style="margin: 10px auto;">&nbsp;</p></div></div></div><h1>8、架构设计与可扩展性挑战</h1><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">为 LLM 应用选择实时通信技术不仅关乎功能实现，更深刻地影响着系统的整体架构设计和未来的可扩展性。本章节将深入探讨使用 Server-Sent Events (SSE)、WebSocket 和 WebRTC 时面临的架构挑战，特别是在大规模生产环境下的可扩展性问题。</p><h2>8.1 Server-Sent Events</h2><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">使用 Server-Sent Events (SSE) 的架构相对简单且更具弹性。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">由于 SSE 基于标准的 HTTP，它可以轻松地与现有的无状态微服务架构集成。服务器可以水平扩展，因为每个 SSE 连接都是独立的，负载均衡器可以将新连接分发到任何可用的服务器实例。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">然而，当需要向所有订阅用户广播消息时，简单的无状态架构会遇到挑战。解决这个问题的常见模式是引入一个中央消息代理，如 Redis Pub/Sub 或 Kafka。所有服务器实例都订阅同一个 Redis 频道，当有新消息需要广播时，只需将消息发布到该频道，Redis 会将其高效地分发给所有相关的 SSE 客户端。这种发布/订阅（Pub/Sub）模式极大地简化了广播逻辑，并提高了系统的可扩展性。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">此外，SSE 的 stateless nature 使其非常适合在云原生环境中运行，例如 Kubernetes 或 serverless 平台，因为它不需要在节点间共享会话状态。</p><h2>8.2 WebSocket</h2><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">相比之下，WebSocket 的架构设计则充满了挑战，其根本原因在于连接的有状态性。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">每个 WebSocket 连接都会占用服务器的一个文件描述符，并持续消耗内存和 CPU 资源。当用户数量从数百增加到数万甚至数百万时，这种状态化特性会迅速成为瓶颈。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">传统的负载均衡策略（如轮询或最少连接）无法有效分配 WebSocket 连接，因为客户端断线重连后很可能需要回到最初的服务器实例以保持会话状态。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">为了解决这个问题，通常需要采用&#8220;粘性会话&#8221;（Sticky Sessions）或&#8220;会话亲缘性&#8221;（Session Affinity）的负载均衡策略，但这会导致负载分布不均，并形成单点故障。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">更高级的解决方案是构建一个全局状态管理系统，例如将所有连接状态存储在 Redis 等外部数据库中。当服务器 A 接收到需要路由到服务器 B 上某个用户的 WebSocket 消息时，它可以从 Redis 获取目标用户的连接信息并进行转发。这种方法虽然可行，但极大地增加了系统的复杂性和延迟。因此，许多团队最终会选择使用专门的实时通信平台（如 Ably 或 Pusher）来托管这部分基础设施，从而将焦点重新放回业务逻辑上。</p><h2>8.3 WebRTC</h2><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">WebRTC 的可扩展性问题则源于其点对点（P2P）的本质。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">纯 P2P 架构在小规模群组（例如，最多 4-5 人）内工作良好，因为每个参与者只需要与其他成员建立连接即可。然而，当参与者数量增加时，连接数量会呈二次方增长（N&#178; problem），导致每个客户端的带宽和 CPU 负载急剧上升，很快就会超出个人设备的处理能力。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">为了实现 WebRTC 的规模化，必须引入中心化的媒体服务器。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><strong>目前主要有两种架构：</strong></p><ul style="margin-left: 2.5rem; padding-left: 0px; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><li style="list-style: inherit;"><em>1）</em>MCU（Multipoint Control Unit，多点控制单元）；</li><li style="list-style: inherit;"><em>2）</em>SFU（Selective Forwarding Unit，选择性转发单元）。</li></ul><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">MCU 会接收所有参与者的媒体流，进行解码、混音/拼接，然后重新编码成一个新的流再分发给所有人，这样客户端只需接收一个流，但 MCU 承担了巨大的计算压力。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">SFU 则是一种更高效的架构，它只负责将每个参与者发送的媒体流转发给其他所有人，而不进行任何处理，从而将计算负担分散到各个客户端。SFU 是现代大规模 WebRTC 应用（如 Zoom、Google Meet）的首选架构。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">然而，无论是 MCUs 还是 SFUs，都需要大量的服务器资源和复杂的网络基础设施来支持，这对于许多团队来说是一笔巨大的投资。</p><div img-uploading-status=""  image-package-8"="" data-index="8" style="font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><div><div><img src="https://img2024.cnblogs.com/blog/1834368/202605/1834368-20260526180806009-1638170641.png" alt="7" loading="lazy" style="border: 0px; max-width: 100%; height: auto !important; cursor: zoom-in; transition: transform 300ms cubic-bezier(0.2, 0, 0.2, 1) !important;" /><p style="margin: 10px auto;"><strong>总而言之：</strong></p></div></div></div><ul style="margin-left: 2.5rem; padding-left: 0px; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><li style="list-style: inherit;"><em>1）</em>SSE 在可扩展性方面提供了最大的灵活性和成本效益；</li><li style="list-style: inherit;"><em>2）</em>WebSocket 的扩展性挑战巨大，通常需要借助第三方服务或投入大量内部工程资源；</li><li style="list-style: inherit;"><em>3）</em>WebRTC 的扩展性则最为昂贵和复杂，是专门为媒体流设计的，不适合用于普通的文本数据通信。</li></ul><h1>9、最终决策与综合建议</h1><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">在对 Server-Sent Events (SSE)、WebSocket 和 WebRTC 进行了全面的原理、性能、安全性和可扩展性分析之后，本章节将整合所有信息，为 LLM 应用的前后端实时通信提供一个清晰的决策框架，并给出具体的选型建议。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">选择何种技术，最终取决于您的 LLM 应用的具体需求、团队的技术栈和预算。我们可以将 LLM 应用的实时通信场景划分为几个典型的层级，每个层级对应不同的技术最优解。</p><h2>9.1 第一层级：流式文本展示</h2><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">这是最常见的 LLM 应用场景，用户输入一个问题，然后看到答案逐字或逐词地动态呈现出来。这种模式的核心特征是服务器主导的单向数据流。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">在这个场景下，Server-Sent Events (SSE) 是无可争议的最佳选择。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">其理由非常充分：</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><em>1）</em>首先，SSE 的设计初衷就是为此类单向推送而优化的，它比 WebSocket 更加轻量和简单。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><em>2）</em>其次，得益于现代浏览器对 EventSource API 的原生支持，客户端实现极其简单，且内置了可靠的自动重连机制，极大地提升了用户体验和应用的健壮性。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><em>3）</em>再者，SSE 基于标准 HTTP，在部署和运维上非常友好，可以无缝融入现有的 web 服务生态，无需为实时通信单独搭建一套复杂的基础设施。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">Shopify 在其 2022 年黑色星期五活动中的 BFCM Live Map 成功案例，就是一个有力的证明，他们通过 SSE 将毫秒级的数据更新推送给数十万用户，展现了其在生产环境下的强大能力和可扩展性。</p><h2>9.2 第二层级：双向实时互动</h2><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">当应用的需求超越了单向展示，进入真正的&#8220;对话&#8221;或&#8220;协作&#8221;阶段时，就需要选择能够支持客户端和服务器双向通信的技术。在这种情况下，WebSocket 是唯一的选择。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><strong>典型的用例包括：</strong></p><ul style="margin-left: 2.5rem; padding-left: 0px; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><li style="list-style: inherit;"><em>1）</em>语音 I/O：OpenAI 的 Realtime API 就是一个绝佳的例子，它利用 WebSocket 实现了低延迟的语音对话，允许用户在 AI 说话时打断，并即时获得反馈。这种场景需要双向的音频流和命令流，是 WebSocket 的典型应用。</li><li style="list-style: inherit;"><em>2）</em>多智能体系统：当多个 AI Agent 需要在后台协同工作，并需要向前端实时同步各自的思考过程、工具调用结果或状态变化时，WebSocket 提供了必要的双向通道。</li><li style="list-style: inherit;"><em>3）</em>实时协作编辑：当 LLM 作为协作者与用户共同编写代码、文档或进行头脑风暴时，WebSocket 可以确保用户的每一次修改都能被实时同步给 LLM，反之亦然。</li></ul><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">选择 WebSocket 的代价是显著增加的开发和运维复杂度。您需要投入资源来构建和维护一个能够处理成千上万个并发长连接的系统，并解决由此带来的一系列可扩展性问题。</p><h2>9.3 第三层级：点对点媒体流与数据交换</h2><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">这是 WebRTC 的专属领域。虽然 WebRTC 也能传输数据，但它的核心价值在于绕过服务器直接传输高质量的音视频流。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><strong>在 LLM 应用中，WebRTC 的应用场景非常具体且有限：</strong></p><ul style="margin-left: 2.5rem; padding-left: 0px; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><li style="list-style: inherit;"><em>1）</em>高级语音交互：当需要处理原始的、高保真的音频流，而不是经过编码的文本或语音片段时，WebRTC 可能是必要的底层传输协议。</li><li style="list-style: inherit;"><em>2）</em>P2P 文件共享：如果 LLM 应用涉及到用户之间直接通过浏览器共享由 LLM 生成的大文件，WebRTC 的 DataChannel 可以提供一条绕过服务器的高速通道。</li></ul><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">除非您的应用明确属于上述范畴，否则不应轻易选择 WebRTC。它的高昂复杂性和成本使其成为一个非常规的选择。</p><h2>9.4 综合决策框架</h2><div img-uploading-status=""  image-package-9"="" data-index="9" style="font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;"><div><div><img src="https://img2024.cnblogs.com/blog/1834368/202605/1834368-20260526180812249-756717547.png" alt="8" loading="lazy" style="border: 0px; max-width: 100%; height: auto !important; cursor: zoom-in; transition: transform 300ms cubic-bezier(0.2, 0, 0.2, 1) !important;" /><p style="margin: 10px auto;">&nbsp;</p></div></div></div><h2>9.5 最终结论与建议</h2><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">对于绝大多数 LLM 应用的前后端通信需求，我们强烈建议从 Server-Sent Events (SSE) 开始。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">它足够强大，足以满足当前主流的流式文本展示需求，同时又足够简单，能让团队快速迭代产品。不要为了所谓的&#8220;先进性&#8221;或过度设计而一开始就选择更复杂的 WebSocket。只有当业务发展到确实需要双向、低延迟的实时互动时，才应该评估并投入资源迁移到 WebSocket。</p><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">记住，没有一种技术是完美的，最好的技术是那个能够以最低的成本和复杂度解决你当前问题的技术。</p><h1>10、参考资料</h1><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">[0]&nbsp;<a href="https://developer.mozilla.org/zh-CN/docs/Web/API/EventSource" target="_blank" style="color: #1d58d1; text-decoration: none;">EventSource API Docs</a><br />[1]&nbsp;<a href="http://www.52im.net/thread-336-1-1.html" target="_blank" style="color: #1d58d1; text-decoration: none;">Web端即时通讯技术盘点：短轮询、Comet、Websocket、SSE</a><br />[2]&nbsp;<a href="http://www.52im.net/thread-335-1-1.html" target="_blank" style="color: #1d58d1; text-decoration: none;">SSE技术详解：一种全新的HTML5服务器推送事件技术</a><br />[3]&nbsp;<a href="http://www.52im.net/thread-907-1-1.html" target="_blank" style="color: #1d58d1; text-decoration: none;">使用WebSocket和SSE技术实现Web端消息推送</a><br />[4]&nbsp;<a href="http://www.52im.net/thread-1038-1-1.html" target="_blank" style="color: #1d58d1; text-decoration: none;">详解Web端通信方式的演进：从Ajax、JSONP 到 SSE、Websocket</a><br />[5]&nbsp;<a href="http://www.52im.net/thread-907-1-1.html" target="_blank" style="color: #1d58d1; text-decoration: none;">使用WebSocket和SSE技术实现Web端消息推送</a><br />[6]&nbsp;<a href="http://www.52im.net/thread-2719-1-1.html" target="_blank" style="color: #1d58d1; text-decoration: none;">一文读懂前端技术演进：盘点Web前端20年的技术变迁史</a><br />[7]&nbsp;<a href="http://www.52im.net/thread-3134-1-1.html" target="_blank" style="color: #1d58d1; text-decoration: none;">WebSocket从入门到精通，半小时就够！</a><br />[8]&nbsp;<a href="http://www.52im.net/thread-3555-1-1.html" target="_blank" style="color: #1d58d1; text-decoration: none;">网页端IM通信技术快速入门：短轮询、长轮询、SSE、WebSocket</a><br />[9]&nbsp;<a href="http://www.52im.net/thread-3695-1-1.html" target="_blank" style="color: #1d58d1; text-decoration: none;">搞懂现代Web端即时通讯技术一文就够：WebSocket、socket.io、SSE</a><br />[10]&nbsp;<a href="http://www.52im.net/thread-442-1-1.html" target="_blank" style="color: #1d58d1; text-decoration: none;">WebRTC实时音视频技术基础：基本架构和协议栈</a><br />[11]&nbsp;<a href="http://www.52im.net/thread-3680-1-1.html" target="_blank" style="color: #1d58d1; text-decoration: none;">零基础入门：基于开源WebRTC，从0到1实现实时音视频聊天功能</a><br />[12]&nbsp;<a href="http://www.52im.net/thread-3804-1-1.html" target="_blank" style="color: #1d58d1; text-decoration: none;">实时音视频入门学习：开源工程WebRTC的技术原理和使用浅析</a><br />[13]&nbsp;<a href="http://www.52im.net/thread-4184-1-1.html" target="_blank" style="color: #1d58d1; text-decoration: none;">零基础快速入门WebRTC：基本概念、关键技术、与WebSocket的区别等</a><br />[14]&nbsp;<a href="http://www.52im.net/thread-4831-1-1.html" target="_blank" style="color: #1d58d1; text-decoration: none;">大模型时代多模型AI网关的架构设计与实现</a><br />[15]&nbsp;<a href="http://www.52im.net/thread-4797-1-1.html" target="_blank" style="color: #1d58d1; text-decoration: none;">全民AI时代，大模型客户端和服务端的实时通信到底用什么协议？</a><br />[16]&nbsp;<a href="http://www.52im.net/thread-4856-1-1.html" target="_blank" style="color: #1d58d1; text-decoration: none;">通俗易懂：AI大模型基于SSE的实时流式响应技术原理和实践示例</a><br />[17]&nbsp;<a href="http://www.52im.net/thread-4832-1-1.html" target="_blank" style="color: #1d58d1; text-decoration: none;">Web端实时通信技术SSE在携程机票业务中的实践应用</a><br />[18]&nbsp;<a href="http://www.52im.net/thread-4872-1-1.html" target="_blank" style="color: #1d58d1; text-decoration: none;">ChatGPT如何实现聊天一样的实时交互？快速读懂SSE实时&#8220;推&#8221;技术</a></p><blockquote style="background-image: none; border-width: medium medium medium 3px; border-style: none none none solid; border-color: currentcolor currentcolor currentcolor #e2dfdf; margin: 10px 0px; background-color: #eeeeee; width: 896px; color: #555555; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif;"><p style="margin: 10px auto;"><strong>即时通讯技术学习：</strong></p><p style="margin: 10px auto;">- 移动端IM开发入门文章：《<a href="http://www.52im.net/thread-464-1-1.html" rel="noopener nofollow" target="_blank" style="color: #1d58d1; text-decoration: none;">新手入门一篇就够：从零开发移动端IM</a>》</p><p style="margin: 10px auto;">- 开源IM框架源码：<a href="https://github.com/JackJiang2011/MobileIMSDK" rel="noopener nofollow" target="_blank" style="color: #1d58d1; text-decoration: none;">https://github.com/JackJiang2011/MobileIMSDK</a>（<a href="https://gitee.com/jackjiang/MobileIMSDK" rel="noopener nofollow" target="_blank" style="color: #1d58d1; text-decoration: none;">备用地址点此</a>）</p></blockquote><p style="margin: 10px auto; font-family: &quot;PingFang SC&quot;, &quot;Microsoft YaHei&quot;, &quot;Helvetica Neue&quot;, Helvetica, Arial, sans-serif; background-color: #ffffff;">（本文同步发布于：<a href="http://www.52im.net/thread-4909-1-1.html" target="_blank" style="color: #1d58d1; text-decoration: none;">http://www.52im.net/thread-4909-1-1.html</a>）</p><img src ="http://www.blogjava.net/jb2011/aggbug/451783.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/jb2011/" target="_blank">Jack Jiang</a> 2026-05-28 11:57 <a href="http://www.blogjava.net/jb2011/archive/2026/05/28/451783.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>