V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
• 请不要在回答技术问题时复制粘贴 AI 生成的内容
kai92zeng
V2EX  ›  程序员

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

  •  
  •   kai92zeng · 1 天前 · 1288 次点击

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

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

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

    几年前写后端,我也迷信“标准答案”:做个服务,起手就是 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 友们指正。如果你的孩子也吵着要抱抱,那我们就是异父异母的亲兄弟了。😄

    15 条回复    2026-01-26 02:20:07 +08:00
    nigga
        1
    nigga  
       1 天前
    k8s 这些强调的高可用 HPA ,强调的是啥也不懂的客户点点点就能从复杂的硬件配置中解放出来
    但是背后是无数运维人员和监控人员在处理故障,只是把问题从客户转嫁给了技术人员
    在个人项目上毫无意义
    kai92zeng
        2
    kai92zeng  
    OP
       1 天前
    @nigga 兄台说的极有道理,不过这也算是创造就业岗位了。
    defunct9
        3
    defunct9  
       21 小时 11 分钟前 via iPhone
    把数据库去了才是王道
    kai92zeng
        4
    kai92zeng  
    OP
       20 小时 56 分钟前
    @defunct9 科技进步如此之快的时代,一切皆有可能
    lemos1235
        5
    lemos1235  
       18 小时 49 分钟前
    玩具就别说了,好吧。想咋弄咋弄
    zenfsharp
        6
    zenfsharp  
       16 小时 29 分钟前
    op 展示的思路很好我很喜欢
    kai92zeng
        7
    kai92zeng  
    OP
       15 小时 54 分钟前
    @zenfsharp 我也是在实践中摸索的,我的前提是,杜绝增加第三方组件,避免增加数据库操作。只有这样,才能保证服务的稳定和高效
    BenjaminSu
        8
    BenjaminSu  
       13 小时 33 分钟前 via Android
    技术栈越少,越稳定
    引入的包越少,越高效
    精简既是高效,也是能力
    wangym20804
        9
    wangym20804  
       11 小时 53 分钟前
    还是业务太简单了, 没有 MQ, 高并发,数据堆积怎么解决? 多方调用的数据链路怎么保证事务性?
    kai92zeng
        10
    kai92zeng  
    OP
       8 小时 20 分钟前
    @BenjaminSu 握爪
    kai92zeng
        11
    kai92zeng  
    OP
       8 小时 13 分钟前
    @wangym20804 MQ:Rust 的 mpsc/broadcast 就在内存里,比外部 MQ 快几个数量级。单机抗不住时,瓶颈通常在 数据库而不是消息转发。事务:单体应用不需要分布式事务,数据库 ACID 就能搞定一切,还没有莫名其妙的问题。架构:脱离业务量谈架构意义不大。对于独立开发,没有中间件就是最好的中间件。能用单机解决的问题,绝对不引入分布式复杂度。特种兵作战,一把枪+一把刀,大队作战才带锅碗瓢盆。
    815377546
        12
    815377546  
       7 小时 53 分钟前
    😄 别的不说,一边带娃一边工作,想想都头大。另外本文 ai 风格略重😆😆
    kai92zeng
        13
    kai92zeng  
    OP
       7 小时 13 分钟前
    @815377546 不用 AI 润色,我都没时间发文章。
    opengps
        14
    opengps  
       4 小时 33 分钟前 via Android
    我有同感:能把单体应用做好,才能明白为什么语言分体架构
    上来就各种拆分本身已经是过度设计,很多用不到极限的地方浪费了过多精力
    doraemonki
        15
    doraemonki  
       3 小时 53 分钟前 via Android
    @BenjaminSu 可惜对面试吹牛不友好
    关于   ·   帮助文档   ·   自助推广系统   ·   博客   ·   API   ·   FAQ   ·   Solana   ·   840 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 21ms · UTC 22:13 · PVG 06:13 · LAX 14:13 · JFK 17:13
    ♥ Do have faith in what you're doing.