答面试官问:如何设计SaaS项目的架构

概念#

SOFTWARE AS A SERVICE#

在某些方面,SaaS 非常类似于早些年的客户端软件模式,其中客户端(在这种情况下通常是 Web 浏览器)提供对服务器上运行的软件的访问点。SaaS 是消费者最熟悉的云服务形式。SaaS 将管理软件及其部署的任务转移到第三方服务。最熟悉的业务 SaaS 应用程序是客户关系管理应用程序,如 Salesforce,像 Google Apps 这样的生产力软件,以及 Box 和 Dropbox 等存储解决方案的软件。

使用 SaaS 应用程序往往会降低软件所有权成本,因为不需要技术人员来管理软件的安装,管理和升级,同时这也可以降低软件许可的成本。SaaS 应用程序通常在订阅模式上被提出来。

PLATFORM AS A SERVICE#

PaaS 提供比 SaaS 低一级的功能,通常提供可以开发和部署软件的平台。 PaaS 提供者抽象处理服务器的大部分工作,并为客户提供了操作系统和服务器软件以及底层服务器硬件和网络基础设施的环境,使用户可以自由地关注业务端可扩展性及其产品或服务的应用开发。

与大多数云服务一样,PaaS 是建立在虚拟化技术之上的。企业可以根据需要申请资源,随着需求的增长而不是以冗余资源投入硬件。

PaaS 提供商的例子包括 Heroku,Google App Engine 和 Red Hat 的 OpenShift。

INFRASTRUCTURE AS A SERVICE#

继续朝服务的下层看,我们就可以看到云服务的基本构件。 IaaS 由高度自动化和可扩展的计算资源组成,由云存储和可以自动配置,计量和可用的按需网络功能组成。

IaaS 提供商通过仪表板以及 API(API 可能没有)提供这些云服务器及其相关资源。 IaaS 客户可以直接访问其服务器和存储,就像传统服务器一样,但这样拥有更高级别的可扩展性。 IaaS 的用户可以在云中外包和构建 “虚拟数据中心”,并可以访问许多与传统数据中心相同的技术和资源功能,而无需投资于服务器容量规划或物理管理维护。

IaaS 是最灵活的云计算模式,允许自动的服务器,处理能力,存储和网络的自动部署。 IaaS 客户对基础设施拥有真正的控制,比 PaaS 或 SaaS 服务的用户不知道高到哪里去了。 IaaS 的主要用途包括 PaaS,SaaS 和网络规模应用程序的实际开发和部署。

有很多提供商提供 Iaas,比如 Navisite,Exoscale 和 Softlayer,具有自己独特的价格方案和服务组合可供选择。

ComputeNext(作者的网站)为 IaaS 提供一个经纪服务,以便你可以确保为您的应用需求选择合适的 IaaS 提供商。通过使用单一 API 对 20 多个云提供商进行归一化的访问,您可以比较提供商的价格和性能,从而找到最佳配置,然后构建和部署,而不会被绑死到一个平台。

具体例子可以参考:www.zhihu.com/question/21641778/an...

通俗的讲 pass 和 saas 的区别#

paas 给你一个完善的开发,测试,上线的环境,应用工程代码还是需要你来开发,在开发过程需要的一些服务已经帮你做好,比如:短信服务,邮件服务,分布式文件系统服务,域名备案服务,网络端负载均衡服务,数据库端负载主从热备服务,分片服务,vpn 服务,https 服务,各个线上服务器的监控统计服务等;saas 是应用工程帮你做好,你只需要调整下页面配置,即可上线运营,有点类似淘宝平台与淘宝入驻商家之间的关系。

程序设计#

分层设计#

saas 系统分层大概是:

租户识别 > 应用层 > 数据访问层 > 缓存层 > 数据库

数据隔离#

saas 系统说起来很简单,任何系统似乎加个 tenant_id (租户 id) 就变成 saas 系统了。比如原来的用户登录是:


select username,password from users where email='abc@qq.com'

改成


select username,password from users where email='abc@qq.com' and tenant_id =1;

对于复杂业务的 saas 系统,这样做法非常危险,而且开发效率很低。你想想如果那个程序员写 sql 时候忘了加 “and tenant_id =1” . 结果不堪设想。

比较好做法是在数据库访问层对租户鉴别进行封装,SQL 进行改写。


function getUserInfo($where,tenant_id){

//sql

}

技术实现#

关于多租户的数据隔离方案#

独立数据库#

这是第一种方案,即一个租户一个数据库,这种方案的用户数据隔离级别最高,安全性最好,但成本较高。

优点:

为不同的租户提供独立的数据库,有助于简化数据模型的扩展设计,满足不同租户的独特需求;如果出现故障,恢复数据比较简单。

缺点:

增多了数据库的安装数量,随之带来维护成本和购置成本的增加。

这种方案与传统的一个客户、一套数据、一套部署类似,差别只在于软件统一部署在运营商那里。如果面对的是银行、医院等需要非常高数据隔离级别的租户,可以选择这种模式,提高租用的定价。如果定价较低,产品走低价路线,这种方案一般对运营商来说是无法承受的。

共享数据库,隔离数据架构#

这是第二种方案,即多个或所有租户共享 Database,但是每个租户一个 Schema(也可叫做一个 user)。

优点:

