一切从一个周末开始
一个周末的意外
那是一个平常的周六下午,我正在家里打游戏。
手机响了,是我大学室友老张。
“兄弟,有没有兴趣来我公司帮忙?我们消息通知系统崩了,CTO 说再搞不好就要砍掉这个功能。”
“什么情况这么严重?”
“我们做了个社交 App,用户增长很快,但是通知系统跟不上。用户抱怨收不到消息,或者同一消息重复推送 5 次,还有半夜被通知轰炸投诉的…”
他顿了顿,“我们后端就两个人,都不太懂推送,你之前不是做过类似的项目吗?”
我犹豫了一下。当时我在一家大厂做业务开发,每天写 CRUD,技术成长有限。而老张的创业公司虽然小,但用户增长很快,正好能接触核心技术。
“待遇怎么样?”
“比你现在高 30%,还有期权。”
“我周一去面试。“
面试那天
周一,我请了半天假,来到老张的公司。
办公楼不大,在一个创业园区里。前台小姐姐带我进了会议室,给我倒了杯水。
过了一会儿,进来一个戴眼镜的中年男人。
“你好,我是技术负责人王明,叫我老王就行。”
简单寒暄后,老王开始介绍他们的情况:
“我们的 App 叫 ‘圈内’,主打兴趣社交。去年上线,现在有 50 万用户,日活 8 万左右。”
他打开白板,画了个简单的架构图:
┌─────────┐ ┌──────────┐ ┌──────────┐
│ iOS App │────▶│ 服务器 │────▶│ 数据库 │
└─────────┘ └──────────┘ └──────────┘
┌─────────┐ │
│ 安卓 App │──────────┘
└─────────┘“通知系统是另一个同事写的,他离职前只留了几个文档。现在问题越来越多…”
他列出了几个主要问题:
- 推送延迟:用户发消息后,接收方要等 5-10 秒才能收到通知
- 重复推送:同一条消息有时推送 3-5 次
- 半夜打扰:凌晨 3 点还推送促销消息,用户投诉不断
- 没有偏好设置:用户无法关闭不想收到的通知类型
“现在的通知系统是什么架构?” 我问。
老王苦笑:“其实就是一个 PHP 脚本,每分钟轮询数据库,把未发送的消息通过极光推送发出去。”
我皱了皱眉:“每分钟轮询?那延迟 1 分钟以内才对啊,怎么会 5-10 秒?”
“问题就在这,” 老王指着白板,“数据库里有个 notifications 表,存储了所有待发送的通知。脚本每次查询 1000 条,发送后标记为已发送。但是…”
“但是什么?”
“表里现在有 200 万条数据,索引设计得很烂,每次查询要 8-9 秒。而且发送完要更新状态,又是一次慢查询。”
我倒吸一口凉气。这哪是通知系统,这是定时炸弹。
技术挑战
老王继续说:
“我们调研了一下,发现通知系统比想象中复杂多了。你看…”
他打开笔记本,给我看了他们的业务场景:
通知类型:
- 评论通知:有人评论了你的动态
- 点赞通知:有人点赞了你的内容
- 关注通知:有人关注了你
- 系统通知:平台活动、促销信息
- 私信通知:收到私信
推送渠道:
- iOS:需要通过 APNs(Apple Push Notification service)
- 安卓:国内用不了 Google 的 FCM,需要接各家厂商的推送(小米、华为、OPPO、vivo)
- 站内信:App 内部的消息中心
- 可选:短信、邮件
“而且,” 老王补充道,“用户可能同时登录多个设备——手机、平板、电脑。怎么保证同步?已读状态怎么处理?”
问题一个接一个。我开始意识到,这不是一个简单的功能,而是一个完整的系统设计问题。
我的决定
面试结束后,我在楼下咖啡馆坐了很久。
回想起在大厂的日子:
- 每天写业务代码,重复性工作多
- 系统架构都是现成的,不需要自己设计
- 成长空间有限,看不到技术天花板
再看老张的公司:
- 用户增长快,技术挑战大
- 可以从零设计一个系统
- 虽然有风险,但能学到很多
我打开手机,给老张发了条微信:
“我决定加入了,什么时候能入职?”
三分钟后,他回了一条:
“太好了!下周一入职。我让 HR 准备 offer,对了,通知系统就交给你了,全权负责。”
看着那条消息,我既兴奋又紧张。这是我第一次独立负责一个系统的设计。