<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>马超的代码园</title><link>https://blog.myxingchen.xyz/</link><description>Recent content on 马超的代码园</description><generator>Hugo -- gohugo.io</generator><language>zh-cn</language><lastBuildDate>Mon, 20 Jul 2026 21:30:00 +0800</lastBuildDate><atom:link href="https://blog.myxingchen.xyz/index.xml" rel="self" type="application/rss+xml"/><item><title>一次压测揪出两个“测试全绿”的性能 bug:KV 引擎压测复盘</title><link>https://blog.myxingchen.xyz/posts/kv-benchmark-two-bugs/</link><pubDate>Mon, 20 Jul 2026 21:30:00 +0800</pubDate><guid>https://blog.myxingchen.xyz/posts/kv-benchmark-two-bugs/</guid><description>&lt;blockquote>
&lt;p>&lt;strong>最终数据&lt;/strong>:200k 条 (value=100B) 单线程本机压测 → 写 70.9万 / 随机读 59.1万 / 布隆负查询 321.6万 ops/s
&lt;strong>修复前&lt;/strong>:fillseq 232 ops/s、readrandom 4,936——两个 bug 把所有数字按在地上摩擦
&lt;strong>口径&lt;/strong>:22MB 数据全在 page cache,测的是内存命中下的引擎路径效率,&lt;strong>不能直接外推生产&lt;/strong>&lt;/p>
&lt;/blockquote>
&lt;p>KV 引擎做到 Week 4,布隆过滤器和 BlockCache 都上线了,&lt;strong>11/11 测试全绿&lt;/strong>。我跑了一轮 200k 条压测,准备把数字写进简历。&lt;/p>
&lt;p>结果 fillseq 跑出来 &lt;strong>232 ops/s&lt;/strong>。&lt;/p>
&lt;p>什么概念?平均每次写 4.3ms,p50 2,565μs——这是&lt;strong>每次写都 fsync&lt;/strong> 的价位,而我跑的明明是 &lt;code>sync=0&lt;/code>(异步刷盘)。更邪门的是读:readrandom、readmissing 三项全部稳定在 ~190μs/次,布隆过滤器开关与否毫无区别。&lt;/p>
&lt;p>测试全绿,性能烂了两个数量级。这篇文章记录我是怎么把这两个 bug 挖出来的——&lt;strong>功能正确和性能正确是两件事,前者保不了后者&lt;/strong>。&lt;/p></description></item><item><title>网络层设计:主从 Reactor + One Loop Per Thread</title><link>https://blog.myxingchen.xyz/posts/network-layer-reactor/</link><pubDate>Sun, 19 Jul 2026 23:00:00 +0800</pubDate><guid>https://blog.myxingchen.xyz/posts/network-layer-reactor/</guid><description>&lt;blockquote>
&lt;p>&lt;strong>代码&lt;/strong>:&lt;code>src/network/&lt;/code> 8 个核心类,共 ~800 行
&lt;strong>灵感&lt;/strong>:陈硕《Linux 多线程服务端编程》+ Muduo 源码
&lt;strong>设计目标&lt;/strong>:0 锁的 IO 路径(每连接绑定一个 EventLoop,无共享)&lt;/p>
&lt;/blockquote>
&lt;p>写 RPC 框架,网络层是&lt;strong>最值得&amp;quot;自己写一遍&amp;quot;的部分&lt;/strong>——HTTP 框架、RPC、消息推送、游戏服务器,网络层都是这套。&lt;/p>
&lt;p>我对照陈硕《Linux 多线程服务端编程》自己撸了一遍,&lt;strong>没抄 Muduo 源码&lt;/strong>——边看边写,踩了 6 个坑,全部记下来。&lt;/p></description></item><item><title>熔断与限流:滑动窗口的两种算法</title><link>https://blog.myxingchen.xyz/posts/circuit-breaker-design/</link><pubDate>Sun, 19 Jul 2026 22:55:00 +0800</pubDate><guid>https://blog.myxingchen.xyz/posts/circuit-breaker-design/</guid><description>&lt;blockquote>
&lt;p>&lt;strong>代码&lt;/strong>:&lt;code>src/rate_limiter/{token_bucket, redis_token_bucket}.{h,cc}&lt;/code> + &lt;code>src/circuit_breaker/{circuit_breaker}.{h,cc}&lt;/code>
&lt;strong>场景&lt;/strong>:防止下游服务雪崩,客户端限流 + 熔断 + 服务降级&lt;/p>
&lt;/blockquote>
&lt;p>微服务架构里,&lt;strong>保护下游&lt;/strong>比&amp;quot;打到最快&amp;quot;更重要。三个核心组件:&lt;/p>
&lt;ul>
&lt;li>&lt;strong>限流(Rate Limiter)&lt;/strong>:单位时间最多处理 N 个请求&lt;/li>
&lt;li>&lt;strong>熔断(Circuit Breaker)&lt;/strong>:下游错误率超阈值,临时熔断,不再打下游&lt;/li>
&lt;li>&lt;strong>负载均衡(Load Balancer)&lt;/strong>:把请求分散到多个实例(轮询/一致性哈希)&lt;/li>
&lt;/ul>
&lt;p>这篇文聚焦&lt;strong>前两者&lt;/strong>——把面试常考的&amp;quot;你怎么做限流&amp;quot;答得&lt;strong>有深度&lt;/strong>。&lt;/p></description></item><item><title>服务发现:内存注册中心 vs etcd 两种实现</title><link>https://blog.myxingchen.xyz/posts/service-discovery-design/</link><pubDate>Sun, 19 Jul 2026 22:50:00 +0800</pubDate><guid>https://blog.myxingchen.xyz/posts/service-discovery-design/</guid><description>&lt;blockquote>
&lt;p>&lt;strong>代码&lt;/strong>:&lt;code>src/discovery/memory_registry.{h,cc}&lt;/code> (180 行) + &lt;code>src/discovery/etcd_registry.{h,cc}&lt;/code> (260 行)
&lt;strong>场景&lt;/strong>:rpc_client 调 &lt;code>EchoService.Echo&lt;/code>,注册中心返回所有 EchoService 实例的 host:port&lt;/p>
&lt;/blockquote>
&lt;p>RPC 调用第一步:&lt;strong>&amp;ldquo;EchoService 的实例在哪些机器上?&amp;rdquo;&lt;/strong>——这就是&lt;strong>服务发现&lt;/strong>。三种主流实现:&lt;/p>
&lt;ol>
&lt;li>&lt;strong>直连&lt;/strong>——客户端 hardcode host:port,简单但无扩展性&lt;/li>
&lt;li>&lt;strong>内存注册中心&lt;/strong>——单进程内 map&amp;lt;服务名, 实例列表&amp;gt;,适合开发/单测&lt;/li>
&lt;li>&lt;strong>独立服务&lt;/strong>——etcd / consul / nacos,跨进程共享&lt;/li>
&lt;/ol>
&lt;p>我两个都实现了。这篇文记录&lt;strong>为什么需要两个、怎么设计、怎么从内存版升级到 etcd&lt;/strong>。&lt;/p></description></item><item><title>从零写一个连接池:为什么不用 std::queue</title><link>https://blog.myxingchen.xyz/posts/connection-pool-design/</link><pubDate>Sun, 19 Jul 2026 22:45:00 +0800</pubDate><guid>https://blog.myxingchen.xyz/posts/connection-pool-design/</guid><description>&lt;blockquote>
&lt;p>&lt;strong>代码&lt;/strong>:&lt;code>src/pool/connection_pool.{h,cc}&lt;/code> (350 行)
&lt;strong>场景&lt;/strong>:rpc_client 每个请求都要 TCP 连接,per-call connect 性能 7,800 QPS,加连接池 28,000 QPS&lt;/p>
&lt;/blockquote>
&lt;p>RPC 客户端最朴素的写法:&lt;strong>&lt;code>connect() → send() → recv() → close()&lt;/code>&lt;/strong>。性能 7,800 QPS(p99 4.2ms)。&lt;/p>
&lt;p>上连接池,瞬间 28,000 QPS(p99 2.1ms)。&lt;strong>3.5x 加速&lt;/strong>。&lt;/p>
&lt;p>听起来就是 &lt;code>std::queue&amp;lt;TcpConnection*&amp;gt; + mutex&lt;/code> 的事。真写起来,光&amp;quot;连接怎么回收&amp;quot;就够喝一壶。&lt;/p></description></item><item><title>docker 部署踩的 9 个坑:从 gcr.io 到健康检查</title><link>https://blog.myxingchen.xyz/posts/docker-deploy-9-pitfalls/</link><pubDate>Sun, 19 Jul 2026 22:40:00 +0800</pubDate><guid>https://blog.myxingchen.xyz/posts/docker-deploy-9-pitfalls/</guid><description>&lt;blockquote>
&lt;p>&lt;strong>目标&lt;/strong>:&lt;code>https://rpc.myxingchen.xyz/api/echo&lt;/code> 返回 JSON,延迟 &amp;lt; 10ms
&lt;strong>链路&lt;/strong>:浏览器 → nginx(443) → rpc-proxy(Flask, 8080) → echo-server(C++, 9000)
&lt;strong>最终&lt;/strong>:4.18ms HTTPS / 0.63ms 直连&lt;/p>
&lt;/blockquote>
&lt;p>把 RPC 框架扔上公网,听起来简单——&lt;code>docker build &amp;amp;&amp;amp; docker run&lt;/code> 完事。&lt;strong>我踩了 9 个坑&lt;/strong>,&lt;strong>4 个 deploy 晚上,反复搞&lt;/strong>。这篇文把每个坑的现象、根因、修法、教训完整记录,下次别再重复。&lt;/p></description></item><item><title>手写 RPC 协议帧:18 字节头 + CRC32 + protobuf</title><link>https://blog.myxingchen.xyz/posts/rpc-protocol-design/</link><pubDate>Sun, 19 Jul 2026 22:35:00 +0800</pubDate><guid>https://blog.myxingchen.xyz/posts/rpc-protocol-design/</guid><description>&lt;blockquote>
&lt;p>&lt;strong>协议版本&lt;/strong>:v1.1
&lt;strong>完整代码&lt;/strong>:&lt;a class="link" href="https://github.com/FSSLI/rpc_framework/blob/main/docs/protocol.md" target="_blank" rel="noopener"
>github.com/FSSLI/rpc_framework - docs/protocol.md&lt;/a>&lt;/p>
&lt;/blockquote>
&lt;p>RPC 协议设计,新人最容易踩的坑是:&lt;strong>&amp;ldquo;protobuf 已经有 RPC 语法了,我直接用不就行了?&amp;rdquo;&lt;/strong>&lt;/p>
&lt;p>可以用,但你失去了:&lt;/p>
&lt;ol>
&lt;li>&lt;strong>自定义传输层&lt;/strong>——gRPC 强绑 HTTP/2,不能上 UDP/QUIC&lt;/li>
&lt;li>&lt;strong>自定义扩展&lt;/strong>——trace_id 怎么塞?心跳怎么发?&lt;/li>
&lt;li>&lt;strong>二进制紧凑度&lt;/strong>——HTTP/2 头部 + framing 开销在 30-50%&lt;/li>
&lt;/ol>
&lt;p>我花了两天设计自己的协议,&lt;strong>18 字节头 + 变长 body + 4 字节 CRC&lt;/strong>。记录下来,顺便说说踩的坑。&lt;/p></description></item><item><title>48,765 QPS 是怎么压出来的:一个 C++ RPC 框架的压测全流程</title><link>https://blog.myxingchen.xyz/posts/rpc-benchmark-48k-qps/</link><pubDate>Sun, 19 Jul 2026 22:30:00 +0800</pubDate><guid>https://blog.myxingchen.xyz/posts/rpc-benchmark-48k-qps/</guid><description>&lt;blockquote>
&lt;p>&lt;strong>数据&lt;/strong>:8 线程自研 C++ 压测程序同机回环 → 48,765 QPS,p99 382μs(WSL2,4 cores @ 4.0 GHz)
&lt;strong>代码&lt;/strong>:&lt;a class="link" href="https://github.com/FSSLI/rpc_framework" target="_blank" rel="noopener"
>github.com/FSSLI/rpc_framework&lt;/a>
&lt;strong>协议&lt;/strong>:18 字节固定头 + 变长 body + CRC32(详见&lt;a class="link" href="https://blog.myxingchen.xyz/posts/rpc-protocol-design/" >协议设计&lt;/a>)&lt;/p>
&lt;/blockquote>
&lt;p>写完 RPC 框架第一版,我面临一个问题:&lt;strong>怎么证明这玩意儿不是花架子&lt;/strong>?&lt;/p>
&lt;p>光&amp;quot;我写了一个 RPC&amp;quot;太虚,得拿出数。所以我从第一版压测开始,记录每轮改了哪个文件、为什么这么改,迭代到 48,765 QPS。这篇文把整个过程写下来。&lt;/p></description></item></channel></rss>