收藏
0
0
分享
举报
·2 小时前发布·63次阅读

创业故事 37|Fathom:周报好了,月报没来

独立开发商业增长付费用户

周报已经顺利跑过,到了月初,月报却没有按预期发出去。

Fathom 创始人 Jack Ellis 在 2024 年 3 月 7 日的文章里,回顾了这次报表优化。起初,后台报表和用户正在使用的仪表盘争抢数据库资源。他把许多小查询合成一次大汇总,测试通过后上线,大查询却又占用了大量资源。

接着,他给后台工作设置了资源限制。周报运行顺利,看起来问题解决了。到了 3 月 1 日,月报任务触及执行时间限制,再次卡住。3 月 6 日,他把工作重新拆成单封报表任务,放进独立队列限制同时运行的数量,并保留数据库资源限制。

这是作者对当时处理过程的自述。文中用到的独立队列并发限制,Laravel Vapor 早在 2023 年 1 月 30 日就已公告提供。这里不把作者报告的处理速度当作我们复现过的测试,也不沿用他对未来规模的乐观预测。

这个故事吸引我的地方,是每一步调整都有理由。先减少查询次数,再约束后台资源,都在处理一个眼前可见的问题。但周报顺利,只回答了周报那种负载下的问题。月报把另一个约束带到了面前:一项工作能占多少资源,和它能持续运行多久,需要一起考虑。

对一个正在经营产品的小团队,这也是交付问题。开发者可能盯着“这批数据处理得更快了”,用户同时在意的却是“我现在还能不能正常使用产品”。一次优化如果只记录后台完成时间,就可能漏掉另一边的等待。

设想一个社区场地预约工具。每到月初,工作人员要导出整月使用表;附近居民仍在查询空余时段、提交预约。这是本文的假设场景,不是 Fathom 的业务或测试记录。

开发者准备重写导出逻辑,可以先把要守住的承诺写出来:居民提交预约仍有明确结果,工作人员能知道导出正在进行还是已经失败,失败后重新处理不会让他们拿到几份互相混淆的结果。速度是其中一项,不能代替这些承诺。

接下来,至少需要看三种情境。只跑日常预约时,交互原本怎样;只跑导出时,后台需要怎样的资源;两者重叠时,哪一边先受到影响。还应换一批覆盖更长时间或更多记录的数据,检查之前的结论是否仍适用。这里的“更多”应来自产品真实增长和已知边界,不能随手造一个很轻的样例就宣布通过。

记录也可以很朴素:这次用了什么数据,哪些工作同时发生,用户操作有没有超时,导出有没有完成,失败发生在哪一步。保存这些条件,比只留下一个漂亮的总耗时更有用。下次数据量变化时,团队才知道旧结论覆盖了什么。

如果最终选择让后台任务排队,还需要检查排队对用户意味着什么。导出按钮按下后,界面能否显示已接收?用户离开页面再回来,能否找到同一项任务?失败后是继续原任务,还是创建一份新的结果?这些是产品需要自行设计的行为,不是换一个队列工具就自然得到的能力。

拆小任务同样会带来新的工作。必须知道哪些部分已经完成,重试时怎样避免重复副作用,以及何时可以宣布整份结果完整。否则,后台终于不再拖慢预约,工作人员却拿到一张缺了部分日期的表,问题只是换了位置。

所以,我不会从这篇回顾推出“凡是大任务都要拆开”,也不会照抄 Fathom 当时的并发数字。更实用的做法,是把一次优化的验收写成两句话:在什么数据与同时使用条件下,它改善了什么;在同样条件下,哪些用户承诺仍然成立。条件写不清时,结论也不宜写得太满。

Jack 的回顾保留了几次判断被现实修正的过程。对后来读到它的开发者,这比一个最终配置更有参考价值。下一次准备说“修好了”时,可以回头看一眼:验证的是一封报表、一轮周报,还是下个月真正会发生的那批工作。

资料一:Jack Ellis,Fathom Analytics,《I made a mistake》,2024 年 3 月 7 日。
https://usefathom.com/blog/email-report-queries-mistake

资料二:Joe Dixon,Laravel,《Vapor: Individual Queue Concurrency》,2023 年 1 月 30 日。
https://laravel.com/blog/vapor-individual-queue-concurrency

两篇于 2026 年 11 月 6 日阅读全文。历史过程按作者自述归属;场地预约工具、验收记录与产品行为讨论为本文独立假设和建议,未实际测试 Fathom。

讨论 (0)

0/250

    关于作者

    分享案例

    TA 还没有留下个人简介

    Solo 独立开发者社区support@solo.xin
    关于社区成长规则SOLO.cc隐私政策用户协议商务合作友情链接订阅更新(RSS)投稿赞助

    © 2023 SOLO · 为独立开发者而生