为安全性要求较高的租户提供了一定程度的逻辑数据隔离,并不是完全隔离;每个数据库可支持更多的租户数量。

缺点:

如果出现故障,数据恢复比较困难,因为恢复数据库将牵涉到其他租户的数据;

如果需要跨租户统计数据,存在一定困难。

共享数据库,共享数据架构#

这是第三种方案,即租户共享同一个 Database、同一个 Schema,但在表中增加 TenantID 多租户的数据字段。这是共享程度最高、隔离级别最低的模式。

优点:

三种方案比较,第三种方案的维护和购置成本最低,允许每个数据库支持的租户数量最多。

缺点:

隔离级别最低,安全性最低,需要在设计开发时加大对安全的开发量;

数据备份和恢复最困难,需要逐表逐条备份和还原。

如果希望以最少的服务器为最多的租户提供服务,并且租户接受牺牲隔离级别换取降低成本,这种方案最适合。

选择合理的实现模式#

衡量三种模式主要考虑的因素是隔离还是共享。

成本角度因素#

隔离性越好,设计和实现的难度和成本越高,初始成本越高。共享性越好,同一运营成本下支持的用户越多,运营成本越低。

安全因素#

要考虑业务和客户的安全方面的要求。安全性要求越高,越要倾向于隔离。

租户数量因素#

系统要支持多少租户?上百?上千还是上万?可能的租户越多,越倾向于共享。

平均每个租户要存储数据需要的空间大小。存贮的数据越多,越倾向于隔离。

每个租户的同时访问系统的最终用户数量。需要支持的越多,越倾向于隔离。

是否想针对每一租户提供附加的服务,例如数据的备份和恢复等。这方面的需求越多, 越倾向于隔离。

信息监管因素#

要考虑政府,机关,企业,公司的安全和信息监管相关的一些政策和规定。

基于 laravel 框架开发 SaaS 系统#

  1. 利用 laravel 内置的前置中间件对租户请求域名进行判断,进而区分租户。

  2. 每个租户的密钥来对应请求域名,后端鉴权通过每个租户不同的密钥和请求域名来制造签名,中心 API 服务器以此鉴权。实现 ACL,防止数据遭窃。

  3. 分库分表,实现数据隔离,可以使分库作为本公司 master 数据库的一个备库扩展库,从而实现读写分离,数据安全,查询优化等功能。

  4. 为 saas 用户提供服务器前端项目,不提供数据链接,服务器前端项目为可转发请求的服务治理中间件功能的框架(curl,guzzle),租户可以买账号直接使用系统,也可以搭在自己服务器,自行增减配置运维,写前端代码添加个性化的内容比如商标、首页、详情页等等。后端接口维护在本公司的服务器,如果系统有 bug 可以随时处理而不需要去所有租户的服务器重新部署,实现平滑升级。

租户识别方案#

比较好做法是通过 url 识别租户。系统是给租户生成一个随机的三级域名,比如 abc.crm.baidu.com. 如果客户想使用自己的域名,可以在 cname 到我们生成的三级域名,并在管理系统里面做绑定。

租户管理系统(计费,订购,定制,充值,催缴)#

Saas 系统是必须考虑计费系统和租户控制系统。这个系统需要都是独立设计。比如那个租户购买了那些模块,一个月多少钱。租户可以创建最多的用户数。计费到期邮件提醒等功能。

计费方式一般有两种,周期性计费,类似月租方案,和使用量计费,用多少付多少。 周期性计费比较简单。也可以两者结合起来。

定制化开发#

SAAS 的优势在于一套系统多人使用,似乎和定制化开发有冲突。比如 A 客户想要 A 功能,B 客户不想要。但定制化开发是无法避免的,比如 CRM 系统这样复杂的系统,不可能一套系统满足所有公司的要求。定制化开发尽可能分系统,分模块去做。然后通过控制台中配置不同租户订购不同模块,那些模块可以在前端页面上显示。不同的子系统需要分开部署。前端可通过 nginx 根据 url 分发,比如 abc.crm.baidu.com/bi/xxx/xx 这个地址,就分发到 BI 子系统。

还有开发和产品,现有需求一定要分析清楚,不要一上线发现后患无穷。新功能尽量做的独立可以配置。

灰度升级#

SAAS 付费企业客户对系统问题都特别敏感。 为了减少升级可能出现问题的影响范围,一般都采用灰度升级策略。如果使用了 url 来区分不同租户,灰度升级配置就会很方便。可以配置 nginx 来根据域名做分发,比如租户 A(aaa.com)到实例 1(版本 1.0),租户 B (bbb.com) 到实例 2 (版本). 当需要域名配置非常多的时候,nginx 配置文档会乱。这块时候可以考虑使用 nignx_lua 来写一些扩展模块。

转自电子书#

www.kancloud.cn/martist/be_new_fri...

答面试官问:如何设计SaaS项目的架构

本作品采用《CC 协议》,转载必须注明作者和本文链接
是非之外有一座花园,我们会在那里相遇
本帖由系统于 4年前 自动加精
Martist
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 1
porygonCN

laravel 使用 saas 推荐 stancl/tenancy 扩展包,使用简单且可高度自定义,想尝试只需要跟着 quick start 完整走一遍即可

4年前 评论
91it 4年前
91it 4年前
porygonCN (作者) 4年前
91it 4年前
L学习不停 4年前
L学习不停 4年前
zhaocrazy 4年前