支持SaaS私有化部署

由于种种原因,SaaS应用程序就是需要在客户环境中私有化部署!!

那么如何让一套代码既支持云上的标准SaaS模式,又支持客户的私有部署模式呢?

本文将介绍如何这现这个需求。

首先请阅读以下二篇文档



准备配置参数

为了保证一套代码能同时支持SaaS和OP二种部署模式,且部署过程简单,请先设计好2个配置参数:

  • Default_Tenant_Id=xxxxxxxxxxxxxxxxxxx:默认租户ID
  • Default_Tenant_ConnName=tenant_db:默认的租户库连接名称



用户登录

租户的切换其实是根据用户登录身份来实现的,具体可参考IUserInfo的定义

public interface IUserInfo
{
    string TenantId { get; }
    string UserId { get; }

因此,可以按以下方式来实现:

  • 为这个客户分配一个明确的 【租户ID】,例如:TenantId=fc6e4bc7a3484304be1afb65b999938d
  • 私有部署环境中,给程序添加环境变量
docker run .....
  -e Default_Tenant_Id=fc6e4bc7a3484304be1afb65b999938d \
  ........
  • 定义静态变量保存这个默认租户ID
public static readonly string DefaultTenantId = LocalSetting.GetSetting("Default_Tenant_Id");
  • 应用程序的显示登录表单时,如果SaasOpTenantId有值,就不显示 "租户CODE" 这种输入控件
  • 用户登录时,设置 UserInfo.TenantId
WebUserInfo userinfo = new WebUserInfo{
    TenantId = DefaultTenantId // 从静态变量中取值
    UserId = "U0001",
    UserName = "张三",
    UserRole = "NormalUser"
}
AuthenticationManager.Login(userInfo, seconds);




Controller中获取租户Id

string tenantId = this.GetTenantId();



数据库操作

这块的代码实现与标准的SaaS没有任何区别,也是:

// Controller
using DbContext dbContext = this.CreateMasterConnection();
using DbContext dbContext = this.CreateAppDbConnection("logging");
using DbContext dbContext = this.CreateTenantConnection(tenantId);
using DbContext dbContext = this.CreateTenantConnection();

// MessageHandler, BackgroundTask
using DbContext dbContext = DbConnManager.CreateMaster();
using DbContext dbContext = DbConnManager.CreateAppDb("logging");
using DbContext dbContext = DbConnManager.CreateTenant(tenantId);

说明:

  • 如果在程序启动时设置了 EnableConfigService=false,租户库的连接名称将是 Default_Tenant_ConnName 参数指定的名称,不再按SaaS的规则去做映射查找。
  • 主库的连接名称依然是 master
  • 应用库根据使用情况来配置

数据库连接配置如下:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <appSettings>        

     </appSettings>

    <connectionStrings>
        <add name="master" providerName="System.Data.SqlClient"
			 connectionString="server=MsSqlHost;database=master;uid=user1;pwd=xxxx"/>

        <add name="logging" providerName="MySql.Data.MySqlClient"
			 connectionString="server=MySqlHost;database=logging;uid=user1;pwd=xxxx"/>

        <add name="tenant_db" providerName="System.Data.SqlClient"
			 connectionString="server=MsSqlHost;database=tenant_db;uid=user1;pwd=xxxx"/>

    </connectionStrings>
</configuration>




以【单体应用】方式运行

如果私有化部署时希望采用单体应用的方式运行,可以参考下面二篇文档:

最后可以实现的效果是:

  • 一套代码支持 SaaS 和 OP 二种部署模式
  • 一套代码支持微服务开发架构 和 单体应用程序架构




部署过程

与云端的部署方式一样,部署所有服务及数据库。

唯独:租户总表只有一条记录。