网易首页 > 网易号 > 正文 申请入驻

Stripe监控工具从1租户到100

0
分享至


一个监控工具从单账户用到100个租户,数据库查询慢了47倍,Webhook丢事件,还有人把密钥配错了别人的端点。这是BillingWatch作者晒出的真实踩坑记录。

他用FastAPI+SQLite搭了个"无聊但能用"的方案,却在Stripe路由上卡了整整两周。最后发现,最干净的解法不是共享端点加校验,而是给每个租户发一把专属钥匙。

01 从"给自己用"到"别人也想用"

BillingWatch最初是个单租户工具。作者对接一个Stripe账户,写死配置,跑起来就行。

然后邮件来了。"能支持多个团队吗?""我们子公司有独立Stripe账户。""代理客户需要隔离数据。"

需求很明确:同一套代码,100个租户,数据不能串门。作者选了最朴素的方案——行级隔离。每张表加tenant_id字段,每个查询强制过滤。

代码长这样:

```python @app.get("/anomalies") def list_anomalies(tenant_id: str = Depends(get_tenant_id), db: Session = Depends(get_db)): return db.query(Anomaly).filter(Anomaly.tenant_id == tenant_id).all() ```

「每个端点、每次查询、每个仪表盘请求都这么处理。无聊,但有效。」作者原话。

SQLite在测试环境够用,生产可切Postgres。没有花哨的多数据库路由,没有按租户分片。就一个WHERE条件,堵死所有跨租户泄漏的可能。

02 Webhook路由:100个账户的头痛问题

查询隔离简单,Stripe webhook才是硬骨头。


Stripe要求每个账户配置独立的webhook端点,接收支付成功、退款、争议通知。100个租户意味着100个不同的Stripe账户,都要往你的服务器推事件。

最脏的方案:所有租户共享一个端点,靠payload里的账户ID路由。作者试过,很快放弃。

「Stripe的签名验证用的是账户级密钥。你先得用密钥A验签,失败了换密钥B,再失败换密钥C……100个租户就是100次尝试,延迟爆炸,日志里全是误报。」

更糟的是安全风险。共享端点意味着任何租户的验签失败都会暴露其他租户的存在,时序攻击能猜出有效账户范围。

作者换了思路:反向操作。不给租户一个共享入口,给每个租户发专属URL。

```python @app.post("/webhook/{tenant_token}") async def stripe_webhook(tenant_token: str, request: Request): tenant = db.query(Tenant).filter(Tenant.webhook_token == tenant_token).first() if not tenant: raise HTTPException(status_code=404) # 用该租户自己的密钥验签 event = stripe.Webhook.construct_event(payload, sig, tenant.webhook_secret) process_event(event, tenant.id) ```

租户在Stripe后台配置的是`https://yourdomain.com/webhook/abc123def`,其中abc123def是随机生成的唯一token。找不到token直接404,找到才用对应密钥验签。

「干净隔离,没有共享密钥。每个租户的事件流物理上就是不同的HTTP端点。」

03 幂等性:Stripe的"至少一次"承诺

Stripe保证webhook至少送达一次。网络抖动、服务器重启、502错误都会触发重试。100个租户的中等流量下,重复事件开始堆积。

作者加了张极简的幂等表:

```python class ProcessedEvent(Base): event_id = Column(String, primary_key=True) # Stripe事件ID tenant_id = Column(String, nullable=False) processed_at = DateTime ```


处理前先查:`SELECT 1 FROM processed_events WHERE event_id=? AND tenant_id=?`。命中就跳过,没命中才执行业务逻辑,最后INSERT。

复合索引(event_id, tenant_id)让查询在百万行数据下保持亚毫秒级。SQLite扛得住,切Postgres后性能更稳。

「有个细节:Stripe事件ID是全局唯一的,但我们的幂等键是复合的。万一两个租户恰好收到同名事件?理论可能,实际没发生。复合键是多租户的安全带。」

04 被嫌"太简单"的方案,为什么作者坚持

作者在HN帖子下回复过一条评论。有人问:为什么不用更"优雅"的方案,比如按租户分数据库,或者用消息队列解耦?

「我试过EventBridge+SQS的架构。租户50的时候,CloudWatch账单先让我清醒了。现在这套代码,新租户注册就是INSERT一行,配个webhook URL,5分钟上线。」

行级隔离的代价是查询都要带tenant_id。但作者算了笔账:100个租户,假设每个每天产生1000条事件,一年才3650万行。SQLite单文件上限140TB,Postgres分区表能撑到百亿级。

「复杂度是渐进式加的。SQLite变慢了?加索引。还不够?切Postgres。再不够?按时间分区。每一步都有明确的瓶颈信号,而不是提前为'可能'的问题写2000行配置。」

有个用户反馈让作者印象深。某SaaS公司把BillingWatch嵌进自己的平台,给客户做白标账单监控。他们的运维问:能不能隐藏tenant_id的存在,让界面看起来是"原生"的?

作者回了句:「tenant_id是URL里的path参数,不是cookie。你的客户永远看不到,除非他们开开发者工具——那时候他们已经知道自己在用第三方服务了。」

对方沉默两天,回复:「我们试了另外两家竞品,一家按API调用收费,100租户每月$800;另一家强制用他们的托管数据库。你的'无聊方案',我们fork后自己部署了。」

100个租户,零额外基础设施成本,代码行数从单租户版本的1200行涨到1800行。这600行里,400行是webhook路由和幂等性,200行是租户管理的CRUD。

作者最后补了句:「如果有人问我多租户架构建议,我会说先写最让你不好意思拿出来展示的代码。能跑、能测、能睡个好觉,比'架构优雅'重要十倍。」

