上一篇《SaaS 多租户数据隔离》讲了字段级隔离的全景:租户插件自动改写 SQL,业务代码零感知。但“零感知”的前提是插件每改一条 SQL 都能答对一个问题——当前租户是谁。
这个问题看起来不起眼,其实被问得极频繁:一次分页查询,主表问一次、count 再问一次、每张关联表各问一次;一次页面渲染,几十条 SQL 就是上百次提问。而答案可能来自四个完全不同的地方——线程里、请求缓存里、Redis 里、token 里。**动态租户的实现,
上一篇《SaaS 多租户数据隔离》讲了字段级隔离的全景:租户插件自动改写 SQL,业务代码零感知。但“零感知”的前提是插件每改一条 SQL 都能答对一个问题——当前租户是谁。
这个问题看起来不起眼,其实被问得极频繁:一次分页查询,主表问一次、count 再问一次、每张关联表各问一次;一次页面渲染,几十条 SQL 就是上百次提问。而答案可能来自四个完全不同的地方——线程里、请求缓存里、Redis 里、token 里。**动态租户的实现,
想象一个场景:你把一套企业管理系统卖给 50 家公司用。每家公司都觉得自己“独享”这套系统——自己的员工、自己的资产、自己的单据,谁也看不见谁。而对你来说,只有一套代码、最好也只有一套数据库,不然 50 家公司的版本升级能把运维逼疯。
这就是 SaaS 多租户的核心矛盾:客户要隔离感,你要低成本。这套机制的难点不在“加个字段”,而在于:租户 ID 从哪来、怎么自动跟着每一条 SQL 走、缓存和登录态怎么隔离,以及运维人员临时“替某个租户干活”时怎么安全切换。
这篇基于 RuoYi-Vue-Plus 的租户模块(`ruoyi-comm
想象一个场景:你做了套企业管理软件,最早是一家客户一家客户地卖——装服务器、部署、培训、收钱,典型的传统软件生意。后来你想清楚了要做 SaaS:客户按月付费、打开浏览器就能用。第一家中型客户签了,第二十家也签了,直到有一天,一家银行说:“数据必须物理隔离,或者这单免谈。”
这时候你的架构怎么摆?这就是 SaaS 架构演进要回答的问题。这篇是 SaaS 系列的开篇,讲清整条演进路线的“为什么”,后面的租户隔离、生命周期、套餐计费都长在这条线上。
起步阶段最自然的做法:每个客户独立部署一套应用和数据库。
想象一个场景:月底对账,财务拿着报表来问——这个客户 8 月账单怎么算出来的?他 8 月 10 号从基础版升到专业版,补了差价;15 号又加了 5 个席位;隔壁那个按用量计费的客户调了 120 万次 API……三笔钱三套算法,对不上账。
这就是 SaaS 计费的全部难度所在:计费不难,“变化中的计费”才难。客户随时升级、降级、加减席位、退订,每一笔变更都要折算成公平的金额。这篇把套餐、订阅、计费模式与升降级结算一次讲清。
只占 40%,sy(内核态)却占了一半——CPU 忙了半天,一大半时间不是在跑你的业务代码,而是在替你跑内核的代码。
时间去哪了?要回答这个问题,得先搞懂这篇文章的主题:CPU 其实有两个"档位",你的代码和内核的代码,各在其中一个档位上跑。这两个档位怎么划分、什么时候切换、切换为什么有开销,就是"用户态与内核态"的全部内容。
文末附一个能自己跑的实测程序:纯用户态操作和"进内核"操作,单次耗时差了四五个数量级。这不
想象一个场景:活动页上线,两个入口同时在扣同一份库存,各扣 10 万次,运营对账时发现账对不上——凭空少了一截。日志里没有任何报错,把请求单独重放一遍,每一笔又都是对的。这种“单看每一步都对,合在一起就是错”的问题,十有八九出在并发。
volatile、synchronized、AtomicInteger、线程池——这些东西平时都在用,但“各自到底解决什么问题、为什么要配合着用”,值得系统梳理一遍。这篇就按这条线走:先看多线程为什么会出事,再按“一个问题一把钥匙”讲每件工具,最后讲线程池怎么配。文中的示例代码都实际跑过(JDK 21),运
学了 ReentrantLock、读写锁、Semaphore、CountDownLatch 之后,可能有过一个疑问:这一堆工具,底层是不是各写各的?不是,它们底下全是同一个东西——AQS(AbstractQueuedSynchronizer,抽象队列同步器)。JUC 里大半的同步工具,都是在这一个框架上搭出来的。这篇把它拆开看:state 是什么、队列怎么排、线程怎么挂起又怎么被唤醒。理解了 AQS,上面那一堆工具就不再是几个孤立的 API,而是同一套机制的不同用法。
上游文章:《[ReentrantLock 详解](/ful