【云驻共创】DTT技术直播 NO.2:《SaaS应用开发》系列之SaaS应用技术架构设计
上期文章:《DTT技术直播系列 NO.1 SaaS云原生应用典型架构》
https://bbs.huaweicloud.cn/blogs/367087
本章:DTT技术直播 NO.2:《SaaS应用开发》系列之SaaS应用技术架构设计
一、如何做好SaaS技术栈转型?通常会考虑哪些因素?
- “按需引入"。按照SaaS应用建设的不同需求阶段,进行技术栈能力引入。
- “可驾驭”。尽可能选择团队熟悉、成熟技术栈,出了问题是否有强有力社区支持。
- “适当超前”。技术栈容量选择能够满足未来1 ~2年业务需求即可;采用可扩展的架构,实现后期的扩容。
- “性价比”。技术栈考虑实施的性价比,如部署、维护成本等。
选择云原生能:容器化、微服务化、基于云化应用中间件、数据库构建应用。
引用技术栈:微服务引擎CSE、SpringBoot/Spring-Cloud/K8S、MySQL、Redis、RabbiMQ、LTS等技术内容。
二、云上微服务开发CSE和应用部署的云容器引擎CCE有哪些优势?
1、如何实现与CSE对接?
例如:maven引入
<!-- 微服务 -->
<dependency>
<groupId>com.huaweicloud</groupId>
<artifactId>spring-cloud-starter-huawei-service-engine</artifactId>
</dependency>
<!-- SpringCloud gateway -->
<dependency>
<groupId>com.huaweicloud</groupId>
<artifactId>spring-cloud-starter-huawei-service-engine-gateway</artifactId>
</dependency>
对应的价值:
2、为什么要选择CCE?如何实现应用的灵活部署?
核心需求
- 节约成本,提升应用发布速度,并且安全可控
- 提升对业务波动的响应能力、性能提升。
CCE方案价值
提高资源利用率(成本优化)
- 榨干资源价值(虚机规格固定,容器规格灵活)
- 秒级弹性伸缩(虚机分钟级弹性,容器秒级弹性)
- 根据部分企业案例, 在总体业务增长20%的情况下,综合节省成本可达到30%
提高运维效率(节省人力)
- 自动化(CI/CD, 自动弹性伸缩)
- 上线/升级时间,从小时级变成分钟级
三、在多租户模式下,如何设计路由策略,实现应用层、数据层的路由?
1、基于CCE实现的应用层多租模式
网络隔离,CCE基于Kubernetes的网络策略功能进行了加强,通过配置网络策略,允许在同个集群内实现网络的隔离,也就是可以在某些实例(Pod)之间架起防火墙。在华为云上提供了vpc网络和容器隧道网络,仅“容器隧道网络”模式的集群支持网络隔离。
资源配额限制,通过设置命名空间级别的资源配额,实现多租户在共享集群资源的情况下限制团队、租户可以使用的资源总量,包括限制命名空间下创建某一类型对象的数量以及对象消耗计算资源(CPU、 内存)的总量。
QoS限速:由于不同租户资源可能部署在同一节点上,导致不同业务容器之间存在带宽抢占的情况,容易造成业务抖动。为了解决这个问题,您可以通过对Pod间互访进行QoS限速来解决这个问题当然,也可以通过亲和性策略,将不同租户的pod调度到不同节点上,避免网络资源抢占。
2、基于RDS实现的数据层多租模式
主要特征:
①所有租户数据保存在共享数据库的共享表中,通过租户标识区分租户记录。
②每个租户访问相同的数据库和表,通过应用层数据访问控制保证数据的安全访问/隔离。
优点:最低的资源成本、最大限度的使用DB资源;DB的维护管理成本降低;
缺点:共享数据库,共享Schema无法保证Schema扩展互相透明,增加了扩展的复杂度;数据隔离在应用层实现,隔离性较弱;租户的数据的备份恢复只能按记录操作。
主要特征:
①每个租户的数据保存在自己的表中,但共享同一个物理数据库。
②每个租户连接相同的数据库(相同的连接配置);但访问不同的表(Schema设置)。
优点:租户间有较弱的关系、影响较小(仍然可以轻松扩展、通过DBUser保证数据安全和隔离;降低资源和数据库维护成本)。
缺点:不同租户访问相同的数据库,租户间的访问性能相互影响;数据备份恢复相互干扰;单DB租户数量受限。
主要特征:
①每个租户的数据保存在一个物理上独立的数据库实例中(RDS)。
②每个租户连接自己特定的数据库。
优点:租户间完全没有影响(轻松扩展、数据备份恢复简单、数据安全的隔离) 。
缺点:更高的资源成本和数据库的维护管理成本。
3、租户应用访问路由策略?
- 不同租户分配到不同的域名,用不同租户域名实现租户区分,通过域名映射,路由到不同租户应用。
- 采用统一域名,通过不同请求参数,如增加租户字段,进行租户区分,将租户请求路由到后端应用。
4、租户应用与数据访问路由策略是怎样的?
- 租户标识可以是域名也可以是租户id或者appid等,租户标识进入网关时需要做安全认证,以免横向夺权。
- 租户标识从访问入口起就要一-路携带, 直到租户隔离区域的终点,例如独享资源模式最简单,进入网关就可以去掉标识,如果是数据库隔离的,进入数据库就可以去掉标识,如果数据库共享根据字段隔离,标识就要放到record中。
- 根据租户标识,服务把租户请求路由到不同的链路中,华为云开源的租户插件saas-tenant-router-starter可以帮助我们在服务中对租户请求进行路由。
四、以SaaS-housekeeper实践为例,如何实现多租上下文的传递、租户配置热更新?
1、请求上下文中携带租户标识
- 以Java为例,本质上是把租户上下文放在每个请求的维度。
- 传统的Javaweb项目,可直接通过RequestContextHolder获取租户标识,这个类使用了ThreadLocal作为线程隔离。
- 使用多线程的项目,例如reactor或项目中使用了hystrix线程池隔离模式,threadlocal变量会在线程传中丢失,此类情况可选择与作用范围对应的容器,例如可使用HystrixRequestValuableDefault作为标识的存储容器,自主代码也可依赖其线程池创建的方式来传递租户标识以及租户相关信息。
- SaaSHousekeeper项目以域名作为租户标识,TENENT_DOMAIN是请求的域名,每个请求到达服务时,过滤器会拦截请求,然后把租户标识存放到HystrixRequestValuableDefault中,如果非用户请求,也需要把租户标识初始化。
2、如何实现租户路由标识传递?
在实现租户标识传递时,可能会遇到不同场景,如跨微服务调用以及MQ、ES访问等,需要采用合理的策略传递租户标识。
情形一: Open Feign调用其他微服务时带上租户标识。
情形二:使用MQ时,在消息头中传递租户标识。
3、数据请求时,如何根据租户标识选择数据库?
在进行数据请求时,拦截器拦截数据请求,从请求上下文中获取租户标识,根据标识从映射表中获取该租户绑定的数据源以及schema,然后设置请求连接。
第一步:获取绑定的数据源组
第二步:获取schema
代码来源:saas-tenant-router-starte
4、如何实现数据库内容版本控制管理?
如果使用数据库或schema隔离的方案,在增加新租户的时候,系统必须为新租户建立新的数据库,而当数据库版本更新,系统也必须为每个租户的数据库更新数据,必须借助一些工具来降低运维复杂度, 在SaaSHousekeeper项目中,我们采用了flyway作为数据版本的管理工具,为租户创建新数据库、插入基础数据,维护数据库版本的更新。
Flyway.configure().dataSource(url, username, password).schemas(schema).load().migrate();
注意:在真实的生产环境,有关数据库的权限要注意访问安全,比如从堡垒机访问相关权限的系统。
5、如何实现系统功能订制策略?
在SaaS-housekeeper项目中,A租户想做清洁服务,B租户想做月子服务,服务的内容和规格和收费计量都不- -样,怎么把这些内容让租户自己定义呢?这些表的设计就是把服务的定义,规格的定义,选项的定义,各种组合的价格都变成租户可自配置的内容。
说明:
关心SaaS的观众大概了解过元数据驱动多租架构,本质上就是让用户去创建虚拟的数据表来定制自己的业务,业务表的字段属性、关联关系。索引都是用户可定义的,根据元数据的定义可以完成业务的建模,仅仅需要更新数据就能实现用户不同的业务,不需要升级程序。这就大大减轻了开发运营的压力。
但SaaS项目不一定需要完全套用元数据驱动开发的模型,完全的元数据驱动开发难度大,太细粒度的订制对开发或租户也是压力。实际的项目可以根据具体业务的维度对元数据进行降维设计,找到业务元数据,让租户恰好能完成业务的定制。
SaaSHousekeeper项目在服务发布的设计上,就是把家政业务场景的元数据定义交给租户,根据租户需求配置。
6、如何实现前端页面可配置性?
不同的租户希望自己的应用展示企业或个人的风格,除了app定制,小程序定制或web模板定制外,也可以在同-个web前端配置不同的展示风格,SaaS-housekeeper项目的SaaS应用前端可在用户根据域名登陆时获取对应租户的设定来配置风格主题。
总结:
- 对于基础技术组件,如K8S、数据库、MQ等,为保证可靠性和运维的便捷,可以优先考虑云服务。
- 云容器引擎CCE提供多种隔离模式,如pod, namespace、cluster, 可根据使用场景对隔离性和性能要求,进行灵活选取。
- 在进行租户上下文传递时,在java环境下,可考虑将HystrixRequestValuableDefault作为标识的存储容器。
- 在多租环境下,数据层采用不同隔离策略(数据库实例、schema、 行)情况下,管理数据源是复杂的,可采用多租户路由插件管理数据源。
《SaaS应用开发》系列课程预告
下期内容:SaaS数据路由设计实现
代码:https://gitee.com/HuaweiCloudDeveloper
文档:https://support.developer.huaweicloud.cn
本文参与华为云社区【内容共创】活动第19期。
https://bbs.huaweicloud.cn/blogs/370132
任务15 DTT技术直播 NO.2:1小时深度解读SaaS应用系统设计
- 点赞
- 收藏
- 关注作者
评论(0)