摘要:解读云上前沿技术,畅聊开发应用实践。专家团队授课,答疑解惑,助力开发者使用华为云开放能力进行应用构建、技术创新。
围绕当下许多企业青睐的SaaS应用开发,华为云DTSE技术布道师李良龙为大家带来《SaaS应用开发》系列课程第3期《SaaS数据路由设计实现》的分享。
成都创新互联公司长期为上千客户提供的网站建设服务,团队从业经验10年,关注不同地域、不同群体,并针对不同对象提供差异化的产品和服务;打造开放共赢平台,与合作伙伴共同营造健康的互联网生态环境。为前锋企业提供专业的网站设计制作、网站制作,前锋网站改版等技术服务。拥有10多年丰富建站经验和众多成功案例,为您定制开发。
一个合格的SaaS应用开发必定伴随着租户数据的隔离,同时租户的开销及成本预算各不相同。随着业务规模的变化,我们该如何选择租户数据隔离的方式,如何实现隔离?相信在这期直播里,你可以找到解答。
在第一期的《SaaS云原生应用典型架构》技术分享中,我们了解到SaaS多租户模式,帮助企业选择合适的SaaS系统匹配企业的客户和业务特点。如:独享资源模式、全共享模式、数据层共享模式等。此时,我们往往会遇到不同租户间的数据隔离问题,如何正确的进行数据路由,才能保证租户的数据隔离。
在SaaS应用开发时应用层和数据层的租户路由设计以及实现方面,我们会遇到几种情况:
并且,不同的资源共享模式、共享程度,在同样资源的情况下所容纳的租户数量不一样,所以每一个租户平均成本不一样,最终的总TCO成本也会不一样。所以往往使用这种混合模式,需要根据租户的需求和预算进行不同程度的资源共享,以达到在保证租户业务正常稳定运行的前提下,成本最小化,收益最大化的目的。
上图中租户1使用独立的应用层和数据层,不涉及资源共享,所以无需要考虑数据路由。图中的租户2-7,都涉及到了资源共享。其中租户3和租户4共享数据库实例,但是占用不同schema;租户5和租户6共享数据库实例,但不使用schema隔离,在业务表中使用租户标识隔离。共享应用层和数据库实例时,在处理业务逻辑过程中需要将租户的数据库相关操作指向正确的目标库,避免数据污染等一系列问题,此时即需要进行路由。
当租户进行数据操作时,可能涉及到关系型数据库的读写,nosql,缓存,消息队列,服务之间的调用等等场景,在这一条完整的链路中,数据的操作需要识别租户的身份,实际上是说租户的业务数据以及个性化配置是需要先识别租户身份的,否则会引起租户之间的数据污染,越权等等问题。
我们需要通过一些方式来识别租户,并且要在整个业务链路中传递,直到不需要区分租户为止,比如请求结束。那么路由到底承担了什么角色,实际上起了什么作用呢。租户路由不仅仅是要实现对租户的数据进行正确的路由,而且是建立在一个可信的规则上的,可维护的,可统一管理的,而且可追溯。可以由一个超级管理员的角色来对租户的资源进行分配并持久化,并能够按照这些持久化的配置来作为租户数据路由的依据。
综上所述,SaaS应用之所以需要租户路由,是多个租户在一定程度上资源共享所导致。按共享程度有一个简单的模型,随着共享程度的升高,同样资源可以容纳的租户数量会越来越多,那么每一个租户所需要的成本就越低。随着共享程度越高,就会导致针对租户的运维难度增大。比如某一共享环境下租户的数据需要回滚,要在不影响其他租户的前提下完成,相比于独享环境的租户会复杂很多。
随着共享程度越高,租户之间的隔离程度就会越低。比如租户数据使用行隔离时,不同租户的数据放在同一个表中,租户之间的数据最容易相互影响,这种模式可容纳的租户数量也是最多的。第二个是总拥有成本会随着租户的共享程度升高而降低,租户的平均成本也随之降低,这也是多租环境下,使用资源共享的一个比较重要的原因。
上面介绍了为什么使用租户路由来隔离租户的数据,接下来为大家介绍一下租户路由插件的设计思路。租户路由插件大体可以分为动态数据源和数据路由策略两个部分,今天重点介绍动态数据源。
上图为动态数据源业务流程图。动态数据源在配置方面使用yml配置,一个数据源可以被称为一个数据源组,一个组包含一主多从。数据源配置可以将租户与数据源的绑定关系分开配置,这样可以灵活的绑定实现租户与数据源的关系。松散配置方面,多个租户可以绑定同一个数据源组,可细化绑定关系到schema,而且绑定关系与数据源组配置的修改不相互影响。同时一个数据源组实际上是一组实例的多个连接池组成的,而且数据源组在满足配置的情况下可以通过配置中心动态配置。
比如可以在不停机的情况下新增租户,并将新增租户绑定到已经存在的数据源中;也可以新增数据源配置,将租户指定到新增的数据源,通过数据库管理工具如flyway,为租户初始化数据库资源,预置一些管理账号、基础配置等等。同时这个功能可以在租户绑定的资源改变的时候使用,比如某个租户随着业务的增长,需要从共享库迁移到独享库等等场景。在配置的基础上构建了动态数据源之后,业务访问的过程中通过绑定关系以及自定义扩展策略来选择数据源,选择schema,最后获取数据库连接,操作数据,比如读写分离,比如负载均衡,租户与数据源的绑定策略的扩展实现等等。
在配置结构中,支持自定义扩展连接池,而且连接池的配置属性可以支持粒度细化到单个实例的,相同属性细粒度的配置会覆盖粗粒度的配置。
在租户标识传递方面,目前默认的是将租户标识放在header中,在接收到请求之后将header中的租户标识放入缓存中,这个可以看作是一个会话级别的缓存。仅需要在父线程中初始化并设置值,子线程也可以获取到,并且需要在请求结束时清理掉,防止线程池中线程复用导致数据污染。
租户与数据源以及schema的绑定关系除了使用配置文件配置之外,还可以使用开放的扩展接口自行扩展绑定逻辑。看到这里,有小伙伴会问,设计的路由插件为什么没有关于行隔离的内容。
行隔离,是指通过在业务表中添加可以标识租户身份的字段,用于数据隔离,但并不代表所有的业务表都需要添加这个字段。每一条业务数据都可以理解为是在基础数据之上创建的,不是凭空出现的,只需要做到在业务表中可以传递租户身份标识即可。
比如一个项目管理系统,根组织可以是SaaS的拥有者,也可以没有这个根组织,不同的团队可以理解成不同的租户。在团队之下新建部门,部门之下新建项目,项目之下关联项目组的成员,以及项目的一些详细信息。在部门这一层,租户标识实际上是团队,在项目这一层的租户标识实际上是部门,成员这一级的标识实际上是项目组,成员详细信息的标识实际上的成员ID,这样也可以理解为租户标识的传递,但是不需要额外的在每个表中去维护这些标识信息。这些标识可以本来就是业务中天然携带的,更是侵入性的,所以正常的业务不用也没必要单独去考虑行隔离的实现。不推荐在业务处理过程中进行切换数据源。
他表示:
以微服务的设计来讲,排除需要分库分表的业务,如果在一个服务里面需要通过连接不同的业务库来实现访问不同业务的数据,这种方式是不合适的。应当基于微服务的设计思想,不同的业务模块需要有不同的服务来管理。跨业务模块操作数据时,需要通过服务调用、消息通知等方式操作,不应该越权去处理其他业务模块的数据。虽然通过配置可以实现这个功能,但是正常的业务场景是不推荐这么使用的。
谈及数据路由插件在未来的演进方向时,现在插件是以SDK的方式提供,有其局限性,如不能跨语言。正在规划中的sidecar版本的路由插件将会解决跨语言的问题,能够完整的把SaaS应用的租户路由管理起来。同时sidecar版本还带能来一些新的能力,例如资源分配策略、路由策略、可视化,统一的资源管理分配等等。
插件具有侵入性小,改造代价小,配置简单灵活的特点,租户规模不是很大时可以考虑使用路由插件,当租户上一定规模之后,需要有完整的管理体系来管理租户与数据源的关系。
使用插件时,只需要引入插件,然后将配置维护到插件指定的路径下面,然后开启插件的开关即可。如果有更高多的要求,可以实现我们的一些配置策略,包括数据源的动态重建等等。另外一种是sidecar模式的路由解决方案,适用于租户数量比较多时使用,sidecar版本可以跨语言,更便捷的解决租户数据路由的问题。
下节课,我们邀请到了派拉软件研发总监、CZTP零信任专家茆正华和华为云DTSE技术布道师程泽,为大家带来《SaaS应用开发》系列课程第4期《身份应用云上技术架构实践》的分享。深入介绍云原生架构下的身份管理平台,为企业、机构、开发者构建云安全数字身份入口,赋能用户全场景下的数字身份治理与链接服务。8月25日,我们不见不散。
应用开发文档:https://support.developer.huaweicloud.com/doc/zh-cn_topic_000000-000000
参考示例代码:https://gitee.com/HuaweiCloudDeveloper
问题咨询和专家服务预约(需注册华为云账号):https://support.developer.huaweicloud.com/feedback/?ticket=ST--mPu9vjwIeAGISrz1rXBAdwt7-sso
点击关注,第一时间了解华为云新鲜技术~