在我们聊企业级 SaaS 产品稳定性之前我们先定义一下这里的企业级 SaaS 产品是什么,稳定性是什么。
1. 企业级 SaaS 产品
根据各家研报的定义,企业级 SaaS 是指以企业客户为服务对象,通过 SaaS 交付模式,向企业用户提供管理软件的服务。主要具有网络供应,集中托管、按需供应及服务化四大特征。
-
网络供应 是指 SaaS 产品大多部署在云端,每个客户使用产品的方式,通过互联网进行分发; -
集中托管 是指使用「多租户构架(Multi-Tenant)」,依靠对数据库分区/分表(其中的一种实现方式)来实现隔离操作,逻辑上隔离,物理层面是共享的。对私有化部署的客户,会单独处理; -
按需供应 是针对中小企业的需求,中小企业的需求在短时间内有较大幅度的变化,特别是一些快速增长的发展类企业; -
服务化 是指 SaaS 企业按月/年付费的商业模式,其核心的增长逻辑在于持续服务的能力,这也是 SaaS 企业的核心竞争力,第一次交付产品只是整个客户生命周期的起点。
以上 4 个特征可以让客户享有开箱即用、较低成本、实时更新以及按需订阅的优点。
1.1 SaaS 产品和 C 端产品的区别
SaaS 端产品面临复杂的业务场景和用户场景,因此进行细节设计时,必须关注建模、抽象、角色、权限等问题。除了使用者本身的功能需求以外,还需要考虑管理者或者决策者的管理需求。C 端产品面临的场景相对单一,并且使用者是相对独立的单个用户,因此不用关心角色、权限管理,而要关注用户的体验,需要在交互设计上投入很大精力。除此之外,在付费决策、使用场景、专业度的期待值、安全等方面都有不同:
-
付费决策人不同,C 端产品的使用者和决策者基本重合,而 SaaS 产品的决策者和使用者绝大部分可能是不同的两波人; -
SaaS 产品绝大部分在工作场景,而 C 端产品大部分在生活或娱乐场景; -
SaaS 产品关注功能 > 体验,需要能帮助他解决工作场景里面的问题,体验反而是其次; -
SaaS 客户花了钱,对稳定性要求会更高,对于问题的容忍度会变低,甚至有些要求会写到合同中去,当出现可用性问题时会有赔偿的情况; -
SaaS 客户对于专业服务的期待值不同,他们对于问题希望是有更专业的人员和更专业的方式来解决,如包括专业的服务,专业的产品,专业的流程,专业的人员,专业的交付,专业的客情维护和沟通话术; -
SaaS 客户对于产品安全、数据隐私、隔离等方面有更高的要求; -
SaaS 产品交付只是整个客户生命周期的起点,核心的增长逻辑在于持续服务的能力; -
SaaS 客户更看重服务过程中 SaaS 企业的专业表现。
1.2 隔离性
以隔离性为例,企业级 SaaS 产品对于隔离性的要求也不一样,我们看一下 AWS 对于隔离性有更细致的要求,总结起来有如下 3 点:
-
隔离不是可选项,是产品的基本要素,系统需要确保有解决方案来提供隔离性; -
身份验证和权限管理不等于隔离,它只是隔离的一个环节,在这个环节后面需要构建对于开发人员视野之外的隔离策略,并作为默认项; -
隔离不等于要求完全的物理隔离,可以基于共享资源模型的多租户逻辑,对于有特殊要求的可以提供物理资源级别的隔离。
思考一下,为什么会有隔离性的需求
SaaS 服务往往会服务于多家企业,企业与企业之间的数据需要完全隔离,不同的企业其量级,需求各有差别,当一家企业使用出问题时不能影响另外一家企业,比如某个企业触发了一个 BUG,这个 BUG 不能影响别的企业的使用,或者一家企业的数据量特别大,不能因为家企业的数据计算影响别家企业的计算,特别是有一些离线计算逻辑的时候。我们在使用云服务的时候也会遇到宿主机超卖的问题,这其实也是一种隔离性做得不到位的情况。
以上这些是我们了解到的一些关于 SaaS 企业的定义和特性。
做产品稳定性的建设和我们平时做一个需求一样,先要搞清楚需求方是谁,需求的价值是什么。
企业级 SaaS 的稳定性需求来自于哪里,是行业,政府,还是客户,还是公司要求?
比如金融行业,有一些业务模块对于稳定性的要求来自于政府,是不能打折扣的,做不好,可能会影响公司生死。又比如在内容相关的行业,如果对于一些涉政、涉黄等内容没能控制住,任其泛滥,可能会导致产品的下架,这里的要求同样来自于行业和政府。
回到我们企业级 SaaS 产品的稳定性,这个需求来自于购买了我们服务的客户,SaaS 产品解决的是工作中的问题,是生产资料的一种,当生产资料不可用的时候会对其工作产生破坏,比如依赖于某个数据分析系统的结论,但是数据分析不能用了,老板要求的报告就出不来,此时又不可能重新拉数据分析,只能等,这样可能就会影响用户第二天的的汇报工作等等,后果可能是丢了客户,甚至丢了工作。如果我们长期不稳定,稳定性也将会影响公司的生死。
相对于 C 端用户的数据,SaaS 的数据显得尤为重要,其作为企业资产的一部分,具有有形的价值,甚至是企业的核心资产,比如做代码管理的 SaaS 服务,对于一家软件公司来说,代码就是其核心的资产,如果因为 SaaS 服务数据丢失,或者泄漏,对于企业来说将会是影响企业生死的大事故。
2. 产品稳定性
前面更多的是聊需求和需求价值,接下来我们聊一下产品稳定性具体是指什么,以及如何做好产品稳定性。
产品稳定性包括三个方面:产品功能的稳定性、数据的稳定性和系统服务的稳定性。
2.1 产品功能的稳定性
产品功能的稳定性可以从功能的上线、变更和下线三个方面来看。无论怎样,我们在做产品功能的变更时都是以减少打扰用户为前提。
2.1.1 产品功能的上线
产品功能的上线,在上线每个功能的时候都要慎重,想不清楚宁可不做,在我们习惯了互联网的敏捷模式后,快速迭代,快速试错成为我们常规的工作方法,但是对于 SaaS 产品来说,敏捷不再是最重要的点。
对于我们的客户来说,更重要的是解决一个场景的问题,或者说解决他们工作中的问题,能提升效率。在我们上线一个产品功能的时候应该能讲出用户故事。
当有某个产品功能能够解决用户问题后,就不要经易改变其逻辑,因为用户已经可能将这个产品功能做到了工作的 SOP 里面。
2.1.2 产品功能的变更
产品功能的变更包括产品的版本规划、功能发布变更。
对于产品功能的规划或版本管理,需要有特定的节奏,让用户习惯你的节奏。对于每个版本,做好了,做稳了,把版本发布前前后后的事情做扎实了再慢慢发布出去,给客户一个接受的过程,一个较轻的落地。并且能让客户能快速找到变更了什么,给客户安全感,如 Saleforce 有一个发布说明(R)https://help.salesforce.com/s/articleView?id=release-notes.salesforce_release_notes.htm&type=5&release=240
有节奏的发版,比如 Canvas LMS(一个学习管理平台) 是每个月的每三个星期六正式发版(Release),每周的周三灰度部署(Deploy),用户可选择性预览使用灰度部署的功能 canvas release
又如 Salesforce 一年就三个版本,命名为 Spring, Summer,Winter spring-22-release 这里不仅仅是发版,发版只是技术层面的逻辑,这里的更多的是产品的逻辑,需求左移。
2.1.3 产品功能的下线
产品功能下线,在下线的时候要考虑到如何承接这部分用户的需求,尽量能有替代方案来承接。
变更管理没有银弹,我们能做的是控制节奏,以 SaaS 的逻辑来控制变更管理,这里的管理除了代码的发布,还有线上环境的变更,线上配置的变更等等,强调一点:在用户的使用期间,不要动任何线上的东西,包括代码,配置,环境等,一切以不影响用户工作为前提。
当产品功能变更,或者进行大版本升级时充分考虑用户的操作习惯以及学习成本,可能你面对的用户在电脑上学会一个操作是很难的一件事情,甚至需要有人专门来培训。每一次的产品变更就需要其培训负责的同学从头来培训一遍。
就算用户量少,也要进行灰度,减少影响范围。
2.2 数据的稳定性
数据的稳定性是企业级 SaaS 产品特别重要的一点,只有确保客户数据的安全性才能长久提供服务,其主要包括以下 4 点:
-
数据不会乱,主要是指当用户习惯了一些数据的逻辑后,不要轻易的打乱,如一些默认排序规则,一些分类逻辑之类的; -
数据不会丢,数据备份,长期存储,对于上传的文件,在满足成本要求的基础上,尽可能的存下来,如果实在不能存了,也放一个地方,给用户一个出口可以方便获取得到; -
数据不会泄漏,这块是数据安全的范围,比较常见的问题是不同的租户数据串了,或者不同的用户数据串了,这里原因可能是代码问题或者架构问题。还有更严重如我们在网上经常看到的被拖库,如前段时间上海的数据泄漏 -
数据可追溯,对于用户的操作,有详细的日志,知道数据从哪来的,要到哪去的,当出了问题可以追溯。
2.3 系统服务的稳定性
系统的稳定性包括系统的可用性和性能稳定:
2.3.1 系统的可用性
系统的可用性指在一个给定的时间间隔内,对于产品系统来说,总的可用时间所占的比例。我们一般用 SLA(Service-level Agreement) 约束和描述可用性,其常用指标如下:
-
MTBF:Mean Time Between Failure,平均故障间隔时间 -
MTTR:Mean Time To Repair,平均恢复前时间 -
MTTF:Mean Time To Failure,修复前平均时间
关于可用性,所要做的事情太多,简单几个字,可用性治理就包括了度量、线上管控、架构治理和研发管理等等。
在互联网行业有个对于线上事故 「 1-5-10 」的原则,即 1 分钟发现,5 分钟定位,10 分钟恢复,如果能做到这个程度,算是及格了。而且这只是针对可用性线上事故处理 SOP 中的一个逻辑,我们要做的事情还有很多。
落到常规建设中,监控、压测和演练,三个经常要做的操作,但是实际上我们仅仅关注了监控的一部分及压测的一部分。
关于系统可用性我们可以做如下一些关键的步骤:
-
测试并跟踪当前的可用性:先有度量,诊断我们可用性的状态; -
将手动流程自动化,自动化部署过程:相信代码比人更靠谱,特别是针对重复性事务; -
维护和跟踪管理系统中的所有配置:所有和线上相关的都是线上环境,而线上配置的变更往往是高危风险地带; -
构建线上问题的快速恢复能力:包括但不限于灰度发布、A/B 实验环境,允许快速更改并进行实验,并且保证如果出现了问题可以轻松回滚; -
将线上问题和系统可用性作为技术团队的核心绩效指标:管理逻辑中有一个核心点你考核什么,大伙儿就会注重什么,人多数是趋利的; -
以不断改进应用程序和系统为目标:反脆弱、不能因为怕变更带来的风险而停止改进; -
服务分级,制定严格的 on-call 机制,对于核心服务需要在分钟级响应并处理。
2.3.2 系统的性能稳定
系统的性能稳定指在满足用户功能可用的基础上,稳定性能,同时在一定程度上帮助可用性的建设。
稳定性和可用性相比,除了关注系统可以无故障地持续运行时间,故障发生的频率,还会关注性能劣化趋势等等。稳定性更关注系统在给定条件下的响应是否一致,行为是否稳定。稳定是对可用性的进一步的要求。
上面聊完了企业级 SaaS 产品和产品稳定性,接下来我们聊聊如何长久的做稳定性的治理,如董宇辉老师在直播间谈到初恋时说的:「你不就图我吗?更长久的图我吗?我懂」,对于稳定性我们也是想长久的图。而且还是用科学的方法系统来图。
3 基于风险模型的稳定性治理
考虑到稳定性治理是一个长期的事情,且是需要持续迭代的,如果只是靠人来推动,当人员变动或者工作重点变化时,可能稳定性相关的事情就会陷入停滞状态。
此时我们可以把所有的稳定性问题抽象出来,形成风险,我们通过系统性的持续的识别风险,并制定对应的风险缓解计划和应对计划,应该是可以较好的控制整个系统的稳定性情况。
管理风险的第一步是识别并理解系统中已有的风险。识别、标记并对已知的风险排列优先级,这就是风险模型所要做的事情。
尽管我们总是想消除风险,但是这样做的成本通常是无法接受的,无论是从实际成本还是从机会成本的角度来看都是如此。我们肯定有更重要、更加需要以客户为中心的事情要做,这些事情对我们的客户、公司来说都有好处,而不是从应用程序中消除你所知道的每一个风险。
管理风险涉及对每个风险评估两个值:风险的可能性和风险的严重性。一般来说,严重性是风险发生时的成本,而可能性是风险发生的概率。一个不太可能发生但是会对应用程序造成非常严重影响的风险,不一定是你想要消除的风险。同样,一个很可能发生但是对应用程序影响很小的风险,也不一定是你想要优先消除的风险。但是,一个很可能会发生并且会导致严重影响的问题,是你需要优先解决的风险。
3.1 风险管理
在聊风险模型之前,我们先聊一下风险管理。
风险管理(Risk Management)是指如何在项目或者企业一个肯定有风险的环境里把风险减至最低的管理过程。风险管理是指通过对风险的认识、衡量和分析,选择最有效的方式,主动地、有目的地、有计划地处理风险,以最小成本争取获得最大安全保证的管理方法。
从系统开发的角度看,风险管理包括系统中的风险的位置,确定哪些风险必须消除,哪些风险可以暂时存在,以及如何降低这些留存风险发生的可能性和重要性。
风险主要由可能性和严重性两方面组成:
-
严重性:如果风险发生,所需付出的代价 -
可能性:风险发生的概率
管理风险就是要管理这两个方面。
3.2 风险模型
风险模型是风险管理的第一步:理解系统中已有的风险,识别、标记并对已知的风险排列优先级,最终形成一张包含了系统所有已知风险的当前状态的表格。这就是我们所说的风险模型。
建立风险模型的过程是识别风险的过程,在这个过程中我们需要识别出系统中已有的风险,并对其进行分析,标记出优先级、梳理当前状态和历史情况。
风险模型构建过程中需要考虑模型的作用范围,是公司级的,团队级的,项目组的,还是服务级的。
对于一个小公司,可以是公司级的,对于大型一些的公司,可以考虑团队或项目级的。
风险模型至少包括以下一些方面:
-
严重性/可能性:高中低,先评估严重性,再评估可能性 -
风险缓和计划:可以使用的或者正在使用的用来降低该风险严重性或者可能性的风险缓和措施。 -
监控:对该风险的发生是否进行了监控,如果监控了说明监控的指标,如果没有监控,说明原因,以及达成监控目标的原因,最终所有的风险应该是要监控起来的。 -
状态:活跃 / 已缓和 / 正在修复 / 已解决 -
历史风险情况:该风险在历史上有没有发生过,什么时候,发生频率等 -
风险缓和计划:当我们制定风险缓和计划的时候,需要从严重性最高的项开始,缓和风险不是为了消除,而是为了降低风险的严重性和可能性。并不是每一个风险都要制订风险缓和计划。 -
风险预案:当风险发生的时候,我们可以采取的措施
除此之外,还包括一些常规的添加时间,ID,负责人之类的
3.3 识别风险
我们参照如上风险模型的项,通过头脑风暴等方式构建整个风险模型,在过程中可以考虑从如下的一些点中提取风险点:
-
已知的故障 -
有出现的告警 -
用户支持的反馈 -
可能存在的性能问题,或者一些慢 SQL 等 -
服务间的强弱依赖 -
一些功能的缺失 -
服务单点 -
内部和外部/离线和在线业务的相互影响 -
服务容量的不足 -
基建发布或扩容等发布操作会影响业务的情况 -
线上配置/环境/网络等的变更 -
安全问题 -
系统或流程的问题,如没有文档,没有沉淀,只在某些人的脑袋里面 -
一些已知的,明确的技术债务
基于上面的逻辑,我们梳理后可以得到一个风险列表,我们称之为风险模型。
3.4 风险缓和计划
风险模型中的风险缓和计划用来说明可以进行或者正在进行哪些风险缓和措施,来降低当前风险的严重性、可能性。这里我们不需要完全消除风险,只是降低风险发生的可能性和严重性。
常见的风险缓和计划,我们一些常见的降级策略属于风险缓和计划的主要部分,包括但不限于:
-
前端降级:应对后端服务不可用或后端服务异常等风险; -
缓存降级:应对存储不可用或下游服务不可用等风险; -
主备切换:应对主存储不可用等风险; -
业务隔离:应对多业务接入时,单个业务引起的整体服务不可用的风险; -
应用限流:应对多业务接入时,单个业务引起的整体服务不可用的风险; -
整体限流:应对大流量突发的风险,保障部分用户可用; -
容量评估及提前扩容:应对大流量突发的风险,保障一定程度流量下的业务稳定性; -
全链路压测:应对整体链接容量不一致的风险,防止单点容量风险; -
线上问题及用户反馈清理:应对系统中小的风险引起的大风险,如一些系统 BUG,一些没有测出来的问题等等; -
线上告警及时处理:应对系统中小的风险引起的大风险,如一些系统 BUG; -
扩缩容演练:应对容量冲击时基建没有准备好的风险; -
定期压测及容量评估:应对系统演化过程中,代码变更,模块变更导致的容量变化; -
性能优化:应对系统中某些服务的性能问题导致的风险;
以上的一些策略只是缓和了部分风险,像容量的风险,BUG 的风险,不可用的风险不可能完全消除,只能缓和,以降低风险发生的可能性,或者降低风险发生时的严重性。
基于以上的一些思路,我们需要做一些专项和一些机制来保证风险可控。
但风险之所以为风险,是说明他还是有可能发生的,当发生时我们需要做什么呢,这就是我们接下来要准备的预案。
当风险发生时,我们计划如何来处理,这个计划是我们有预先设计的,是一个系统性的计划。
比如,当容量突发时,开启降级策略或者限流策略等等。
3.5 定期风险回顾,维护风险模型
风险模型是稳定性治理过程的抓手,通过不停的识别风险,消除风险,缓和风险,不断提高稳定性变好的可能,以最终达到稳定性的目标。
风险评估和应对规划是一个反复重复的过程,不停的迭代风险模型,识别出新的风险。
当风险模型构建完成后,我们需要定期逐个风险拉出来 review 一次,我们可以问我们自己如下的一些问题:
-
与上次回顾相比,风险有更严重吗?可能性有更高吗? -
接下来会排专人来解决某些风险吗?是否应该安排? -
上次回顾安排的事项落实了,对应的风险情况如何,是否有更新到风险模型中?
问完问题,我们可能需要有一些实际的行动:
-
评估是否有新的风险; -
删除旧的风险:如果风险已经解决了,可以归档; -
评估原有风险模型中的每一项风险,评估其严重性和可能性,如果有变动,对其进行更新; -
对于不同的优先级的风险区别对待。
以上的回顾操作我们建议以某个管理系统来承载,并且这个管理系统是带有通知等功能,以更好的将风险相关的信息周知出去,如 Jira 系统。
写在最后
记得当年「我是歌王」有一段汪涵救场的主持,从一个观众的角度看,真的牛逼,简直是教科书式,这算是一个超大的线上事故,但是这和我们的稳定性有什么关系呢,我们有如下的思考点:
-
为什么会有这个事故发生 – 问原因 -
在流程和机制上是否有改进的空间来规避 – 如何系统性的规避 -
这个事故有没有其它更平滑的处理方案,减少对用户的影响 – 如何减少影响 -
我们是否需要英雄 – 线上不应该有英雄
如同扁鹊的大哥一样:「长兄于病视神,未有形而除之,故名不出于家」
最后有一些原则可以指导我们稳定性的工作:
-
以用户为中心,不打扰,不影响 -
灰度,产品灰度,发布灰度,坚持住 -
防微杜渐,敬畏线上 -
快速发现,快速解决,减少对于用户的影响
重复一句:我们所做的一切都是以减少对客户的打扰为前提。
在我们所有的事项中并没有写与组织结构、人才梯队相关的内容,并不是这些不需要,恰恰相关,他们至关重要。下次有机会我们再聊。
最后,祝大家新年快乐~