浅谈技术探索与实践:一个带娃写代码的妈妈的碎碎念

Rust练习生
2025-12-19 05:23
阅读 3192

今天早上8点整,我准时坐到电脑前——不是因为自律,而是因为娃刚被送去幼儿园,再不开工今天的KPI就要凉了。作为一名远程办公的全职妈妈+分布式系统方向的后端工程师,我的日常就是在“奶瓶”和“微服务”之间反复横跳。上周五晚上11点,我在哄睡失败、代码跑崩、线上告警连环炸的三重夹击下,终于顿悟了一件事:技术探索从来不是锦上添花,而是雪中送炭,尤其是在你连喝口水都要掐着时间的时候。

这篇文章,就当是我给同样在“带娃+coding”夹缝中求生的同行们一点微不足道的技术分享吧。


事情得从“那个要命的产品需求”说起

去年双11前一个月,产品团队突然甩过来一个需求文档,标题赫然写着:“支持千万级实时用户在线互动”。我盯着屏幕看了三秒,内心OS:“你们是打算让我用单机MySQL扛住整个抖音的流量吗?”

更离谱的是,产品经理小王还一脸天真地问我:“这个功能后天能上线吗?大促要用。”
我差点把咖啡喷到键盘上——后天?你知道光部署一套 Kafka 集群都得调三天配置吗?

但吐槽归吐槽,活儿还是得干。我们现有的架构还是基于传统的请求-响应模型,状态全靠数据库扛。面对这种高并发、低延迟、强状态的场景,显然不够看。于是,技术探索被迫提上日程——不是我想搞新花样,是真的快被线上事故逼疯了。


踩坑记:从“我觉得行”到“我真的不行”

一开始,我天真地以为引入 Redis + WebSocket 就能搞定。结果第一次压测,连接数一过5万,服务器直接 OOM。日志里全是:

java.lang.OutOfMemoryError: Unable to create new native thread

那一刻,我坐在凌晨两点的书房里,听着隔壁房间娃的翻身声,真的想砸电脑。

后来翻遍 Stack Overflow,才意识到问题出在线程模型上。每个 WebSocket 连接默认占用一个线程,这在高并发下就是资源黑洞。于是开始调研更轻量的通信方案,最终锁定了 Reactive Streams + Project Reactor 的组合。

但 Reactive 编程的学习曲线……emmm,怎么说呢?就像一边给孩子换尿布一边背《九阴真经》——脑子不够用。尤其是处理 backpressure 和上下文传播时,debug 到怀疑人生。

最崩溃的是某次上线后,发现用户登录态莫名其妙丢失。排查三天才发现是 Reactor 的 Context 在异步链路中断了,导致 SecurityContext 没传下去。这种“幽灵 Bug”,测试根本测不出来,只能靠肉眼盯日志+人肉回溯调用链。


技术选型:没有银弹,只有权衡

在确定用 Reactive 架构后,我们还得选消息中间件。团队内部吵了一周:有人推 RabbitMQ(老熟人,稳),有人推 Pulsar(新潮,分层存储香),还有人说直接上 Kafka(毕竟社区大)。

我拉了个表格对比了一下核心指标:

中间件 吞吐量 (msg/s) 延迟 (ms) 运维复杂度 社区活跃度 是否支持多租户
Kafka 500k+ <10 中 ⭐⭐⭐⭐⭐ 弱
Pulsar 300k+ <5 高 ⭐⭐⭐⭐ 强
RabbitMQ 50k <1 低 ⭐⭐⭐ 中

考虑到我们未来要支持多个业务线共用同一套实时通道(产品又画了个大饼),多租户隔离成了关键。最后咬牙上了 Pulsar——虽然运维同事一脸生无可恋,但架不住它 topic 级别的配额控制真香。

顺便说一句,Pulsar 的 BookKeeper 调优过程简直反人类。光是 ledgerDirs 和 journalDirs 的磁盘 IO 分离,就让我和运维老李对骂了两次。不过现在回头看,那次“痛苦”的升级,反而让团队对分布式存储的理解深了一个 level。


实践出真知:别信文档,信监控

技术落地最怕什么?不是写不出代码,而是线上效果和预期对不上。

我们上线第一周,虽然吞吐量达标了,但 P99 延迟飙到 800ms。用户反馈“消息发出去半天才收到”。我一度以为是网络抖动,直到打开 Argo CD 的拓扑图才发现:反向代理层成了瓶颈。

原来 Nginx 默认的 keepalive 连接池太小,大量短连接打满后,新请求排队等复用。调整 upstream 配置后,延迟直接降到 30ms 以内:

upstream backend {
    server reactive-service:8080;
    keepalive 1000;
}

location /ws {
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_pass http://backend;
}

这件事给我敲响警钟:再牛的技术栈,也扛不住基础设施的短板。从此以后,我养成了上线前必查“全链路监控”的习惯——从 CDN 到 DB,一个环节都不能放过。


技术分享的意义:不是秀肌肉,是少踩坑

说到这儿,可能有人觉得我在炫耀技术选型多牛。其实真不是。作为一个每天和尿布、辅食、deadline 打交道的妈妈程序员,我深知时间是最奢侈的资源。所以每次踩完坑,我都强迫自己写一篇内部 Wiki,哪怕只有三句话。

比如那篇《Reactor Context 丢失的七种死法》,已经被团队新人收藏为“保命指南”。上周实习生小张照着改了两行代码,避免了一次重大资损——那一刻,我觉得比涨薪还爽。

技术分享的本质,不是证明“我懂”,而是告诉别人“你可以不用像我一样痛”。


写在最后:在混乱中寻找秩序

现在,我们的实时互动系统已经稳稳扛过了今年618。虽然过程中经历了三次深夜回滚、两次 P0 事故,但至少没再出现“用户发个消息全家断网”的史诗级 Bug。

回头看看这段技术探索之路,其实没什么高深理论,就是在有限资源下,用最小代价解决问题。而所谓“前瞻性”,不过是提前预判了产品又要画饼,提前给自己挖好逃生通道罢了。

至于我?今天下午三点要去接娃,所以这篇博客必须在中午前写完。赶紧保存草稿,去改最后一个 Bug —— 毕竟,生活和代码一样,总得在 deadline 前跑通。

共勉,各位在育儿和 coding 之间走钢丝的战友。

评论 0

最热最新
暂无评论
Rust练习生Lv.1
0
影响力
0
文章
0
粉丝