你的监控工具是从第几个租户开始重构的?还是还在用"暂时先这样"的单账户方案硬撑?

特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐
热点推荐
儿子去世一周后,白发人送黑发人的张妈妈状态曝光,未来令人心痛

儿子去世一周后,白发人送黑发人的张妈妈状态曝光,未来令人心痛

妙知
2026-03-31 10:42:52
李毅教授这样说牢A,有点太过分了,让沈逸教授情何以堪

李毅教授这样说牢A,有点太过分了,让沈逸教授情何以堪

读鬼笔记
2026-03-30 20:32:04
逆市拉升!600488,一分钟涨停

逆市拉升!600488,一分钟涨停

中国基金报
2026-03-31 12:52:46
AI妓馆爆了,成人行业彻底变天

AI妓馆爆了,成人行业彻底变天

李东阳朋友圈
2026-03-31 11:08:15
快讯!白宫发言人,重大宣布

快讯!白宫发言人,重大宣布

果妈聊娱乐
2026-03-31 08:42:57
教皇利奥罕见发表强硬言论:中东冲突极其恶劣,你们双手沾满鲜血

教皇利奥罕见发表强硬言论:中东冲突极其恶劣,你们双手沾满鲜血

知法而形
2026-03-31 10:54:47
李瑞环说:叶选平是叶帅的儿子,但水平比我高,为啥不能当省长?

李瑞环说:叶选平是叶帅的儿子,但水平比我高,为啥不能当省长?

基斯默默
2026-03-31 08:20:29
比赖清德更狂的人出现了,只要她当上台湾领导人,解放军必定收台

比赖清德更狂的人出现了,只要她当上台湾领导人,解放军必定收台

共工之锚
2026-03-29 18:26:19
刚刚,直线飙升!特朗普,突然释放重磅信号!

刚刚,直线飙升!特朗普,突然释放重磅信号!

数据宝
2026-03-31 11:31:45
三野名将不听粟裕调遣,出言不逊后甩手离去,主席:立刻撤职 

三野名将不听粟裕调遣,出言不逊后甩手离去,主席:立刻撤职 

纪实文录
2025-05-10 17:45:35
郑丽文表态愿跟赖清德见面:台湾不能无穷无尽恶斗下去

郑丽文表态愿跟赖清德见面:台湾不能无穷无尽恶斗下去

海峡导报社
2026-03-30 15:17:02
丹麦男友去世后,东北姑娘仍为他生下遗腹子,还为了公婆定居丹麦

丹麦男友去世后,东北姑娘仍为他生下遗腹子,还为了公婆定居丹麦

星星没有你亮
2026-03-22 08:48:35
绝对“钞能力”!哈兰德用不到一周工资,入手限量LV联名迈巴赫!

绝对“钞能力”!哈兰德用不到一周工资,入手限量LV联名迈巴赫!

田先生篮球
2026-03-30 21:35:46
男演员最新声明:已退出美国国籍,正式成为中国公民

男演员最新声明:已退出美国国籍,正式成为中国公民

去山野间追风
2026-03-30 01:31:53
74岁港星施明病逝,儿子没见最后一面泣不成声,李家鼎仍无法接受

74岁港星施明病逝,儿子没见最后一面泣不成声,李家鼎仍无法接受

白面书誏
2026-03-31 14:43:13
车管所正式通知:C1驾照“2取消、1增加”已执行,车主尽早了解。

车管所正式通知:C1驾照“2取消、1增加”已执行,车主尽早了解。

沙雕小琳琳
2026-03-31 09:30:37
0-2,国足输球仍有含金量 林良铭丢单刀 邵佳一变阵半场不落下风

0-2,国足输球仍有含金量 林良铭丢单刀 邵佳一变阵半场不落下风

替补席看球
2026-03-31 15:56:18
老战友AA聚会每人交3100元,次日警察上门:你的9位战友全出事了

老战友AA聚会每人交3100元,次日警察上门:你的9位战友全出事了

晓悦流年
2025-11-20 15:31:22
外交部:中方强烈谴责

外交部:中方强烈谴责

第一财经资讯
2026-03-31 11:27:44
2026年交警正式更名交管!不止换称呼,罚单、停车、换驾照全变了

2026年交警正式更名交管!不止换称呼,罚单、停车、换驾照全变了

混沌录
2026-03-20 21:00:04
2026-03-31 17:40:49
赛博兰博
赛博兰博
专注捣鼓AI效率工具,试图在这个时代留下数字分身的探索者。
552文章数 5关注度
往期回顾 全部

科技要闻

尚未正式宣发,国行苹果AI半夜"意外闪现"

头条要闻

00后女孩回国当职业扫墓人:每天鞠躬上百次 月薪4千多

头条要闻

00后女孩回国当职业扫墓人:每天鞠躬上百次 月薪4千多

体育要闻

县城修车工,用20年成为世界冠军

娱乐要闻

丝芭传媒举报鞠婧祎:瞒报收入竟达85%

财经要闻

高薪内推藏陷阱!"招转培"骗局盯上求职者

汽车要闻

腾势Z9GT到底GT在哪?

态度原创

家居
本地
手机
数码
公开课

家居要闻

新婚爱巢 甜蜜情趣拉满

本地新闻

用Color Walk的方式解锁城市春日

手机要闻

国行iPhone突现Apple智能,苹果回应了

数码要闻

华硕推出Prime RTX 5080 EVO显卡,相较原版取消均热板

公开课

李玫瑾:为什么性格比能力更重要?

无障碍浏览 进入关怀版