技术探索与实践:从救火到跳槽的两年踩坑实录

后端漫游指南
2025-12-13 14:36
阅读 682

大家好,我是老张,在某三线城市一家“互联网+传统行业”公司做技术负责人。说白了,就是那种老板嘴上喊着要搞数字化转型,实际连测试环境都经常和生产共用一台服务器的神奇地方。平时我一边戴着 AirPods 听 Lo-fi Beats 写代码(别笑,这真能让我冷静面对产品经理提的“小需求”),一边在 LeetCode 上刷题——没错,正在偷偷准备跳槽。

这篇文章,源于上周五晚上 10 点,我在公司改完第 8 版需求文档后,突然想到:这两年折腾的技术方案、踩过的坑、甚至被线上事故逼出来的架构优化,其实挺值得总结一下。尤其最近不少朋友问我“三线城市做技术还有没有成长空间”,我想说:有,但得自己主动挖


起因:一个差点让我背锅的“小项目”

去年双11前两周,产品总监突然冲进我们工位:“老张,咱们得做个实时库存预警系统!大促期间不能超卖!”
我说:“行啊,但得加人、加预算、加时间。”
他:“不用不用,就你带两个 junior,两周搞定,反正你们程序员不就敲敲键盘嘛?”

于是,我和两个实习生开始了“地狱模式”。原始方案是用定时任务每5秒查一次数据库库存,一旦低于阈值就发企业微信通知。结果上线第一天,DBA 就找上门:“你们这查询把主库 CPU 干到 90% 了!”

当时我真的想砸电脑。

痛定思痛,我们决定引入消息队列 + 缓存机制。但问题来了:公司技术栈老旧,连 Redis 都没正经用过,Kafka 更是听都没听过(运维大哥原话:“那玩意儿吃内存,咱服务器扛不住”)。

求职驱动学习成了唯一出路。为了跳槽简历好看,也为了真能把这事干成,我开始猛啃《Kafka 权威指南》,同时在 B 站、掘金找实战教程。不得不说,有些教程写得跟天书一样,光讲原理,不讲怎么在烂泥地里种花。


实战:从“玩具 demo”到“能跑的系统”

我们最终选了 RabbitMQ ——不是因为它多牛,而是因为公司内网能装、运维会配、社区文档多。虽然 Kafka 吞吐量更高,但在我们这种日活不到 5 万的小平台,RabbitMQ 完全够用,而且出问题我能自己 debug。

核心思路变了:不再轮询 DB,而是让下单服务在扣减库存时,主动发一条消息到队列。监听服务消费消息后,判断当前库存是否低于阈值,再触发告警。

关键代码片段如下(已脱敏):

# 库存扣减服务(伪代码)
def deduct_stock(product_id, quantity):
    # 先更新 DB
    StockModel.update(product_id, -quantity)
    
    # 再发消息
    current_stock = get_current_stock(product_id)  # 从缓存读
    if current_stock < THRESHOLD:
        mq_client.publish(
            exchange='inventory_alert',
            routing_key='low_stock',
            body=json.dumps({
                'product_id': product_id,
                'current_stock': current_stock,
                'timestamp': time.time()
            })
        )

监听服务这边:

# 告警消费者
def on_message(body):
    data = json.loads(body)
    if data['current_stock'] < config.ALERT_THRESHOLD:
        send_wechat_alert(data)  # 调企业微信 API
        # 加个防重:同一商品 5 分钟内不重复告警
        redis.setex(f"alert_sent:{data['product_id']}", 300, "1")

踩过的坑

  1. 消息丢失:一开始没开持久化,服务重启后积压消息全没了。后来给 Queue 和 Message 都加了 durable=True
  2. 重复消费:网络抖动导致 ACK 未送达,消息被重新投递。解决方案是消费者端做幂等(靠 Redis 记录已处理 ID)。
  3. 缓存一致性:库存变更后,缓存没及时更新,导致告警延迟。最后用“先更新 DB,再删缓存”的经典策略(虽然理论上仍有窗口期,但在我们业务容忍范围内)。

效果对比:不只是“能用”,而是“稳了”

上线一个月后,我们做了简单压测(其实就是模拟 1000 单/分钟),结果如下:

指标 轮询方案 消息队列方案
DB CPU 使用率 85%~95% 30%~40%
告警延迟 ≤5s ≤200ms
运维投诉次数 7次/周 0

更爽的是,双11当天零点,系统稳如老狗。产品总监拍我肩膀:“老张,还是你靠谱!” —— 虽然我知道他转头就去跟老板说“这个功能很简单,技术团队效率很高”。


关于“教程”和“项目”的一点真心话

现在网上教程太多了,但很多脱离真实场景。比如教你用 Spring Cloud Stream 接 Kafka,却不说清楚:

  • 如何在没有 ZooKeeper 的环境下部署?
  • 消息积压了怎么监控?
  • 日志怎么集中收集?

我在准备跳槽时,特意把这次项目写进了简历,并附上了 GitHub 仓库(内部代码脱敏后开源)。面试官问得最多的就是:“你们怎么保证消息不丢?”、“如果消费者挂了怎么办?”——这些问题,只有真正上线过的人才能答得具体。

所以我的建议是:别只看教程,要自己造轮子。哪怕是在公司“屎山”项目里打补丁,只要能抽象出通用模式,就是有价值的项目经验。


写在最后:三线城市的工程师,也能有技术追求

很多人觉得,三线城市技术氛围差、项目 low、学不到东西。但我觉得,限制你的从来不是地理位置,而是解决问题的态度

我现在每天依然要应付各种“明天上线”的需求,依然要帮测试复现“在我机器上没问题”的 Bug,依然要听运维抱怨“又改配置?”。但只要我还保持着对代码可读性、系统可维护性的执念,还在刷题、还在研究新方案,我就没被温水煮青蛙。

下个月我应该就要离开这家公司了。不是因为它不好,而是我需要更大的战场。但这段“在夹缝中搞技术”的经历,反而让我更清楚:真正的工程能力,是在资源有限、时间紧迫、人手不足的情况下,依然能把事情做成、做稳、做得优雅

如果你也在类似环境里挣扎,不妨试试:
👉 把每一次救火,当成一次技术实验
👉 把每一个需求,当作一个 mini 项目来设计
👉 把每一段烂代码,当作重构的起点

毕竟,我们写的不是代码,是未来的简历。

(P.S. 刚才写完这段,耳机里正好放完一首歌。关掉 IDE,该回家了——明天还要 review 三个 PR 呢。)

评论 0

最热最新
暂无评论
匿名用户Lv.1
0
影响力
0
文章
0
粉丝