精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

揭秘!多租戶 SaaS 系統這樣設計:數據庫級/表級隔離 + 資源配額全攻略

數據庫 其他數據庫
我們已經在多個 SaaS 項目中實現了從數百到數十萬租戶的平滑擴展,既保證了數據安全,又實現了資源的高效利用。

在參與多個大型 SaaS 平臺的架構設計之后,我逐漸發現,多租戶架構的核心價值并不只是“共享”,而是“隔離 + 配額”。 一方面,我們必須確保不同租戶之間的數據嚴格分離,以滿足合規性與安全性;另一方面,還需要限制資源消耗,避免某些租戶“獨占”系統性能。

本文將結合實踐經驗,全面拆解 多租戶 SaaS 系統的數據隔離方案(數據庫級 / 表級 / 行級)與資源配額控制策略,并給出核心代碼示例,幫助你在實際項目中快速落地。

什么是多租戶架構?

多租戶(Multi-Tenancy)是一種典型的 SaaS 模式:

  • 單實例運行:一套系統為多個租戶(Tenant)服務。
  • 邏輯隔離:每個租戶擁有獨立的業務空間,但共享基礎設施(數據庫、存儲、計算資源)。

多租戶架構需要解決兩個關鍵問題:

  1. 數據隔離 —— 確保租戶之間互不干擾。
  2. 資源配額 —— 控制存儲、API 調用、并發用戶數等,防止“資源搶占”。

數據隔離方案對比與實現

在多租戶架構下,數據隔離常見有三種方式:數據庫級、表級和行級。

數據庫級隔離

架構思路:每個租戶獨立一個數據庫。

+-------------------+     +-------------------+     +-------------------+
| Tenant A Database |     | Tenant B Database |     | Tenant N Database |
+-------------------+     +-------------------+     +-------------------+
|    Users Table    |     |    Users Table    |     |    Users Table    |
|    Orders Table   |     |    Orders Table   |     |    Orders Table   |
+-------------------+     +-------------------+     +-------------------+

代碼實現:動態數據源路由

// 文件路徑: src/main/java/com/icoderoad/tenant/TenantRoutingDataSource.java
public class TenantRoutingDataSource extends AbstractRoutingDataSource {
    @Override
    protected Object determineCurrentLookupKey() {
        return TenantContextHolder.getTenantId(); // 基于 ThreadLocal 獲取租戶ID
    }
}
// 文件路徑: src/main/java/com/icoderoad/tenant/TenantContextHolder.java
public class TenantContextHolder {
    private static final ThreadLocal<String> CONTEXT = new ThreadLocal<>();
    public static void setTenantId(String tenantId) { CONTEXT.set(tenantId); }
    public static String getTenantId() { return CONTEXT.get(); }
    public static void clear() { CONTEXT.remove(); }
}

表級隔離

架構思路:所有租戶共享數據庫,但每個租戶有獨立的表(加前綴)。

+---------------------+
|   Shared Database   |
+---------------------+
| TenantA_Users_Table |
| TenantA_Orders_Table|
| TenantB_Users_Table |
| TenantB_Orders_Table|
+---------------------+

代碼實現:動態表名攔截器(MyBatis)

// 文件路徑: src/main/java/com/icoderoad/tenant/TableNameInterceptor.java
@Intercepts({
    @Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class, Integer.class})
})
public class TableNameInterceptor implements Interceptor {
    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        StatementHandler handler = (StatementHandler) invocation.getTarget();
        BoundSql boundSql = handler.getBoundSql();
        String tenantId = TenantContextHolder.getTenantId();
        String modifiedSql = boundSql.getSql().replaceAll("\\b(user|order)\\b", tenantId + "_$1");
        Field field = boundSql.getClass().getDeclaredField("sql");
        field.setAccessible(true);
        field.set(boundSql, modifiedSql);
        return invocation.proceed();
    }
}

行級隔離

架構思路:單庫單表,通過 tenant_id 字段區分租戶。

+-------------------+
|  Shared Database  |
+-------------------+
| Users Table       | tenant_id + user_id
| Orders Table      | tenant_id + order_id
+-------------------+

代碼實現:自動注入租戶 ID

// 文件路徑: src/main/java/com/icoderoad/tenant/TenantIdInterceptor.java
@Intercepts({
    @Signature(type = Executor.class, method = "update", args = {MappedStatement.class, Object.class})
})
public class TenantIdInterceptor implements Interceptor {
    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        Object parameter = invocation.getArgs()[1];
        String tenantId = TenantContextHolder.getTenantId();
        if (parameter instanceof BaseEntity) {
            ((BaseEntity) parameter).setTenantId(tenantId);
        }
        return invocation.proceed();
    }
}

