# saas-housekeeper **Repository Path**: tomdev/saas-housekeeper ## Basic Information - **Project Name**: saas-housekeeper - **Description**: SaaS+微服务:本项目是华为云开发者团队基于SaaS项目技术支持实践,采用微服务架构(SpringCloud),结合华为云服务能力开发的SaaS化开源项目,旨在为企业级开发者提供云原生SaaS应用构建的技术参考,包括微服务架构、多租隔离设计、多租户路由、数据存储多租设计等。更多SaaS相关技术细节可参考:华为云开发者文档中心SaaS应用开发指导。 - **Primary Language**: Java - **License**: Apache-2.0 - **Default Branch**: master-dev - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 156 - **Created**: 2023-04-17 - **Last Updated**: 2023-04-17 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README [TOC] **项目介绍** =============== 本项目是华为云开发者团队基于SaaS项目技术支持实践,采用微服务架构,结合华为云服务能力开发的SaaS化开源项目,旨在为企业级开发者提供云原生SaaS应用构建的技术参考,包括微服务架构、多租隔离设计、多租户路由、数据存储多租设计等。更多SaaS相关技术细节可参考:[SaaS应用开发](https://support.developer.huaweicloud.com/doc/development/ApplicationScenarioDevelopmentInCloud-guides/zh-cn_topic_0000001271256348-0000001271256348)。 本项目提供服务型SaaS服务,提供家政服务的接入,家政公司或个人家政服务者可通过此SaaS平台发布自己的服务为用户提供家政服务,此SaaS系统在用户入口上是彼此独立的,用户场景类比小程序独立商户。项目主要演示租户的申请,租户的建立,租户的定制,SaaS管理者的运营操作。项目最终目的是打造SaaS系统脚手架,提供具体业务之外的SaaS基础架构,包括运营、运维,CICD的能力,为SaaS开发者提供可复用的素材。 ![saas-housekeeper.PNG](img/jdk-1.8-brightgreen.svg) ![saas-housekeeper.PNG](img/maven-3.6.3-red.svg) **架构图** --------------- #### 活动图 ![saas-housekeeper.PNG](img/business-diagram-cn.png) #### 技术架构图 ![saas-housekeeper.PNG](img/technical-diagram-cn.png) **逻辑组件** ![housekeeper逻辑视图](img/housekeeper逻辑视图.png) **项目演示** --------------- - 访问地址 | 名称 | 地址 | 账号 | | ------------ | ------------ | ------------ | | 租户注册 | [http://saas-housekeeper.cloudbu.cloud-onlinelab.cn/tenant/#/register](http://saas-housekeeper.cloudbu.cloud-onlinelab.cn/tenant/#/register) | 无需账号 | |超级管理中心 | [http://saas-housekeeper.cloudbu.cloud-onlinelab.cn/super-admin/#/login](http://saas-housekeeper.cloudbu.cloud-onlinelab.cn/super-admin/#/login) | 账号: Admin
密码: AF5 密码: lhKk101@mm. | | 用户管理中心 | [http://sample1.saas-housekeeper.cloudbu.cloud-onlinelab.cn/customer/#/login](#) | 注册获得 | | 雇员管理中心 | [http://sample1.saas-housekeeper.cloudbu.cloud-onlinelab.cn/worker/#/login](#) | 注册获得 | NOTE: 五级域名*“sample1”*为租户定义,可替换为租户自己申请的域名,注册域名时请注意五级域名不包含“.” 。不能注册为“sample1.com” - 体验流程 步骤一:潜在租户(企业)通过访问租户管理中心-租户注册([http://saas-housekeeper.cloudbu.cloud-onlinelab.cn/tenant/#/register),进行租户注册操作](http://saas-housekeeper.cloudbu.cloud-onlinelab.cn/tenant/#/register) 步骤二:SaaS管理员账号可通过访问租户管理中心([http://saas-housekeeper.cloudbu.cloud-onlinelab.cn/super-admin/#/login](https://gitee.com/link?target=http%3A%2F%2Fsaas-housekeeper.cloudbu.cloud-onlinelab.cn%2Fsuper-admin%2F%23%2Flogin)) 对提交的租户注册请求进行审批 ps:租户域名为租户注册时填写的栏目,为后续租户、用户、雇员中心网站分配动态url 步骤三:注册审批通过的租户可通过访问发布中心 http://(你注册的租户域名).saas-housekeeper.cloudbu.cloud-onlinelab.cn/tenant/#/login 定制企业服务 步骤四:雇员角色通过任务中心注册称为企业员工 http://(你注册的租户域名).saas-housekeeper.cloudbu.cloud-onlinelab.cn/worker/#/login 接取最终用户的订单 步骤五:用户角色注册访问用户前端 http://(你注册的租户域名).saas-housekeeper.cloudbu.cloud-onlinelab.cn/customer/#/login 对租户提供的定制服务进行购买下单 步骤六:雇员可以通过访问雇员管理中心 http://(你注册的租户域名).saas-housekeeper.cloudbu.cloud-onlinelab.cn/worker/#/login 接取最终用户的订单 - 租户注册,管理员审批 ![saas-housekeeper.PNG](img/租户注册审批.gif) - 租户新建服务 ![saas-housekeeper.PNG](img/租户新建服务.gif) - 用户下单 ![saas-housekeeper.PNG](img/用户下单.gif) - 雇员接单 ![saas-housekeeper.PNG](img/雇员接单.gif) **组织结构** --------------- ``` lua saas-housekeeper ├── saas-housekeeper-common -- 公共类 ├── saas-housekeeper-config-server -- 配置中心 ├── saas-housekeeper-eureka -- 注册中心 ├── saas-housekeeper-gateway -- 网关中心 ├── saas-housekeeper-message-service -- 消息中心 ├── saas-housekeeper-order-service -- 订单中心 ├── saas-housekeeper-publish-service -- 服务发布中心 ├── saas-housekeeper-web-customer -- 用户管理中心 ├── saas-housekeeper-web-super-admin -- 超级管理员管理中心 ├── saas-housekeeper-web-tenant -- 租户管理中心 ├── saas-housekeeper-web-worker -- 任务管理中心 └── saas-housekeeper-config -- 配置文件 ``` **技术选型** --------------- | 技术 | 说明 | 官网 | | -------------------- | -------------------| -------------------------------------------- | | Spring-Cloud | 微服务框架 | https://spring.io/projects/spring-cloud | | SpringBoot | 容器+MVC框架 | https://spring.io/projects/spring-boot | | Eureka | 注册中心 | https://github.com/xmartlabs/Eureka | | SpringSecurity | 认证和授权框架 | https://spring.io/projects/spring-security | | MyBatis-plus | ORM框架 | https://baomidou.com/ | | K8S | 华为云应用容器引擎CCE | https://support.huaweicloud.com/cce/index.html | | Mysql | 云数据库RDS | https://support.huaweicloud.com/rds/index.html | | Redis | 分布式缓存DCS服务 | https://support.huaweicloud.com/intl/zh-cn/dcs/index.html | | RabbitMQ | 分布式消息队列 DMS | https://support.huaweicloud.com/intl/zh-cn/rabbitmq/index.html | | flyway | 数据迁移工具 | https://flywaydb.org/ | | saas-tenant-router-starter| 多租户路由中间件| https://gitee.com/HuaweiCloudDeveloper/saas-tenant-router-starter.git | | JWT | JWT登录支持 | https://github.com/jwtk/jjwt | | Lombok | 简化对象封装工具 | https://github.com/rzwitserloot/lombok | | Swagger-UI | 文档生成工具 | https://github.com/swagger-api/swagger-ui | **项目启动** --------------- 运行此项目你需要安装Docker,如何将Docker安装在[Ubuntu](https://docs.docker.com/engine/install/ubuntu/)、 [Windows](https://docs.docker.com/desktop/install/windows-install/)、[Mac](https://docs.docker.com/desktop/install/mac-install/)。 1 windows环境执行start.bat文件,Linux,Mac环境执行start.sh文件,将host地址 127.0.0.1 映射为 sample.housekeeper.local.huawei.com. 实现租户路由。 2 项目根目录执行下列命令打包后端模块 > mvn clean install -DskipTests 3 然后用docker compose 运行整个项目 > docker compose up ps: 本项目是通过访问域名的前缀来实现租户路由的。在本地运行只能模拟域名,将127.0.0.1映射为sample.housekeeper.local.huawei.com(租户标识为前缀). 其中租户标识为sample。 | 名称 | 地址| 账号 | |--------|-----|------| | 超级管理中心 | [http://sample.housekeeper.local.huawei.com/#/super-admin/login](http://sample.housekeeper.local.huawei.com/#/super-admin/login)| 账号: Admin
密码: AF5 密码: lhKk101@mm. | | 用户管理中心 | [http://sample.housekeeper.local.huawei.com/#/customer/login](http://sample.housekeeper.local.huawei.com/#/customer/login) | 账号: customer
密码: 123456 | | 雇员管理中心 | [http://sample.housekeeper.local.huawei.com/#/worker/login](http://sample.housekeeper.local.huawei.com/#/worker/login) | 账号: worker
密码: 123456 | # 项目设计说明 #### Schema数据隔离设计 我们在SaaS应用开发指南里提到数据隔离的三种方案,在本项目中我们采用了Schema数据隔离方案,我们选择这个方案的原因无关业务,主要是为了展示Schema数据隔离的技术手段。关于这几种数据隔离方案的特性和应用场景可以参考SaaS应用开发指南 Schema数据隔离的实现依赖了我们的开源插件,我们只需要在网关处把租户标识放到请求头“tenentDomain”中(此过程可称为流量染色),通过路由插件的schema切换功能,租户的访问就可以路由到数据库相应的schema。 具体参考[租户路由插件](https://gitee.com/HuaweiCloudDeveloper/saas-tenant-router-starter) ![Figure Name:unnaming.png CAD Name:zh-cn_image_0000001443530661.png](img/zh-cn_image_0000001443530661.png) #### 租户申请 本项目可分为两个子系统,一个是SaaS管理系统,一个是housekeeper应用系统,租户申请是通过SaaS管理系统来完成的, - 租户通过邮件申请流程 ![housekeeper邮箱验证顺序图](img/housekeeper%E9%82%AE%E7%AE%B1%E9%AA%8C%E8%AF%81%E9%A1%BA%E5%BA%8F%E5%9B%BE.png) 1. 潜在租户打开租户申请界面输入邮箱名 2. 后台收到邮箱名后生成验证码并以验证码为key存放邮箱名到缓存 3. 拼接验证码和邮箱名到一个租户注册的前端连接,发送该连接到潜在租户邮箱 4. 潜在租户点击连接携带验证码和邮箱名到该前端,输入注册信息后提交到后台。 5. 后台根据验证码找到缓存中的邮箱名与刚提交的邮箱名作对比,验证一直则把潜在租户信息保存到后台待审核。 *此设计的目的是通过邮件坐标对潜在租户的访问进行审计以及信息的初步验证* #### Schema数据隔离设计的租户创建 数据空间 租户路由表 - 数据空间的创建需要新建schema以及同步数据表。 本项目的数据空间创建借助了flyway插件做管理。flyway保存了创建数据空间的sql语句,执行后会在新的schema下建表,插入预置数据。参考:[flyway官网](https://flywaydb.org/) - 租户路由表需要记录租户标识、租户domain、数据库名和schema名等信息, 在本项目的Spring Cloud 版本中我们使用了Spring Cloud Config作为配置管理,使用jdbc方式动态配置表,使用消息Bus作数据同步,实现租户路由表动态更新。 ![新建租户活动图](img/新建租户活动图.png) #### SaaS用户系统与权限设计 - 用户系统 SaaS管理系统和业务系统的使用对象并不重叠,很多企业级的SaaS管理系统一般是在内网使用,所以两个系统并不使用同一套用户系统,SaaS管理系统使用者通常只会有一两个人,所以直接放在配置里。 本项目业务系统的用户系统与其他业务子系统一样,使用了Schema数据隔离,每个租户下的员工与用户都是独立的,并不能使用一个账号登录其他租户的系统。 用户系统是否独立与业务性质相关,如果系统只是企业级应用,使用独立的用户系统比较方便。如果系统涉及C端市场,用户资源可以设为租户通用,促进最终用户在租户间的共享,免去用户重复注册登录的麻烦。 ![zh-cn_image_0000001393011770](img/zh-cn_image_0000001393011770.png) - 角色 此套系统中,业务系统包括3个角色,商家(租户)、雇员(租户内部员工)、消费者(最终用户)。 本系统RBAC设计非常简单,每个用户只属于一个角色,接口以角色的维度对访问进行控制。 本项目中,租户角色的授予是SaaS管理员审批的,随着租户创建生成。用户和员工的角色在此系统中没有人工审批流程,只是在员工注册中加了身份证检测,真实应用中员工的注册一般需要通过系统审核和人工审核,然后才能把员工角色赋予该账号。 - 权限 页面权限:本业务系统中有三个前端应用,角色对应该前端的登录权限,租户可以登陆租户前端、雇员前端和用户前端,雇员可以登陆雇员前端和用户前端,用户只能登录用户前端。 操作权限:在每个后台接口中都会对不同角色的操作权限做判断,例如参观者角色只可以浏览界面,而不能做业务操作 数据权限:每个租户下的用户只能看到本租户应用下的数据。 #### 租户可配置设计 在家政项目中,A租户想做清洁服务,B租户想做月子服务,服务的内容和规格和收费计量都不一样,怎么把这些内容让租户自己定义呢?这些表的设计就是把服务的定义,规格的定义,选项的定义,各种组合的价格都变成客户可自配置的内容。 关注SaaS的观众大概了解过元数据驱动多租架构,本质上就是让用户去创建虚拟的数据表来定制自己的业务,例如业务表的字段属性、关联关系、索引都是客户可配置的,目前这种设计更多用在PaaS项目中,SaaS项目可以依赖这种基础能力去开拓自己的产品,但SaaS产品完全按照元数据驱动的设计去开发比较复杂也非必要,在具体的SaaS产品设计上可以根据业务的维度来定义业务元数据。本项目把家政业务的元数据定义交给租户。 ![zh-cn_image_0000001443690641](img/zh-cn_image_0000001443690641.png) #### SaaS系统可观测设计 本项目在上线的时候采用了华为云的AOM与APM作为线上运维部署,在AOM配置了探针后,我们在日志的配置中把“apm-traceid”配置上就可以打印出链路追踪的信息,使链路追踪与日志关联,达到立体化运维的效果。 我们的路由插件会把租户的标识放到日志的tanantId中,可以通过日志查询到请求对应的租户。 本项目日志收集的标准格式,可打印出traceId 和 tanentId ,对租户的使用进行分析: ` %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level traceId:[%X{apm-traceid}tenantId:[%X{tenantId}]userId[%X{userId}] %logger{50} : %msg%n ` **相关参考** --------------- - 华为云开发者中心SaaS应用开发指导 - [Istio版本](https://gitee.com/HuaweiCloudDeveloper/huaweicloud-istio-k8s-saas-housekeeper) - [多租路由中间件开源项目](https://gitee.com/HuaweiCloudDeveloper/saas-housekeeper/blob/master-dev/saas-housekeeper-tenant-router-starter/README.md)