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

SaaS定制困局:一个代码库如何服务千个客户

0
分享至

每个做大的SaaS产品都会撞上同一堵墙:客户提了个专属需求,你做了,代码库里就多了一段只为一家租户跑的逻辑。一年后,这样的"特例"攒了十几个。代码里到处是判断租户ID的if语句,测试套件要模拟各种客户专属分支,唯一清楚哪段代码归哪个客户的资深工程师成了重构工作的瓶颈。

有没有更好的办法?有。而且不用放弃按客户定制的灵活性。关键是把"能做什么"的代码和"选哪个做"的数据彻底分开。这篇文章讲怎么做、数据存哪儿、以及一个致命的安全陷阱——如果你让数据变成代码,就会掉下悬崖。


先说什么不能做。几种常见方案各有硬伤:


第一,给每个客户单独部署实例。这等于把运营面也分叉了:N套数据库、N组后台任务、N条部署流水线、N个版本的bug修复要滚动。两三个客户还能撑,到十个就崩。

第二,后端写条件代码——if tenant_id == "acme": ...。第一天便宜,第六个月就扛不住。每个开发者都得摸清客户版图才能安全改代码,每次重构风险跟租户分支数成正比,客户专属逻辑像毛细血管一样蔓延。

第三,构建时注入代码。靠配置生成不同二进制文件,运营成本和单独实例一样高,还得享受"调试行为取决于编译时flag"的额外乐趣。别这么干。

能扩展的模式是:一个代码库、一个运行集群、一条部署流水线——让租户专属行为活在代码查询的数据里。说白了,这就是多租户架构。

具体怎么做?先定位系统里行为能按租户变化的地方:折扣引擎、审批流、导出格式、通知规则。这些叫扩展点。在每个扩展点,代码定义一小套已知行为,租户数据负责选哪个行为、传什么参数。

典型的实现是类层次结构。比如一个CustomRule基类,约定两个方法——applies?(context)判断是否适用,apply(context)执行逻辑。然后是一组具体实现:

class CustomRule:
def applies(self, context) -> bool: ...
def apply(self, context) -> None: ...


class PercentageDiscountRule(CustomRule):
def __init__(self, percent, min_order):
self.percent = percent
self.min_order = min_order
def applies(self, context):
return context.order_total >= self.min_order
def apply(self, context):
context.discount += context.order_total * (self.percent / 100)

class FirstPurchaseDiscountRule(CustomRule): ...

代码只定义可能性,数据决定选哪个。租户配置表里存的是规则类型和参数,比如{"rule_type": "PercentageDiscountRule", "percent": 10, "min_order": 100}。运行时加载、实例化、执行。

数据存在哪?数据库就行,但要考虑缓存和版本控制。规则变更需要审计日志,回滚要快速。别把规则塞进应用配置——那是代码,不是数据。

最后那个安全悬崖:如果让数据变成代码,你就完了。永远不要eval()租户输入,不要动态加载租户上传的模块,不要把规则写成自由形式的脚本。数据只能是数据,结构化的、可验证的、沙箱化的。一旦数据能执行任意逻辑,多租户的安全模型就塌了。

这套模式的核心就一句话:代码是通用的,数据是专属的。守住这条线,一个代码库服务一千个客户,不是神话。

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

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.

相关推荐
热点推荐
菲律宾专家:如果中国真咄咄逼人,为什么我们能在仁爱礁待24年!

菲律宾专家:如果中国真咄咄逼人,为什么我们能在仁爱礁待24年!

田园小归
2026-06-01 09:29:48
谷爱凌把米兰冬奥会全部奖金796万自己4万,一共800万全部捐出去

谷爱凌把米兰冬奥会全部奖金796万自己4万,一共800万全部捐出去

离离言几许
2026-03-09 22:43:32
今年秋季登场 全新三菱帕杰罗预告图发布

今年秋季登场 全新三菱帕杰罗预告图发布

车质网
2026-06-01 09:18:08
人间恶魔!32岁男子伪装成15岁,骗11岁女孩开房!施暴致其染性病

人间恶魔!32岁男子伪装成15岁,骗11岁女孩开房!施暴致其染性病

川渝视觉
2026-05-30 22:40:22
“你的教资不想要了?”男老师抱着学生拍视频,网友都看不下去了

“你的教资不想要了?”男老师抱着学生拍视频,网友都看不下去了

