[独立开发] 带娃写代码的觉悟:删掉 Redis 和 Kafka,我用“喊一嗓子”解决了高并发 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
kai92zeng
V2EX    程序员

[独立开发] 带娃写代码的觉悟:删掉 Redis 和 Kafka,我用“喊一嗓子”解决了高并发

  •  
  •   kai92zeng 13 小时 14 分钟前 619 次点击

    大家好,我是《交易学徒》的作者。

    简单介绍下背景:我现在的核心身份是带两个孩子的全职奶爸,副业才是趁着孩子睡着后,在键盘上敲敲打打的独立开发者。

    对于我这种“碎片化时间”开发者来说,运维复杂度就是最大的敌人。

    几年前写后端,我也迷信“标准答案”:做个服务,起手就是 Docker 编排,Redis 做缓存,Kafka 做解耦,微服务先分几个出来。结果往往是,功能没写几个,光是调网络、修连接超时、查中间件报错,就把孩子午睡的那宝贵两小时耗光了(那时候还没孩子)。

    在开发后端时,我陷入了深思:

    “对于一个追求极致性能、但只有一个人维护的系统,所谓的‘工业级架构’真的是解药吗?还是毒药?”

    最终,我做了一个违背祖宗的决定:做减法。 我删除了 Redis ,移除了 Kafka ,把整个微服务集群塌缩成了一个 Rust 单体应用。

    今天想聊聊这背后的思考过程。

    一、 复杂度的守恒与转移 我的业务场景看似简单,实则牵一发而动全身。一个简单的“用户平仓”动作,就像推倒了第一块多米诺骨牌:

    核心域:结算盈亏,改余额,写数据库。(必须马上做)

    通知域:给前端发个弹窗通知“平仓成功”。(晚 0.1 秒没关系)

    营销域:判断有没有触发“五连胜”、“以小博大”成就,发奖励。(晚 1 秒没关系)

    统计域:计算交易评分,统计分数或者更新等级与交易报表。(晚几秒都行)

    在“标准架构”里,我们需要引入 消息队列 (MQ) 来解耦这些逻辑。 但引入 MQ 本质上并没有消除复杂度,只是将“代码复杂度”转移成了“运维复杂度”。

    对于团队,运维复杂度可以分摊给同事;但对于我,这意味着我不仅要写代码,还得修服务器。

    Rust 给了我另一个选择:利用它极高的性能,把“运维复杂度”重新压回“架构设计”里,用最朴素的方式解决问题。

    二、 内存即总线:构建“喊一嗓子”的架构 我利用 Rust 的内存通道特性,构建了一个“超光速大喇叭”。 我不请求数据,我只发布事实。

    这个过程,可以用一个生活化的场景来描述:

    1. 定义世界的真相 (The Truth) 我不写复杂的 XML 或 JSON 定义,我只是在代码里列了一张“事实清单”:

    事实 A:有人平仓了(包含:是谁、赚了多少、单号是多少)

    事实 B:有人购买商品了

    事实 C:AI 分析完成了

    编译器会盯着这张清单,保证我发出的每一个“事实”都是格式正确、童叟无欺的。

    1. 极简的生产者 (Fire and Forget) 在核心交易逻辑里,当数据库事务提交成功后,我只需要做一件事:拿着大喇叭喊一嗓子。

    传统架构 (Kafka) 是这样的:

    交易模块 -> 打包数据 -> 建立 TCP 连接 -> 三次握手 -> 发送给 Kafka 集群 -> 等待 ACK -> 结束 (这中间任何一步网络抖动,都得处理异常)

    我的单体架构是这样的:

    交易模块 -> 喊:“老王平仓赚了 100 块!” -> 结束 (纯内存操作,纳秒级完成,快到像是没有发生过)

    1. 静默的消费者 (Sidequest Logic) 我把原本分散在微服务里的逻辑,变成了几个坐在角落里的“隐形工人”。

    比如 “营销服务”,它就像一个在角落里旁听的记分员:

    它平时不说话,只听大喇叭。

    一听到 “老王平仓赚了 100 块”,它立马翻开小本本查历史。

    发现老王已经连赢 4 把了,加上这把正好 5 把。

    于是它默默地给老王发了一个“五连绝世”的徽章。

    整个过程,核心交易模块完全不知情,也完全不用等待,它喊完那一嗓子就去服务下一个用户了。

    三、 深度思考:关于“不可靠”的权衡 很多朋友可能会问:“没有 Kafka 把消息存到硬盘里,万一服务器断电了,你喊的那一嗓子不就丢了吗?”

    是的,这是整个架构思考中最痛苦,也是最关键的取舍。 我问了自己两个问题:

    Q1:我的程序崩溃概率有多大? Rust 以安全著称,只要代码写得不离谱,它极难崩溃( Panic )。这比 Java 的内存溢出或 Python 的运行时错误要稳健得多。

    Q2:丢失数据的代价是什么?

    我们可以把数据分成两类:

    钱(核心数据): 余额、订单状态。

    处理方式: 必须落袋为安。 直接写死在数据库里,绝不依赖“大喇叭”。

    气氛(衍生数据): 弹窗通知、成就徽章、达标奖励、统计报表。

    处理方式: 听天由命。 如果真的赶上万年不遇的服务器着火,用户少收到了一个“五连胜”的弹窗,或者报表少统计了一笔,天会塌吗?不会。

    结论: 为了 0.001% 的极端掉电风险,去让 99.99% 的时间里的系统背负沉重的中间件包袱,对于独立开发者来说,这是一笔亏本买卖。

    四、 结语 当我们谈论“高性能”时,往往想到的是复杂的集群、昂贵的服务器。 但 Simple is fast. (简单即快)

    现在的《交易学徒》后端,就是一个 20MB 的小文件。

    没有 Docker 容器编排

    没有 虚拟机调优

    没有 Redis 维护

    没有 服务间通讯

    只有一个跑在单机上的进程,CPU 占用极低,响应速度极快。

    这省下来的不仅仅是每年的服务器费用,更是我作为父亲陪伴孩子的宝贵时间。

    技术服务于生活,这大概就是独立开发的魅力吧。

    关于《交易学徒》 这是我用这套“极简架构”打磨的作品,前端是 Flutter ,后端 Rust 。 希望能给交易员朋友们提供一个干净、流畅、无延迟的练习环境。

    官网: https://www.zgjiazu.top

    Google Play: https://play.google.com/store/apps/details?id=com.zengkai.jyxtclient

    欢迎 V 友们指正。如果你的孩子也吵着要抱抱,那我们就是异父异母的亲兄弟了。

    2 条回复    2026-01-24 22:09:50 +08:00
    nigga
        1
    nigga  
       7 小时 57 分钟前
    k8s 这些强调的高可用 HPA ,强调的是啥也不懂的客户点点点就能从复杂的硬件配置中解放出来
    但是背后是无数运维人员和监控人员在处理故障,只是把问题从客户转嫁给了技术人员
    在个人项目上毫无意义
    kai92zeng
        2
    kai92zeng  
    OP
       7 小时 52 分钟前
    @nigga 兄台说的极有道理,不过这也算是创造就业岗位了。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     881 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 26ms UTC 22:01 PVG 06:01 LAX 14:01 JFK 17:01
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86