摘要:解读云上前沿技术,畅聊开发应用实践。专家团队授课,答疑解惑,助力开发者使用华为云开放能力进行应用构建、技术创新。

围绕当下许多企业青睐的SaaS应用开发,华为云DTSE技术布道师李良龙为大家带来《SaaS应用开发》系列课程第3期《SaaS数据路由设计实现》的分享。

本期直播详解

一个合格的SaaS应用开发必定伴随着租户数据的隔离,同时租户的开销及成本预算各不相同。随着业务规模的变化,我们该如何选择租户数据隔离的方式,如何实现隔离?相信在这期直播里,你可以找到解答。

从7个租户模式了解数据路由的使用

在第一期的《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_0000001321416345-0000001321416345

参考示例代码:https://gitee.com/HuaweiCloudDeveloper

问题咨询和专家服务预约(需注册华为云账号):https://support.developer.huaweicloud.com/feedback/?ticket=ST-5385866-mPu9vjwIeAGISrz1rXBAdwt7-sso

点击关注,第一时间了解华为云新鲜技术~

DTSE Tech Talk丨第3期:解密数据隔离方案,让SaaS应用开发更轻松的更多相关文章

  1. PHP通过OpenSSL生成证书、密钥并且加密解密数据,以及公钥,私钥和数字签名的理解

    一.公钥加密假设一下,我找了两个数字,一个是1,一个是2.我喜欢2这个数字,就保留起来,不告诉你们(私钥),然后我告诉大家,1是我的公钥. 我有一个文件,不能让别人看,我就用1加密了.别人找到了这个文 ...

  2. java RSA实现私钥签名、公钥验签、私钥加密数据、公钥解密数据

    通过OpenSSL生成公私钥文件(如果没有OpenSSL工具建议下载Cmder工具自带OpenSSL指令) 1.生成RSA密钥的方法 genrsa -out private-rsa.key 2048 ...

  3. 微信 unionid 获取 解密数据

    1.申请注册微信开放平台  open.weixin.qq.com 2.绑定公众号或者小程序到微信开放平台 3.微信公众号的话,使用微信网页授权获取 unionid https://mp.weixin. ...

  4. 使用Mybatis的TypeHandler加解密数据

    使用Mybatis的TypeHandler加解密数据 一.背景 二.解决方案 三.需求 四.实现思路 1.编写一个实体类,凡是此实体类的数据都表示需要加解密的 2.编写一个加解密的`TypeHandl ...

  5. DTSE Tech Talk | 第9期:EiPaaS驱动企业数字化转型

    摘要: 揭秘华为企业集成新模式. 本期直播详解 组装式概念解析 EiPaaS的核心技术能力 华为实践经验分享 EiPaaS未来的技术趋势 直播讲师:华为云PaaS DTSE布道师 傅翌伟 tips:E ...

  6. DTSE Tech Talk | 第10期:云会议带你入门音视频世界

    摘要:本期直播主题是<云会议带你入门音视频世界>,华为云媒体服务产品部资深专家金云飞,与开发者们交流华为云会议在实时音视频行业中的集成应用,帮助开发者更好的理解华为云会议及其开放能力. 本 ...

  7. 代码安全丨第六期:XPath注入漏洞样例

    1.什么是XPath注入漏洞? XPath是一种用来在内存中导航整个XML树的语言,它使用路径表达式来选取XML文档中的节点或者节点集. XPath注入是指程序使用外部输入动态构造用于从XML数据库检 ...

  8. PHP使用OPENSSL RSA加密解密数据

    加密数据有很多种方法,今天我们来看一下OPENSSL RSA的加密办法. 1.首先得安装php的openssl扩展 php -m | grep openssl 执行以上命令,确保已经安装了openss ...

  9. 微信公众号-加解密数据demo坑

    demo里面的MsgSignature作为url参数一部分了,demo也不更新下 坑爹的微信! 解密信息部分 include_once "wxBizMsgCrypt.php"; $ ...

随机推荐

  1. 使用 KubeKey 搭建 Kubernetes/KubeSphere 环境的"心路(累)历程"

    目录 今天要干嘛? 在哪里干? 从哪里开始干? 快速开干! 解决依赖问题再继续干! 如何干翻重来? 连着 KubeSphere 一起干! 干不过,输了. 重整旗鼓,继续干! 再次重整旗鼓,继续干! 一 ...

  2. 【RocketMQ】NameServer的启动

    NameServer是一个注册中心,Broker在启动时向所有的NameServer注册,生产者Producer和消费者Consumer可以从NameServer中获取所有注册的Broker列表,并从 ...

  3. 31.Squid缓存代理服务器应用

    Squid缓存代理服务器应用 Squid安装介绍 web缓存的工作机制 缓存网页对象,减少重复请求 squid 主要提供缓存加速.应用层过滤控制的功能. 工作机制 代替客户机问网站请求数据,从而可以隐 ...

  4. 安装pystaller

    安装命令 # -i指定下载地址,此处采用清华大学镜像 pip install -i https://pypi.tuna.tsinghua.edu.cn/simple some-package pyin ...

  5. jieba分词原理解析:用户词典如何优先于系统词典

    目标 查看jieba分词组件源码,分析源码各个模块的功能,找到分词模块,实现能自定义分词字典,且优先级大于系统自带的字典等级,以医疗词语邻域词语为例. jieba分词地址:github地址:https ...

  6. 手把手教你实现在Monaco Editor中使用VSCode主题

    背景 笔者开源了一个小项目code-run,类似codepen的一个工具,其中代码编辑器使用的是微软的Monaco Editor,这个库是直接从VSCode的源码中生成的,只不过是做了一点修改让它支持 ...

  7. 从UI Designer上面动态创建下拉列表

    在UI Desigher上创建一个新的列表 并创建2个值,code 和value 添加一个EventHandler 在EventHandler上面添加一个Operation 类型为script$dat ...

  8. 聊聊 C++ 大一统的初始化运算符 {}

    一:背景 最近发现 C++ 中的类型初始化操作,没有 {} 运算符搞不定的,蛮有意思,今天我们就来逐一列一下各自的用法以及汇编展现,本来想分为 值类型 和 引用类型 两大块,但发现在 C++ 中没这种 ...

  9. SQLZOO练习三--SELECT within SELECT Tutorial

    This tutorial looks at how we can use SELECT statements within SELECT statements to perform more com ...

  10. 数据质量管理工具预研——Griffin VS Deequ VS Great expectations VS Qualitis

    开源数据质量管理工具预研--Griffin VS Deequ VS Great expectations VS Qualitis. 概述 ​ 数据质量监控(DQC)是最近很火的一个话题,也是数据治理中 ...