[笔记]saas成熟度模型和微服务

工作中需要开发面对大小客户的网站(烂大街的需求),考虑后台架构(怎么建项目),之前的Leader随口说了个方案:不是有看docker吗,做成分布式的、一个容器一个客户网站,一个客户网站一个数据库;网站代码都一样但配置文件不同,连接哪个数据库就是哪个客户的数据,开发也简单。实际尝试了下这里面其实是有很多问题的(打包发布就很麻烦、与前台的接口也很麻烦、各数据库的数据划分和相互查询更加麻烦),但是顺着他给的思路,了解到了Multi-Tenant和Multi-Instance概念,不过还是这篇Gianpaolo 2006: SaaS Simple Maturity Model 最直接清楚。

06年提出的成熟度模型到现在好像已经是基础概念,借用上面链接原图:
[笔记]saas成熟度模型和微服务
和其他一些blog介绍:
SaaS-Architecture-and-The-SaaS-Maturity-Model
saas-architecture-maturity-model
简单翻译:
1. Level 0: (Ad-hoc / Custom) 或(Chaos/完全混乱状态) :给每个客户各自定制软件服务,每增加一个客户都新写一套代码和运行一个新实例;
2. Level 1: (Configurable) 或(Managed Chaos/管理着的混乱状态):给每个客户提供同一套的软件(代码相同)、通过软件配置来区分各客户服务,每增加一个客户仍然需要运行一个新的软件实例;
3. Level 2: (Configurable, Multi tenant) 或(Multi-Tenant, Highrise/多租户、垂直升级):只运行一套软件来服务所有的客户(同样只有一套代码,但因为要处理多用户情况、系统设计和开发要求比Level 1高),要增加系统性能只能升级单节点的资源(cpu, memory…);
4. Level 3: (Scalable, Configurable, Multi tenant) 或(Multi-Tenant, Build-Out/多租户、水平扩展):仍然是用一套软件服务、但通过负载均衡的方式引入多个节点;
5. (原文中没有、可能是后来人加的)Level 4 (Utopia/乌托邦):以负载均衡等方式管理服务端多版本软件的多个实例,对外仍是统一的interface;


上图4里的每个实例(instance)有可能是一个monolithic software搞定了所有的功能服务(一个war包写完所有后台项目……),但更可能的情况是每个instance都是包含着多个子模块的复杂系统。既然(不管是业务上还是代码上)已经拆分成模块,就会很自然的想到:不必认死理的按 1个instance:1套应用服务{子服务1,子服务2,...} 这样的方式进行组织发布。如果这些 {子服务1,子服务2,…} 可以从大项目里解耦出来、作为一个发挥特定功能的小instance单独运行,即对图4的实例集群不是单纯地从负载均衡的角度进行整体软件系统的复制(如果不是复制而是从用户角度进行ad hoc地修改又会回到图1)、而是从服务的角度(SOA)进行系统分解(break down):
- 性能瓶颈的服务可以分配到更多的资源/节点;
- 一个模块的运行出错也不会把整套应用实例拖挂;
- 一条子服务可以有多个实例维持功能;
- 如果免不了特殊服务、也可以封装成另外的模块、而非散布到每个发布实例;

细化到一定程度就引出了微服务的概念。
参考AWS re:Invent 2016: From Monolithic to Microservices: Evolving Architecture Patterns in the Cloud (ARC305),下面图里连接着broswer的LoadBalancer就应该对应上图4里的Tenant Load Balancer:
[笔记]saas成熟度模型和微服务

PFC304 Effective IPC in the Cloud: The Pros and Cons of Micro Services Architectures
以及James Lewis&Martin Fowler: Microservices


回到开头的问题,总结2点:
1. 开头提到的方案就是Level 1的情况,虽然理想中只要一份代码、但实际很容易倒退回Level 0、Multi-Instance的情况(总有奇葩的客户需求);然后即便是Level 1、在web app里不区分用户省下的气力也要在项目发布和数据库管理等别的地方还回来…
2. 架构设计和docker其实没什么直接关系…提到docker只是当时正在看。但一个容器一个网站的想法、应该是“tomcat里丢war包”的思维定势吧。