<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>服务治理 on 止语Lab</title>
        <link>https://www.wujiachen.com.cn/tags/%E6%9C%8D%E5%8A%A1%E6%B2%BB%E7%90%86/</link>
        <description>Recent content in 服务治理 on 止语Lab</description>
        <generator>Hugo -- gohugo.io</generator>
        <language>zh-cn</language>
        <lastBuildDate>Tue, 02 Jun 2026 22:52:33 +0800</lastBuildDate><atom:link href="https://www.wujiachen.com.cn/tags/%E6%9C%8D%E5%8A%A1%E6%B2%BB%E7%90%86/index.xml" rel="self" type="application/rss+xml" /><item>
            <title>为什么大厂还在用 RPC？不是因为快，是因为不崩</title>
            <link>https://www.wujiachen.com.cn/posts/rpc-vs-http/</link>
            <pubDate>Tue, 02 Jun 2026 22:52:31 +0800</pubDate>
            <guid>https://www.wujiachen.com.cn/posts/rpc-vs-http/</guid>
            <description>&lt;img src=&#34;https://img.wujiachen.com.cn/rpc-vs-http/cover.png&#34; alt=&#34;Featured image of post 为什么大厂还在用 RPC？不是因为快，是因为不崩&#34; /&gt;&lt;p&gt;&#xA;    &lt;img src=&#34;https://img.wujiachen.com.cn/rpc-vs-http/cover.png&#34; alt=&#34;封面&#34; loading=&#34;lazy&#34;&gt;&lt;/p&gt;&#xA;&#xA;    &lt;blockquote&gt;&#xA;        &lt;p&gt;所有&amp;quot;RPC 比 HTTP 快&amp;quot;的对比文章，多数拿 HTTP/1.1+JSON 当对手。换成 HTTP/2 之后呢？我跑了实验，协议层的差距在你大部分接口里是个位数百分比。那大厂为什么还在用 RPC？答案不在协议层。&lt;/p&gt;&#xA;&#xA;    &lt;/blockquote&gt;&#xA;&lt;h2 id=&#34;一那天凌晨三点我们的服务挂了&#34;&gt;&lt;a href=&#34;#%e4%b8%80%e9%82%a3%e5%a4%a9%e5%87%8c%e6%99%a8%e4%b8%89%e7%82%b9%e6%88%91%e4%bb%ac%e7%9a%84%e6%9c%8d%e5%8a%a1%e6%8c%82%e4%ba%86&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;一、那天凌晨三点，我们的服务挂了&#xA;&lt;/h2&gt;&lt;p&gt;凌晨三点二十一分，电话把我吵醒。&lt;/p&gt;&#xA;&lt;p&gt;值班同学的声音在那头发抖：&amp;ldquo;订单接口全挂了，下游全在超时，连查询都打不开。&amp;rdquo;&lt;/p&gt;&#xA;&lt;p&gt;我抓起电脑接上 VPN，打开监控。一整列接口的 P99 延迟都飙到 30 秒——也就是 Nginx 的网关超时。底下用户正在双十二大促，每秒几千单。我盯着监控大屏，心里只有一个问题：&lt;strong&gt;到底是哪个环节先崩的？&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;那时候我们的架构很简单：所有服务之间用 HTTP/1.1 + JSON 互相调用。Spring Boot + Nginx + Eureka，在内网里跑。说实话，我之前以为这套挺好用的——直到那一晚。&lt;/p&gt;&#xA;&lt;p&gt;后面复盘，事故链是这样的：&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;一个不重要的&amp;quot;积分计算&amp;quot;接口突然变慢（下游 Redis 集群有抖动）&lt;/li&gt;&#xA;&lt;li&gt;上游的&amp;quot;下单&amp;quot;服务每次调用都等到超时——但&lt;strong&gt;没有超时上限&lt;/strong&gt;，连接池一格一格被卡住&lt;/li&gt;&#xA;&lt;li&gt;卡住之后，&amp;ldquo;下单&amp;quot;服务的连接池打满，新请求开始排队&lt;/li&gt;&#xA;&lt;li&gt;排队太久，Nginx 那一层的健康检查超时，开始把&amp;quot;下单&amp;quot;服务标成不可用&lt;/li&gt;&#xA;&lt;li&gt;流量被甩到剩下的实例上，那些实例也因为同样的下游问题，几秒后步入同样的命运&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;整条调用链垮了&lt;/strong&gt;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;p&gt;我们花了 47 分钟把它拉回来——靠的不是什么聪明的工程手段，是手动重启每一个被卡死的服务，把&amp;quot;积分计算&amp;quot;这个不重要的功能直接降级成&amp;quot;返回 0&amp;rdquo;。&lt;/p&gt;&#xA;&lt;p&gt;&#xA;    &lt;img src=&#34;https://img.wujiachen.com.cn/rpc-vs-http/ch1-avalanche-flow.png&#34; alt=&#34;雪崩传播路径示意图&#34; loading=&#34;lazy&#34;&gt; [16:9]&lt;/p&gt;&#xA;&lt;p&gt;那一晚我没再睡。坐在工位上想了很多事。第二天复盘会上有人提出来：要不要换 RPC 框架？&lt;/p&gt;&#xA;&lt;p&gt;我当时的第一反应是抗拒——RPC 不就是为了&amp;quot;更快&amp;quot;吗？我们这点流量，&amp;ldquo;快不快&amp;quot;根本不是瓶颈。&lt;strong&gt;改框架的成本谁来承担？&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;但接下来三个月发生的事，让我把这句话原封不动地咽了回去。&lt;/p&gt;&#xA;&lt;p&gt;先记住这个画面：&lt;strong&gt;接口崩的时候，崩的不是协议，是没有刹车的调用链。&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;hr&gt;&#xA;&lt;h2 id=&#34;二所有rpc-更快的文章都选错了对手&#34;&gt;&lt;a href=&#34;#%e4%ba%8c%e6%89%80%e6%9c%89rpc-%e6%9b%b4%e5%bf%ab%e7%9a%84%e6%96%87%e7%ab%a0%e9%83%bd%e9%80%89%e9%94%99%e4%ba%86%e5%af%b9%e6%89%8b&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;二、所有&amp;quot;RPC 更快&amp;quot;的文章都选错了对手&#xA;&lt;/h2&gt;&lt;p&gt;雪崩之后，我第一件事是研究 RPC。我打开搜索引擎，搜&amp;quot;RPC 比 HTTP 快多少&amp;rdquo;——好家伙，铺天盖地的文章告诉我&amp;quot;RPC 快 5 倍 / 10 倍 / 20 倍&amp;quot;。&lt;/p&gt;&#xA;&lt;p&gt;我一篇一篇看。看到第六篇我笑了。&lt;/p&gt;&#xA;&lt;p&gt;我翻了一圈，绝大多数文章，对手都是 HTTP/1.1 + JSON。&lt;/p&gt;&#xA;&lt;p&gt;这就像两个人比谁跑得快，一个穿钉鞋，另一个穿拖鞋。然后告诉你：钉鞋跑得真快。&lt;/p&gt;&#xA;&lt;p&gt;让我把现有的&amp;quot;RPC 更快&amp;quot;论证拆给你看。它们的套路高度一致，就这三招：&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;第一招：HTTP 头巨大。&lt;/strong&gt;&#xA;他们说，HTTP/1.1 每次请求要发好几百字节的纯文本头部，又是 &lt;code&gt;Content-Type&lt;/code&gt; 又是 &lt;code&gt;Accept&lt;/code&gt;，开销巨大。&#xA;听起来很合理对吧？但你打开 HTTP/2 的 RFC 看看——HPACK 头部压缩在 2015 年就已经标准化。同样的头部，HTTP/2 走二进制 + 静态字典，重复头部通过动态表索引压缩后通常只需 1-2 字节。这一招在 HTTP/2 面前直接报废。&lt;/p&gt;&#xA;&lt;p&gt;而且你想想，这个时代谁还在生产环境用纯 HTTP/1.1？除了一些老遗留系统和外部 API，几乎所有现代微服务网关——Envoy、Nginx 1.9.5+、ALB（对外入口侧默认 HTTP/2，到后端 upstream 需显式配置）、API Gateway——基本都在用 HTTP/2。你拿 HTTP/1.1 的头部开销出来吓人，约等于拿 32 位系统说事——理论上没错，现实里离我们已经很远。&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;第二招：JSON 序列化慢。&lt;/strong&gt;&#xA;他们说，文本协议比二进制协议解析慢一个数量级。&#xA;这话本身没错。但 JSON 的对手不是 HTTP，是序列化方案。HTTP 完全可以走 Protobuf、可以走 MessagePack、可以走任何二进制协议——只是大多数人懒得换罢了。把&amp;quot;序列化方案&amp;quot;算到&amp;quot;协议&amp;quot;头上，本身就是偷换概念。&lt;/p&gt;&#xA;&lt;p&gt;打个比方。你说&amp;quot;开高铁比开汽车快&amp;quot;——这成立。但你说&amp;quot;开高铁比开汽车快，因为高铁烧的是电&amp;quot;——这就不对了。烧电是动力来源，不是速度差距的根本原因；快是因为它跑在专线轨道上。把&amp;quot;序列化方式&amp;quot;算到&amp;quot;协议&amp;quot;头上，犯的就是这种错。HTTP 完全可以载二进制，gRPC 跑在 HTTP/2 上就是最好的证明。&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;第三招：连接握手开销大。&lt;/strong&gt;&#xA;他们说，HTTP 每次请求要重新握手。&#xA;这一招最离谱。Keep-Alive 是 1997 年的 HTTP/1.1 RFC 写进去的，连接复用早就是默认行为。任何一个稍微正经一点的 client 都不会每次重新建连。&lt;/p&gt;&#xA;&lt;p&gt;你打开 Java 的 Apache HttpClient、Go 的 &lt;code&gt;http.Transport&lt;/code&gt;、Python 的 &lt;code&gt;requests.Session&lt;/code&gt;——它们底层全都是连接池，全都是 Keep-Alive。会让你&amp;quot;每次重新握手&amp;quot;的写法，是 PHP 早期那种 &lt;code&gt;file_get_contents&lt;/code&gt; 短连接调用——但那已经是十几年前的故事了。&lt;/p&gt;&#xA;&lt;p&gt;三招都打偏。那为什么这些文章看起来还挺有道理？&lt;/p&gt;&#xA;&lt;p&gt;因为他们对比的是 2010 年的 HTTP，对比的是没人用心配过的客户端，对比的是教科书里那张&amp;quot;OSI 七层&amp;quot;的简化图。他们没在拿你今天用的东西做对比。&lt;/p&gt;&#xA;&lt;p&gt;而你今天用的东西是什么？&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;gRPC = HTTP/2 + Protobuf + 一套 IDL&lt;/li&gt;&#xA;&lt;li&gt;Dubbo = TCP + Hessian/Protobuf + 注册中心（Dubbo 3.x 起主流版本默认已改用基于 HTTP/2 的 Triple 协议，兼容 gRPC）&lt;/li&gt;&#xA;&lt;li&gt;现代 HTTP 服务 = HTTP/2 + Protobuf 或 JSON + Keep-Alive&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;你看，&lt;strong&gt;gRPC 本身就是 HTTP/2&lt;/strong&gt;。这两个东西在协议层面已经是一家人了。&lt;/p&gt;&#xA;&lt;p&gt;&#xA;    &lt;img src=&#34;https://img.wujiachen.com.cn/rpc-vs-http/ch2-wrong-opponent.png&#34; alt=&#34;“选错对手&amp;#34;对比图&#34; loading=&#34;lazy&#34;&gt; [3:2]&lt;/p&gt;&#xA;&lt;p&gt;那 RPC 和 HTTP 的边界到底在哪？&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;不在协议层。在框架层。&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;但要论证这一点，光说不够。我得让数据说话。&lt;/p&gt;&#xA;&lt;hr&gt;&#xA;&lt;h2 id=&#34;三实测协议优化的真实收益只有-5&#34;&gt;&lt;a href=&#34;#%e4%b8%89%e5%ae%9e%e6%b5%8b%e5%8d%8f%e8%ae%ae%e4%bc%98%e5%8c%96%e7%9a%84%e7%9c%9f%e5%ae%9e%e6%94%b6%e7%9b%8a%e5%8f%aa%e6%9c%89-5&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;三、实测：协议优化的真实收益只有 5%&#xA;&lt;/h2&gt;&lt;p&gt;我写了两组实验。第一组对比三种协议组合的吞吐和延迟，第二组拆解一次真实调用的各环节耗时。代码全部开源，你可以自己跑。&lt;/p&gt;&#xA;&lt;h3 id=&#34;实验一三种协议组合谁更快&#34;&gt;&lt;a href=&#34;#%e5%ae%9e%e9%aa%8c%e4%b8%80%e4%b8%89%e7%a7%8d%e5%8d%8f%e8%ae%ae%e7%bb%84%e5%90%88%e8%b0%81%e6%9b%b4%e5%bf%ab&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;实验一：三种协议组合，谁更快？&#xA;&lt;/h3&gt;&lt;p&gt;我用 Go 起了三个服务，跑同一个接口（返回一个用户对象），用 32 个并发 worker 持续打 5 秒：&lt;/p&gt;&#xA;&lt;table&gt;&#xA;  &lt;thead&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;th&gt;方案&lt;/th&gt;&#xA;          &lt;th style=&#34;text-align: right&#34;&gt;QPS&lt;/th&gt;&#xA;          &lt;th style=&#34;text-align: right&#34;&gt;P50 延迟&lt;/th&gt;&#xA;          &lt;th style=&#34;text-align: right&#34;&gt;P99 延迟&lt;/th&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/thead&gt;&#xA;  &lt;tbody&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;HTTP/1.1 + JSON&lt;/td&gt;&#xA;          &lt;td style=&#34;text-align: right&#34;&gt;&lt;strong&gt;104,841&lt;/strong&gt;&lt;/td&gt;&#xA;          &lt;td style=&#34;text-align: right&#34;&gt;276µs&lt;/td&gt;&#xA;          &lt;td style=&#34;text-align: right&#34;&gt;919µs&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;HTTP/2 + JSON&lt;/td&gt;&#xA;          &lt;td style=&#34;text-align: right&#34;&gt;77,007&lt;/td&gt;&#xA;          &lt;td style=&#34;text-align: right&#34;&gt;404µs&lt;/td&gt;&#xA;          &lt;td style=&#34;text-align: right&#34;&gt;848µs&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;HTTP/2 + 二进制&lt;/td&gt;&#xA;          &lt;td style=&#34;text-align: right&#34;&gt;77,804&lt;/td&gt;&#xA;          &lt;td style=&#34;text-align: right&#34;&gt;403µs&lt;/td&gt;&#xA;          &lt;td style=&#34;text-align: right&#34;&gt;837µs&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/tbody&gt;&#xA;&lt;/table&gt;&#xA;&#xA;    &lt;blockquote&gt;&#xA;        &lt;p&gt;实验配置：macOS / Go 1.26.2 / 同主机 loopback / 32 worker / 5s。响应大小：HTTP/1.1+JSON 179 B，HTTP/2+二进制 84 B。代码在 &lt;code&gt;evidence/code/e1-protocol-bench/&lt;/code&gt;，可复现。&lt;/p&gt;&#xA;&#xA;    &lt;/blockquote&gt;&#xA;&lt;p&gt;HTTP/1.1 + JSON 的 QPS 居然最高——这不是我特意挑的反差数据。同主机 loopback 消除了网络往返延迟，HTTP/2 多路复用的核心价值（减少 RTT 等待）在这个场景根本无法体现；叠加 HTTP/2 帧处理的额外 CPU 开销，导致同机测试 QPS 反不如 HTTP/1.1。换到真实跨机网络环境，HTTP/2 会反超回来，但反超的幅度也就 10~20%，不是数量级。这组数据更重要的结论是实验本身的局限——loopback 场景不是 HTTP/2 的主场，别拿这组数字去反推生产决策。&lt;/p&gt;&#xA;&lt;p&gt;&#xA;    &lt;img src=&#34;https://img.wujiachen.com.cn/rpc-vs-http/ch3-e1-protocol-table.png&#34; alt=&#34;E1 协议对比表&#34; loading=&#34;lazy&#34;&gt; [3:2]&lt;/p&gt;&#xA;&lt;p&gt;更有趣的是 HTTP/2 + JSON vs HTTP/2 + 二进制的对比：P50 差距只有 &lt;strong&gt;1µs&lt;/strong&gt;——百万分之一秒。把 JSON 换成二进制压缩到 47% 体积，端到端延迟几乎看不出来。&lt;/p&gt;&#xA;&lt;p&gt;为什么？因为响应本身才 179 字节。你省下 95 字节，在万兆网卡上根本不够看。&lt;/p&gt;&#xA;&lt;p&gt;那序列化本身呢？我专门跑了一组：&lt;/p&gt;&#xA;&lt;table&gt;&#xA;  &lt;thead&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;th&gt;操作&lt;/th&gt;&#xA;          &lt;th style=&#34;text-align: right&#34;&gt;JSON&lt;/th&gt;&#xA;          &lt;th style=&#34;text-align: right&#34;&gt;二进制&lt;/th&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/thead&gt;&#xA;  &lt;tbody&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;编码 50000 次平均&lt;/td&gt;&#xA;          &lt;td style=&#34;text-align: right&#34;&gt;253ns&lt;/td&gt;&#xA;          &lt;td style=&#34;text-align: right&#34;&gt;115ns&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;解码 50000 次平均&lt;/td&gt;&#xA;          &lt;td style=&#34;text-align: right&#34;&gt;1.367µs&lt;/td&gt;&#xA;          &lt;td style=&#34;text-align: right&#34;&gt;217ns&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/tbody&gt;&#xA;&lt;/table&gt;&#xA;&lt;p&gt;二进制确实更快——快了一个数量级。但&lt;strong&gt;单位是纳秒&lt;/strong&gt;。换算到端到端，这点差距完全被网络抖动淹没。&lt;/p&gt;&#xA;&lt;p&gt;到这里你应该有个直觉：&lt;strong&gt;协议层的优化空间，比你想象的小得多。&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;但直觉不算证据。我得给你看真正的拆解。&lt;/p&gt;&#xA;&lt;h3 id=&#34;实验二一次调用的时间都花在哪了&#34;&gt;&lt;a href=&#34;#%e5%ae%9e%e9%aa%8c%e4%ba%8c%e4%b8%80%e6%ac%a1%e8%b0%83%e7%94%a8%e7%9a%84%e6%97%b6%e9%97%b4%e9%83%bd%e8%8a%b1%e5%9c%a8%e5%93%aa%e4%ba%86&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;实验二：一次调用的时间都花在哪了？&#xA;&lt;/h3&gt;&lt;p&gt;第二个实验把端到端调用拆成可测量的几段。业务逻辑用 &lt;code&gt;sleep 10ms&lt;/code&gt; 模拟，代表轻量级场景（这是本实验的基准假设，代表轻量级 DB 查询；真实生产 P99 常见 50-200ms，见下方敏感性分析）。&lt;/p&gt;&#xA;&lt;p&gt;跑 1000 次取中位数：&lt;/p&gt;&#xA;&lt;table&gt;&#xA;  &lt;thead&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;th&gt;环节&lt;/th&gt;&#xA;          &lt;th style=&#34;text-align: right&#34;&gt;中位耗时&lt;/th&gt;&#xA;          &lt;th style=&#34;text-align: right&#34;&gt;占总耗时&lt;/th&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/thead&gt;&#xA;  &lt;tbody&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;请求序列化（JSON Marshal）&lt;/td&gt;&#xA;          &lt;td style=&#34;text-align: right&#34;&gt;2.79µs&lt;/td&gt;&#xA;          &lt;td style=&#34;text-align: right&#34;&gt;&lt;strong&gt;0.02%&lt;/strong&gt;&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;网络栈 + 协议处理&lt;/td&gt;&#xA;          &lt;td style=&#34;text-align: right&#34;&gt;1.91ms&lt;/td&gt;&#xA;          &lt;td style=&#34;text-align: right&#34;&gt;&lt;strong&gt;15.96%&lt;/strong&gt;&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;业务逻辑（DB / 下游调用）&lt;/td&gt;&#xA;          &lt;td style=&#34;text-align: right&#34;&gt;10ms&lt;/td&gt;&#xA;          &lt;td style=&#34;text-align: right&#34;&gt;&lt;strong&gt;83.64%&lt;/strong&gt;&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;响应反序列化（JSON Unmarshal）&lt;/td&gt;&#xA;          &lt;td style=&#34;text-align: right&#34;&gt;24.25µs&lt;/td&gt;&#xA;          &lt;td style=&#34;text-align: right&#34;&gt;&lt;strong&gt;0.20%&lt;/strong&gt;&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;&lt;strong&gt;端到端 P50&lt;/strong&gt;&lt;/td&gt;&#xA;          &lt;td style=&#34;text-align: right&#34;&gt;&lt;strong&gt;11.96ms&lt;/strong&gt;&lt;/td&gt;&#xA;          &lt;td style=&#34;text-align: right&#34;&gt;100%&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/tbody&gt;&#xA;&lt;/table&gt;&#xA;&#xA;    &lt;blockquote&gt;&#xA;        &lt;p&gt;实验代码：&lt;code&gt;evidence/code/e2-latency-breakdown/&lt;/code&gt;&lt;/p&gt;&#xA;&#xA;    &lt;/blockquote&gt;&#xA;&lt;p&gt;序列化加反序列化加起来，&lt;strong&gt;0.22%&lt;/strong&gt;。&lt;/p&gt;&#xA;&lt;p&gt;那协议层（网络栈+协议处理）的 16% 看起来挺可观——但别急。这个 16% 是建立在&amp;quot;业务只要 10ms&amp;quot;这种轻量场景下的。真实业务有多重？我做了敏感性分析：&lt;/p&gt;&#xA;&lt;table&gt;&#xA;  &lt;thead&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;th style=&#34;text-align: center&#34;&gt;业务逻辑耗时&lt;/th&gt;&#xA;          &lt;th style=&#34;text-align: center&#34;&gt;协议+序列化占比&lt;/th&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/thead&gt;&#xA;  &lt;tbody&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td style=&#34;text-align: center&#34;&gt;10ms&lt;/td&gt;&#xA;          &lt;td style=&#34;text-align: center&#34;&gt;16.19%&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td style=&#34;text-align: center&#34;&gt;20ms&lt;/td&gt;&#xA;          &lt;td style=&#34;text-align: center&#34;&gt;8.82%&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td style=&#34;text-align: center&#34;&gt;&lt;strong&gt;50ms&lt;/strong&gt;&lt;/td&gt;&#xA;          &lt;td style=&#34;text-align: center&#34;&gt;&lt;strong&gt;3.73%&lt;/strong&gt;&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td style=&#34;text-align: center&#34;&gt;100ms&lt;/td&gt;&#xA;          &lt;td style=&#34;text-align: center&#34;&gt;1.90%&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/tbody&gt;&#xA;&lt;/table&gt;&#xA;&lt;p&gt;&lt;strong&gt;业务越重，协议层占比越小。&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;&#xA;    &lt;img src=&#34;https://img.wujiachen.com.cn/rpc-vs-http/ch3-latency-breakdown.png&#34; alt=&#34;端到端延迟堆叠条形图&#34; loading=&#34;lazy&#34;&gt; [3:2]&lt;/p&gt;&#xA;&lt;p&gt;而典型微服务的业务逻辑（不算下游调用）通常 20~50ms。&lt;strong&gt;在你大部分接口里，协议层优化的天花板是个位数百分比。&lt;/strong&gt;&lt;/p&gt;&#xA;&#xA;    &lt;blockquote&gt;&#xA;        &lt;p&gt;你花一周时间把所有接口从 JSON 切到 Protobuf——也许能省下 5% 的端到端延迟。&#xA;而你的下游服务慢了 50ms——直接把整条链路打崩。&lt;/p&gt;&#xA;&lt;p&gt;哪个更值得你关心？&lt;/p&gt;&#xA;&#xA;    &lt;/blockquote&gt;&#xA;&lt;p&gt;这就是为什么我看到那些&amp;quot;RPC 比 HTTP 快 10 倍&amp;quot;的标题想笑。不是说他们撒谎——他们确实测出了协议层的差距——而是他们测对了一个没人在乎的指标。&lt;/p&gt;&#xA;&#xA;    &lt;blockquote&gt;&#xA;        &lt;p&gt;这一章不是说协议优化没价值。10w QPS 量级以上的核心链路，省 5% 是真金白银。问题是，绝大多数业务系统连 1w QPS 都到不了——你优化协议，是给空气省时间。&lt;/p&gt;&#xA;&#xA;    &lt;/blockquote&gt;&#xA;&lt;hr&gt;&#xA;&lt;h2 id=&#34;四真正的胜负手是出问题的那一刻&#34;&gt;&lt;a href=&#34;#%e5%9b%9b%e7%9c%9f%e6%ad%a3%e7%9a%84%e8%83%9c%e8%b4%9f%e6%89%8b%e6%98%af%e5%87%ba%e9%97%ae%e9%a2%98%e7%9a%84%e9%82%a3%e4%b8%80%e5%88%bb&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;四、真正的胜负手是出问题的那一刻&#xA;&lt;/h2&gt;&lt;p&gt;回到我开头讲的那个雪崩之夜。&lt;/p&gt;&#xA;&lt;p&gt;复盘那天我画了一张图。把整个事故的传播路径画出来之后，我盯着它发呆——&lt;strong&gt;没有一个环节是被&amp;quot;协议慢&amp;quot;杀死的&lt;/strong&gt;。&lt;/p&gt;&#xA;&lt;p&gt;杀死系统的是这几个东西：&lt;/p&gt;&#xA;&lt;p&gt;超时没有上限——下游一慢，上游连接池就成了无底洞，慢慢被卡死。熔断器不存在，&amp;ldquo;积分计算&amp;quot;连续失败几百次，调用方还在继续发。一个非核心接口出了问题，没有任何机制把它从主链路隔离出去。下游越慢，上游排队越积越多，雪上加霜。&lt;/p&gt;&#xA;&lt;p&gt;这四个东西是什么？是&lt;strong&gt;服务治理&lt;/strong&gt;。&lt;/p&gt;&#xA;&lt;p&gt;而 RPC 框架——我说的是接入公司内部治理 SDK（或 Service Mesh 层）之后的真实 RPC 框架，gRPC、Dubbo（Triple）、Tars（腾讯生态）、Thrift——给你的是什么？&lt;/p&gt;&#xA;&lt;p&gt;这些能力，在接入治理 SDK 后都有。&lt;/p&gt;&#xA;&#xA;    &lt;blockquote&gt;&#xA;        &lt;p&gt;注：gRPC 裸框架本身提供 deadline、拦截器、客户端侧负载均衡，不内置熔断/限流/降级。这些治理能力来自：①公司内部封装的治理 SDK（如 tRPC-Go 的内置治理能力）②Sentinel/Resilience4j 独立集成③Istio/Envoy Service Mesh。以下讨论基于公司内部封装的 gRPC 治理 SDK 场景。&lt;/p&gt;&#xA;&#xA;    &lt;/blockquote&gt;&#xA;&lt;p&gt;让我把同样的雪崩场景，搬到接入治理 SDK 的 RPC 框架下推演一遍：&lt;/p&gt;&#xA;&#xA;    &lt;blockquote&gt;&#xA;        &lt;p&gt;以下是基于工程常识的场景推演，不是某次真实事故的实测复盘——但雪崩演进的典型路径就是这样。&lt;/p&gt;&#xA;&#xA;    &lt;/blockquote&gt;&#xA;&lt;p&gt;&lt;strong&gt;纯 HTTP（无治理）的故障演进：&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;T+0s   下游 Redis 抖动，「积分计算」开始变慢&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;T+5s   上游连接池开始堆积，未完成请求 1000 → 5000&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;T+15s  连接池打满，新请求直接报错 &amp;#34;no available connection&amp;#34;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;T+30s  Nginx 健康检查失败，把上游实例标记下线&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;T+45s  剩余实例承接全部流量，依次进入相同状态&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;T+60s  整条调用链不可用&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;注意第二步——&amp;ldquo;连接池开始堆积&amp;rdquo;。这是雪崩的起点。HTTP/1.1 的默认 client 行为，在大多数语言里都没有强制的&amp;quot;等待上限&amp;rdquo;。你可以加 &lt;code&gt;timeout&lt;/code&gt;，但要有人记得加。你的整个团队，里里外外几十个调用点，每一个都加对了吗？这是个赌局，赌输的代价就是某天凌晨三点的电话。&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;RPC 框架（接入治理 SDK）的故障演进：&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-fallback&#34; data-lang=&#34;fallback&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;T+0s   下游 Redis 抖动，「积分计算」开始变慢&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;T+2s   SDK 强制的超时上限触发，调用方快速失败&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;T+5s   服务治理层识别连续失败，「积分计算」被熔断&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;T+5s   后续请求直接走 fallback 逻辑（返回默认积分 0）&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;T+10s  下游恢复，熔断器进入 half-open，自动恢复&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;T+15s  全链路恢复正常&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;差别在&lt;strong&gt;有没有刹车&lt;/strong&gt;。&lt;/p&gt;&#xA;&lt;p&gt;更深一层：差别在&lt;strong&gt;默认行为&lt;/strong&gt;。&lt;/p&gt;&#xA;&lt;p&gt;HTTP 的默认行为是&amp;quot;无脑等到死&amp;rdquo;——除非你主动设超时、主动加重试、主动配熔断、主动接监控。这些动作每一个都不难，但加起来就是一套需要长期维护的体系。问题是，你团队里新来的同学知道为什么这么写吗？三年后业务长出十倍体量的时候，这套手工拼装的治理还能跟上吗？&lt;/p&gt;&#xA;&lt;p&gt;接入内部治理 SDK 的 RPC 框架，它的设计哲学是&amp;quot;假设下游会出问题&amp;quot;——SDK 要求超时显式设置（没有全局默认值兜底），服务治理层识别连续失败后触发熔断，限流和降级开箱即用。它把&amp;quot;治理&amp;quot;从&amp;quot;工程师的自觉&amp;quot;，变成了&amp;quot;框架的契约&amp;quot;。&lt;/p&gt;&#xA;&lt;p&gt;&#xA;    &lt;img src=&#34;https://img.wujiachen.com.cn/rpc-vs-http/ch4-default-behavior.png&#34; alt=&#34;HTTP 默认行为 vs RPC 框架默认行为&#34; loading=&#34;lazy&#34;&gt; [3:2]&lt;/p&gt;&#xA;&lt;p&gt;HTTP 这套不是不能加刹车——你可以装 Spring Cloud，可以接 Sentinel，可以自己写中间件。但你得知道你需要刹车，得有人去配，得有人去维护。&lt;/p&gt;&#xA;&lt;p&gt;而内置治理 SDK 的 RPC 框架默认就给你装好了。&lt;strong&gt;你的下游一定会出问题，所以它提前帮你假设它会出问题。&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;这才是大厂选 RPC 的真正原因。不是因为它&amp;quot;快 5ms&amp;quot;——是因为它在出事的时候给你一根救命稻草。&lt;/p&gt;&#xA;&lt;p&gt;&#xA;    &lt;img src=&#34;https://img.wujiachen.com.cn/rpc-vs-http/ch4-avalanche-comparison.png&#34; alt=&#34;雪崩演进双场景对比&#34; loading=&#34;lazy&#34;&gt; [3:2]&lt;/p&gt;&#xA;&lt;h3 id=&#34;那次选型我们最后选了什么&#34;&gt;&lt;a href=&#34;#%e9%82%a3%e6%ac%a1%e9%80%89%e5%9e%8b%e6%88%91%e4%bb%ac%e6%9c%80%e5%90%8e%e9%80%89%e4%ba%86%e4%bb%80%e4%b9%88&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;那次选型，我们最后选了什么？&#xA;&lt;/h3&gt;&lt;p&gt;雪崩之后，我们组开了三次会讨论框架。会上有人主张直接上 Dubbo，有人主张换 gRPC，还有人主张就在 HTTP 上接 Sentinel。&lt;/p&gt;&#xA;&lt;p&gt;最后我们的决策不是技术比拼，是这两个判断：&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;判断一：我们需要的不是「快」，是「可控」。&lt;/strong&gt;&#xA;我们的业务量根本不到协议优化能体现差距的水平。但我们需要熔断、需要限流、需要降级、需要服务发现、需要负载均衡——这些东西自己写一遍，不仅麻烦，还容易写错。&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;判断二：内置 vs 自建，成本差几个数量级。&lt;/strong&gt;&#xA;Spring Cloud 看起来&amp;quot;也能做&amp;quot;——但你试过自己接一遍 Eureka + Hystrix（现已停止维护，社区主推 Resilience4j）+ Ribbon + Zuul + Sleuth + Zipkin 吗？光把这套调通就要两周，跑稳定要半年，每次升级又是一波踩坑。&#xA;gRPC + 公司内部治理 SDK，接入文档走完，接入周期从两周压缩到两天——大部分踩坑的坑，中间件团队替你踩完了。&lt;/p&gt;&#xA;&lt;p&gt;我们选了 gRPC。整个治理栈都在 SDK 里，不需要自己拼装。&lt;/p&gt;&#xA;&lt;p&gt;那之后没再发生过类似的雪崩。不是因为系统变快了——P50 延迟其实差不多——而是因为任何一个下游开始有问题，链路会自己止血。&lt;/p&gt;&#xA;&lt;hr&gt;&#xA;&lt;h2 id=&#34;五决策框架你到底该不该选-rpc&#34;&gt;&lt;a href=&#34;#%e4%ba%94%e5%86%b3%e7%ad%96%e6%a1%86%e6%9e%b6%e4%bd%a0%e5%88%b0%e5%ba%95%e8%af%a5%e4%b8%8d%e8%af%a5%e9%80%89-rpc&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;五、决策框架：你到底该不该选 RPC&#xA;&lt;/h2&gt;&lt;p&gt;讲到这里，应该可以给你一个落地的判断标准了。我把这两年看过的、做过的选型总结成一张决策表。&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;先回答这四个问题，再决定要不要换 RPC：&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;table&gt;&#xA;  &lt;thead&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;th&gt;问题&lt;/th&gt;&#xA;          &lt;th&gt;建议方案&lt;/th&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/thead&gt;&#xA;  &lt;tbody&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;你的服务调用关系是网状的，超过 5 个内部服务互相调？&lt;/td&gt;&#xA;          &lt;td&gt;✅ RPC&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;你担心某个下游慢/挂会拖垮整个链路？&lt;/td&gt;&#xA;          &lt;td&gt;✅ RPC&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;你需要在服务实例增减时自动发现/负载均衡？&lt;/td&gt;&#xA;          &lt;td&gt;✅ RPC&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;      &lt;tr&gt;&#xA;          &lt;td&gt;你的接口需要给非内部团队（前端/外部合作方）调用？&lt;/td&gt;&#xA;          &lt;td&gt;✅ HTTP&lt;/td&gt;&#xA;      &lt;/tr&gt;&#xA;  &lt;/tbody&gt;&#xA;&lt;/table&gt;&#xA;&lt;p&gt;如果前三个全是 RPC，第四个是 HTTP——上 RPC，省心。&#xA;如果只有第四个——继续用 HTTP，REST 风格反而更直观。&#xA;两边都有？典型的&lt;strong&gt;双协议并存&lt;/strong&gt;架构：内部用 gRPC，对外暴露 HTTP/REST 网关层。这是大多数中型公司的最终形态。&lt;/p&gt;&#xA;&lt;p&gt;&#xA;    &lt;img src=&#34;https://img.wujiachen.com.cn/rpc-vs-http/ch5-decision-flow.png&#34; alt=&#34;RPC/HTTP 决策流程图&#34; loading=&#34;lazy&#34;&gt; [3:2]&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;几个常见的判断误区，顺便也说一下：&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;误区一：&amp;ldquo;我们流量小，用不上 RPC。&amp;quot;——错。RPC 的核心价值不是承载大流量，是控制小故障不要演变成大故障。哪怕你只有几百 QPS，只要你的服务调用链路超过三跳，就有雪崩风险。&lt;/p&gt;&#xA;&lt;p&gt;误区二：&amp;ldquo;切 RPC 要花两个月，我们没时间。&amp;quot;——切框架是有成本，但对比的是&amp;quot;出一次大事故的代价&amp;rdquo;。我们那次 47 分钟的故障，业务损失够养一个 5 人小组工作半年。这套治理能力你可以自建，但半年踩坑加持续维护的代价，往往超过直接接入框架的成本。&lt;/p&gt;&#xA;&lt;p&gt;&#xA;    &lt;img src=&#34;https://img.wujiachen.com.cn/rpc-vs-http/ch5-misconceptions.png&#34; alt=&#34;误区澄清&#34; loading=&#34;lazy&#34;&gt; [1:1]&lt;/p&gt;&#xA;&lt;hr&gt;&#xA;&lt;h2 id=&#34;六回到那一晚&#34;&gt;&lt;a href=&#34;#%e5%85%ad%e5%9b%9e%e5%88%b0%e9%82%a3%e4%b8%80%e6%99%9a&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;六、回到那一晚&#xA;&lt;/h2&gt;&lt;p&gt;回到我开头那个凌晨三点。&lt;/p&gt;&#xA;&lt;p&gt;那一晚之后我学到的最重要的一件事是：&lt;strong&gt;工程师对&amp;quot;性能&amp;quot;的迷恋，常常掩盖了真正的工程问题。&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;p&gt;我们花了好几年优化接口、压榨 SQL、研究序列化协议——所有这些加起来，可能还不如一行 &lt;code&gt;WithTimeout(3 * time.Second)&lt;/code&gt; 的价值大。&lt;/p&gt;&#xA;&lt;p&gt;不是说优化没意义。是说&lt;strong&gt;优先级搞反了&lt;/strong&gt;。&lt;/p&gt;&#xA;&lt;p&gt;让你的服务跑得更快，是锦上添花。让你的服务在出问题的时候不要一起死掉——这是命。&lt;/p&gt;&#xA;&lt;p&gt;这两年带过几个新同学，每次让他们做服务设计的复盘，问题都集中在一个地方：他们对&amp;quot;快&amp;quot;特别敏感，对&amp;quot;崩&amp;quot;特别迟钝。看到 P99 慢了 10ms 就着急去调，看到没设超时却觉得&amp;quot;反正大概率不会触发&amp;rdquo;。&lt;/p&gt;&#xA;&lt;p&gt;可工程的现实是反过来的——大概率不会出事的事，一旦出事就是大事。&lt;/p&gt;&#xA;&lt;p&gt;下次再看到&amp;quot;RPC 比 HTTP 快多少&amp;quot;的标题，先问一句：它在衡量什么。答案往往已经说明了作者在不在乎你真正的问题。&lt;/p&gt;&#xA;&#xA;    &lt;blockquote&gt;&#xA;        &lt;p&gt;选 RPC 不是因为它跑得快，是因为它在你最需要的时候，告诉你：&amp;ldquo;出问题了，我替你刹车。&amp;rdquo;&lt;/p&gt;&#xA;&#xA;    &lt;/blockquote&gt;&#xA;&lt;p&gt;&#xA;    &lt;img src=&#34;https://img.wujiachen.com.cn/rpc-vs-http/ch6-relief.png&#34; alt=&#34;收尾情绪图&#34; loading=&#34;lazy&#34;&gt; [3:2]&lt;/p&gt;&#xA;&lt;hr&gt;&#xA;&lt;h2 id=&#34;附录实验代码和原始数据&#34;&gt;&lt;a href=&#34;#%e9%99%84%e5%bd%95%e5%ae%9e%e9%aa%8c%e4%bb%a3%e7%a0%81%e5%92%8c%e5%8e%9f%e5%a7%8b%e6%95%b0%e6%8d%ae&#34; class=&#34;header-anchor&#34;&gt;&lt;/a&gt;附录：实验代码和原始数据&#xA;&lt;/h2&gt;&lt;p&gt;本文 2 组实验的代码已开源：&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;GitHub：&lt;a class=&#34;link&#34; href=&#34;https://github.com/wujiachen0727/zhiyulab-evidence/tree/main/rpc-vs-http&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;zhiyulab-evidence/rpc-vs-http&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;strong&gt;&lt;code&gt;e1-protocol-bench/&lt;/code&gt;&lt;/strong&gt;：E1 协议层吞吐与延迟对比（HTTP/1.1+JSON vs HTTP/2+JSON vs HTTP/2+二进制），可复现 46.9% 体积压缩和 1µs P50 差距&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;&lt;code&gt;e2-latency-breakdown/&lt;/code&gt;&lt;/strong&gt;：E2 端到端调用延迟分解（序列化/网络+协议/业务逻辑各环节占比），可复现 83.64% 业务逻辑占比和敏感性分析数据&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;每个子目录都有独立说明，二进制编译产物不入库，跑实验前自己 &lt;code&gt;go build&lt;/code&gt;。&lt;/p&gt;&#xA;&#xA;    &lt;blockquote&gt;&#xA;        &lt;p&gt;原文发布于 &lt;a class=&#34;link&#34; href=&#34;https://www.wujiachen.com.cn/posts/rpc-vs-http&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;&#xA;    &gt;止语Lab&lt;/a&gt;&lt;/p&gt;&#xA;&#xA;    &lt;/blockquote&gt;&#xA;</description>
        </item></channel>
</rss>