資源配額控制

在多租戶系統中,資源配額控制防止“資源獨占”。

通用資源模型

// 文件路徑: src/main/java/com/icoderoad/quota/TenantQuota.java
@Entity
@Table(name = "tenant_quota")
public class TenantQuota {
   @Id
   private String tenantId;
   private Long storageQuota;
   private Long storageUsed;
   private Long apiCallQuota;
   private Long apiCallsUsed;
   private Integer concurrentUserQuota;


   public boolean canUseStorage(long size) {
      return (storageUsed + size) <= storageQuota;
   }
}

攔截器控制 API 調用

// 文件路徑: src/main/java/com/icoderoad/quota/QuotaInterceptor.java
public class QuotaInterceptor implements HandlerInterceptor {
    @Autowired private TenantQuotaService quotaService;
    @Override
    public boolean preHandle(HttpServletRequest req, HttpServletResponse res, Object handler) throws Exception {
        String tenantId = getTenantIdFromRequest(req);
        TenantQuota quota = quotaService.getQuota(tenantId);
        if (quota.getApiCallsUsed() >= quota.getApiCallQuota()) {
            res.setStatus(HttpStatus.TOO_MANY_REQUESTS.value());
            res.getWriter().write("API call quota exceeded");
            return false;
        }
        quotaService.recordApiCall(tenantId);
        return true;
    }
}

分布式配額控制(Redis 方案)

// 文件路徑: src/main/java/com/icoderoad/quota/RedisQuotaServiceImpl.java
@Service
public class RedisQuotaServiceImpl implements QuotaService {
    @Autowired private RedisTemplate<String, Long> redisTemplate;
    private static final String QUOTA_KEY_PREFIX = "tenant:quota:";
    private static final String USAGE_KEY_PREFIX = "tenant:usage:";


    @Override
    public boolean checkAndConsume(String tenantId, String resourceType, long amount) {
        String quotaKey = QUOTA_KEY_PREFIX + tenantId + ":" + resourceType;
        String usageKey = USAGE_KEY_PREFIX + tenantId + ":" + resourceType;
        String script =
            "local usage = redis.call('GET', KEYS[2]) or 0 " +
            "if usage + ARGV[1] > tonumber(ARGV[2]) then return 0 " +
            "else return redis.call('INCRBY', KEYS[2], ARGV[1]) end";
        Long result = redisTemplate.execute(new DefaultRedisScript<>(script, Long.class),
                Arrays.asList(quotaKey, usageKey), amount, redisTemplate.opsForValue().get(quotaKey));
        return result != null && result > 0;
    }
}

認證與權限控制

  1. JWT 提取租戶 ID 在過濾器中解析 JWT,并寫入 TenantContextHolder。
  2. Spring Security 細粒度權限 通過 isTenantUser(tenantId) 方法實現基于租戶的訪問限制。

最佳實踐與方案選擇

  • 數據庫級隔離:適用于安全性要求極高、租戶數量有限的場景。
  • 表級隔離:兼顧隔離性與成本。
  • 行級隔離:適用于大規模、多租戶場景。

配額管理建議

  • 多層控制:應用層 + 基礎設施層雙保險。
  • 提前預警:當資源使用接近閾值時提醒租戶升級。
  • 彈性伸縮:結合計費與限流機制。

結論

多租戶 SaaS 架構的核心挑戰在于:數據的干凈隔離資源的公平分配。

  • 在數據層面,數據庫/表/行級隔離各有優劣,需要根據業務規模與成本選擇。
  • 在資源層面,通用配額模型 + Redis 分布式限流是高并發場景下的最佳實踐。
  • 在安全層面,基于 JWT 的租戶上下文和 Spring Security 的細粒度權限控制可確保租戶之間權限清晰。

通過上述方案,我們已經在多個 SaaS 項目中實現了從數百到數十萬租戶的平滑擴展,既保證了數據安全,又實現了資源的高效利用。

未來的 SaaS 架構演進中,多租戶隔離與配額管理仍會是不可或缺的基礎能力。

責任編輯:武曉燕 來源: 路條編程
相關推薦

2015-03-04 13:53:33

MySQL數據庫優化SQL優化

2023-06-07 13:50:00

SaaS多租戶系統

2023-12-14 12:26:16

SaaS數據庫方案

2010-08-10 09:53:47

DB2數據庫補丁

2011-02-25 10:29:01