妍妍教育日记
2026-05-31 09:25:07
新华社下场,耿同学又抛出4条大鱼!

新华社下场,耿同学又抛出4条大鱼!

仕道
2026-05-30 09:52:28
杨鸣再爆金句!33分屠杀 广厦充足季后赛经验 却一文不值?

杨鸣再爆金句!33分屠杀 广厦充足季后赛经验 却一文不值?

你看球呢
2026-06-01 10:36:49
日韩股市续创新高 韩国综合指数涨近1.5%

日韩股市续创新高 韩国综合指数涨近1.5%

每日经济新闻
2026-06-01 08:25:12
人口告别世界第一?催生“二孩”无效后,国家终于向住房出手了!

人口告别世界第一?催生“二孩”无效后,国家终于向住房出手了!

混沌录
2026-05-30 23:41:14
震撼!超150万人参加阿森纳夺冠游行 赖斯高歌:定位球又来了哈哈

震撼!超150万人参加阿森纳夺冠游行 赖斯高歌:定位球又来了哈哈

风过乡
2026-06-01 06:07:36
《主角》还没收官就停播?疑似有3个原因,都在说明它是一个好剧

《主角》还没收官就停播?疑似有3个原因,都在说明它是一个好剧

可乐谈情感
2026-06-01 06:21:07
虎父无犬子!曼联名宿19岁爱子压哨入选世界杯名单

虎父无犬子!曼联名宿19岁爱子压哨入选世界杯名单

仰卧撑FTUer
2026-05-31 18:57:03
人类灭绝已成定局?科学家算出人类灭绝日期,我们还能幸存多久?

人类灭绝已成定局?科学家算出人类灭绝日期,我们还能幸存多久?

蜉蝣说
2026-05-28 19:49:46
理想高管:目前没见到过任何一台SUV 滤震舒适性超过全新L9 Ultra

理想高管:目前没见到过任何一台SUV 滤震舒适性超过全新L9 Ultra

快科技
2026-05-31 13:58:07
医生:只要低密度脂蛋白没这个数,高血脂并发症风险就不用太焦虑

医生:只要低密度脂蛋白没这个数,高血脂并发症风险就不用太焦虑

健康科普365
2026-05-31 13:05:09
又美又能打:2-0,世界第8完胜泰希曼,安德列娃昂首挺进法网女单8强

又美又能打:2-0,世界第8完胜泰希曼,安德列娃昂首挺进法网女单8强

凌空倒钩
2026-06-01 01:01:47
美国选手跑出9秒89打破白人男子百米世界纪录

美国选手跑出9秒89打破白人男子百米世界纪录

林子说事
2026-05-31 12:37:41
1-0爆冷!天津津门虎掀翻中超第3名,于根伟把4队拖入保级军团

1-0爆冷!天津津门虎掀翻中超第3名,于根伟把4队拖入保级军团

何老师呀
2026-05-31 21:04:48
对越反击战走出的五位传奇上将

对越反击战走出的五位传奇上将

祁州校尉
2026-05-31 13:00:17
1949年,渡江战役若晚20天开战,中国可能被推入分裂深渊

1949年,渡江战役若晚20天开战,中国可能被推入分裂深渊

鹤羽说个事
2026-05-29 22:59:33
2026-06-01 11:31:00
灰度测试中
灰度测试中
生活正在重构,目前还在灰度测试阶段,暂不全量发布。
4252文章数 32关注度
往期回顾 全部

科技要闻

关停三年后,天涯社区今起开放访问

头条要闻

牛弹琴:巴黎又乱了火光冲天 马克龙都看得目瞪口呆

头条要闻

牛弹琴:巴黎又乱了火光冲天 马克龙都看得目瞪口呆

体育要闻

哭过之后,文班亚马想给波波维奇打电话

娱乐要闻

张凌赫活动商场玻璃被挤爆5人受伤

财经要闻

网红驱蚊产品,标注化妆品竟含农药成分

汽车要闻

卖车卖到手软 MG4 5月销量突破15000台

态度原创

房产
本地
游戏
艺术
公开课

房产要闻

红动五月!全国抢入核心资产,广州盯紧凯旋新世界!

本地新闻

用剪纸的方式,打开江苏扬州

老外压抑了!《漫威争锋》黑猫新皮肤翘臀变大引热议

艺术要闻

李讷刘思齐邵华童年照曝光!"红二代"狂草热榜,大草为何难写好?

公开课

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

无障碍浏览 进入关怀版