JavaOracleDB2

2014-03-19 17:22:33

2025-07-14 07:07:22

Spring多場景抽獎

2012-03-02 16:05:16

筆記本推薦

2009-11-10 12:08:15

2025-09-11 03:00:00

2010-05-26 11:22:08

2013-04-15 10:48:16

Xcode ARC詳解iOS ARC使用

2024-05-07 09:01:21

Queue 模塊Python線程安全隊列

2013-06-08 11:13:00

Android開發XML解析

2010-04-23 14:04:23

Oracle日期操作

2009-12-11 14:03:47

Windows路由表

2010-05-18 11:12:21

2015-08-12 15:46:02

SaaS多租戶數據存儲

2011-09-20 10:01:35

投影儀常見問題

2009-12-14 14:32:38

動態路由配置
點贊
收藏

51CTO技術棧公眾號

国产亚洲毛片在线| 精品人人人人| 亚洲女人的天堂| 国产精品播放| 日本黄色一级视频| 亚洲一级毛片| 日韩精品中文在线观看| 国产精品嫩草影院8vv8| aa级大片免费在线观看| 国产欧美精品一区二区三区四区| 亚洲最大福利视频| 中文字幕精品无码一区二区| 亚洲无中文字幕| 亚洲精品少妇网址| 18深夜在线观看免费视频| 婷婷六月国产精品久久不卡| 亚洲一区二区视频在线| 视频在线一区二区三区| 日韩一级中文字幕| 国内精品写真在线观看| 日韩美女主播视频| 久久国产精品二区| 欧美日韩国产一区二区三区不卡| 精品欧美黑人一区二区三区| 国产小视频精品| 婷婷电影在线观看| 一区二区三区蜜桃网| 色一情一乱一伦一区二区三区| 秋霞视频一区二区| 国产真实乱对白精彩久久| 国产成人久久久| 在线观看国产亚洲| 精品二区视频| 欧美老女人xx| 东方av正在进入| 日韩视频在线观看| 在线日韩精品视频| 丰满少妇一区二区| 日韩av午夜| 亚洲电影av在线| 国产chinesehd精品露脸| 亚洲人成网站在线在线观看| 欧美丝袜丝交足nylons图片| 国产熟人av一二三区| 神马午夜在线视频| 午夜精品一区二区三区电影天堂| 日韩一级免费看| 怡红院在线播放| 亚洲三级在线免费观看| 制服国产精品| 日本美女高清在线观看免费| 国产精品天美传媒| 翔田千里亚洲一二三区| 国产美女视频一区二区三区 | 日韩免费观看高清| 日韩激情在线播放| 日韩午夜在线| 欧美亚洲国产视频| 国产农村妇女aaaaa视频| 一区二区三区成人精品| 欧美孕妇与黑人孕交| 国产成人在线免费视频 | 91国内在线视频| 日本特黄特色aaa大片免费| 极品av少妇一区二区| 欧美精品电影在线| 国产又大又黑又粗免费视频| 亚洲一区二区三区四区五区午夜| 奇米影视亚洲狠狠色| 天干夜夜爽爽日日日日| 日韩**一区毛片| 成人午夜一级二级三级| 国产高清第一页| 不卡一区二区三区四区| 久久久久久久久久久久久久久久av| 国产又爽又黄网站亚洲视频123| ww久久中文字幕| 日韩av影视| a天堂中文在线官网在线| 亚洲一区二区三区自拍| 久久久久狠狠高潮亚洲精品| 国产69精品久久久久按摩| 91精品国产综合久久久久久久久久 | 九九九九九精品| 成人免费视频| 一区二区三区四区中文字幕| 免费观看国产精品视频| 少妇一区视频| 在线不卡a资源高清| 岛国精品一区二区三区| 曰本一区二区三区视频| 久久人人爽人人爽人人片亚洲| 免费毛片在线播放免费| 久久精品道一区二区三区| 成人www视频在线观看| 欧美一区二不卡视频| 国产午夜亚洲精品午夜鲁丝片| 国产三级中文字幕| av电影一区| 6080日韩午夜伦伦午夜伦| 朝桐光av一区二区三区| 日韩免费高清| 97在线看免费观看视频在线观看| 中文字幕一区二区三区波野结 | brazzers精品成人一区| 亚洲精品极品少妇16p| 欧美一级黄色网| 国产av无码专区亚洲av| 国产亚洲va综合人人澡精品| 99在线观看视频免费| www成人在线视频| 亚洲成人网久久久| 国产人与禽zoz0性伦| 亚洲男女自偷自拍| 成人毛片网站| 久久77777| 在线观看精品一区| 菠萝菠萝蜜网站| 欧美久久久久| 成人黄色网免费| lutube成人福利在线观看| 五月天国产精品| 超碰人人cao| 欧美顶级大胆免费视频| 日韩av片永久免费网站| 欧美性受xxxx狂喷水| 日韩一区欧美小说| 欧美婷婷精品激情| 欧美女优在线视频| 91精品国产电影| 日韩有码第一页| 亚洲黄色av一区| 午夜激情影院在线观看| 日韩精品四区| 国产精品久久久久久久久粉嫩av| 欧美伦理影视网| 狠狠爱在线视频一区| 久久久久久婷婷| 亚洲精品欧美| 久久国产精品一区二区三区| 91破解版在线观看| 精品久久久久久综合日本欧美| 欧美一级片在线视频| 久久精品久久久精品美女| 日韩精品一区二区三区外面 | 亚洲第一伊人| 国产精品日韩欧美一区二区三区| 青春草在线免费视频| 欧美一卡2卡三卡4卡5免费| 国产午夜精品理论片在线| 久久成人综合网| 正义之心1992免费观看全集完整版| 国产精品无码久久久久| 日韩在线观看免费高清| 91国产免费视频| 中文字幕一区二区三区精华液 | 日本免费精品| 欧美国产欧美亚洲国产日韩mv天天看完整| 99国产精品久久久久99打野战| 亚洲精品国产无套在线观| 亚洲成人av免费观看| 国产中文一区| 久久亚洲高清| 岛国精品在线| 欧美猛交ⅹxxx乱大交视频| 国产成人av免费看| 亚洲va天堂va国产va久| 女~淫辱の触手3d动漫| 奇米四色…亚洲| 偷拍盗摄高潮叫床对白清晰| 97视频一区| 欧美亚洲另类激情另类| 福利成人在线观看| 日韩一区二区三区电影| 日韩三级视频在线播放| 国产亚洲婷婷免费| 欧美视频亚洲图片| 狠久久av成人天堂| 欧美日韩高清在线一区| 国产亚洲精品精品国产亚洲综合| 久久精品国产欧美激情| 成人毛片在线精品国产| 日本大香伊一区二区三区| 亚洲色图 激情小说| 国产精品一品二品| 日韩av一二三四| 99热国内精品永久免费观看| 国产精品一区二区三区四区五区| 蜜桃精品在线| 久久久久九九九九| 麻豆app在线观看| 欧美一级免费大片| 中文字幕免费观看| 一区二区欧美在线观看| 丰腴饱满的极品熟妇| 国产精品一区二区黑丝 | 狠狠v欧美v日韩v亚洲ⅴ| 国产成人永久免费视频| 色呦哟—国产精品| 国产一区二区三区四区hd| 成人深夜福利| 91精品国产沙发| 浪潮av一区| 亚洲午夜av久久乱码| 亚洲精品第五页| 欧美色精品在线视频| 粉嫩aⅴ一区二区三区| 亚洲欧美日本在线| 亚洲久久久久久久| av在线一区二区三区| 日韩在线一区视频| 久久亚洲不卡| 欧美日韩一道本| 亚洲一区二区| 影音先锋亚洲视频| 中文有码一区| 精品免费一区二区三区蜜桃| 欧美午夜在线播放| 国产精品视频导航| 国产精欧美一区二区三区蓝颜男同| 欧美乱人伦中文字幕在线| 69视频在线观看| 亚洲欧美日韩一区二区在线 | 国产欧美一区二区三区鸳鸯浴| 四虎精品一区二区| 国产精品一区不卡| 色网站在线视频| 久久精品99国产国产精| 天天干在线影院| 午夜综合激情| www国产精品内射老熟女| 国产精品hd| 丰满人妻一区二区三区53号| 在线成人直播| 无码人妻精品一区二区蜜桃百度| 久久精品亚洲人成影院 | 国产日韩一区二区| 日韩在线精品强乱中文字幕| 国产精品一区二区久久| 草莓视频成人appios| 日韩女优在线播放| 成人自拍av| 国产suv精品一区二区| 欧美日韩国产v| 日韩免费av一区二区| 成人免费网站www网站高清| 日本精品久久久久久久| 免费福利视频一区二区三区| 欧美在线xxx| 666av成人影院在线观看| 国产精品久久久久9999| 日韩中文在线播放| 国产精品一区二区久久精品| 亚洲日日夜夜| www.成人av.com| 国产精品对白| 欧美精品人人做人人爱视频| 九九热爱视频精品视频| 亚洲精美视频| 91精品国产91久久久久久密臀| 成人性做爰片免费视频| 欧美日韩综合| 老太脱裤让老头玩ⅹxxxx| 久久福利影视| 视频二区在线播放| 国产原创一区二区三区| 精人妻一区二区三区| 91在线小视频| 我想看黄色大片| 亚洲人123区| 久久中文字幕无码| 欧美视频不卡中文| 中文字幕观看视频| 欧美成人免费网站| 日韩欧美在线观看一区二区| 影音先锋欧美精品| 2024最新电影在线免费观看| 国外成人在线直播| 欧亚av在线| 国产一区玩具在线观看| 91精品国产自产精品男人的天堂| 久久精品午夜一区二区福利| 日韩精品中文字幕第1页| 日韩精品免费一区| 另类图片国产| 成人在线短视频| 久久亚洲捆绑美女| 午夜精品福利在线视频| 精品国产精品自拍| 91女人18毛片水多国产| 亚洲第一男人av| 日本在线观看www| 97精品国产aⅴ7777| 精品国产黄a∨片高清在线| 国产高清自拍99| 久久社区一区| 亚洲中文字幕无码中文字| 精品中文字幕一区二区小辣椒| 国产性猛交96| 中文字幕一区二区三中文字幕| 国产手机在线视频| 777a∨成人精品桃花网| 黄色的视频在线免费观看| 色综合久综合久久综合久鬼88| 高清电影一区| 精品国产乱码久久久久软件 | 国产精品久久久久久久久久久久久久久久 | 国产精品免费久久久| 精品国产一区二区三区成人影院 | 在线播放日韩导航| 三级无遮挡在线观看| 欧美激情精品久久久久久大尺度| 日本免费成人| 日本免费高清不卡| 亚洲美女啪啪| 国产伦理在线观看| 中文字幕视频一区二区三区久| 你懂的国产在线| 亚洲国产高清福利视频| av网址在线免费观看| 国产精品麻豆va在线播放| 久操精品在线| 黄色免费观看视频网站| 成人v精品蜜桃久久一区| 欧美日韩精品亚洲精品| 欧美精品久久久久久久多人混战 | 国产午夜精品久久久久久免费视 | 国产日韩欧美三级| 潘金莲一级淫片aaaaa| 亚洲日本丝袜连裤袜办公室| 亚洲精品无码久久久久| 国产一区二区三区高清在线观看| 制服丝袜专区在线| 久久99精品国产99久久| 在线视频观看日韩| 欧美激情一区二区三区p站| 亚洲免费av网站| 国产精品无码专区av免费播放| 中文字幕精品在线视频| 成人mm视频在线观看| 日韩欧美手机在线| 日韩成人午夜精品| 国产三级av在线播放| 欧美性猛片xxxx免费看久爱| 成人免费一区二区三区视频网站| 国产精品久久97| 欧美一二区在线观看| 精品999在线| 中文字幕亚洲电影| 99久久精品免费看国产交换| 精品少妇一区二区30p| 深夜福利一区二区三区| 精品人妻大屁股白浆无码| 国产不卡视频在线观看| 国产在线观看免费视频今夜| 亚洲成人精品久久| 亚洲天堂免费电影| 视频一区二区三区免费观看| 美女一区二区久久| 99久久99久久精品国产| 日韩午夜在线观看| h片在线观看| 日韩精品第一页| 国产综合久久久久影院| 欧美成人精品欧美一级| 亚洲国产欧美自拍| 日韩高清成人| 欧美 亚洲 视频| 91香蕉国产在线观看软件| 亚洲永久精品一区| www.亚洲成人| av不卡一区二区| 已婚少妇美妙人妻系列| 国产精品成人午夜| 懂色av一区二区三区四区| 欧美一区二区三区精品电影| 欧美日韩色图| 涩视频在线观看| 欧美在线999| 日韩三级免费| 日韩av图片| 成人午夜免费av| 中文在线字幕av| 久久久久久噜噜噜久久久精品| 婷婷亚洲精品| 在线观看免费av网址| 亚洲图片欧美色图| 成人18在线| 国产精品区一区| 久久精品久久精品| 国产成人在线播放视频| 色噜噜狠狠狠综合曰曰曰| 91大神精品| 91丨九色丨蝌蚪| 一本大道久久精品懂色aⅴ| 爆操欧美美女| 色噜噜一区二区| 久久影院午夜论| 国产a级免费视频| 国产精品电影网站|