搞砸SaaS开发?你要知道这些事!

想要让SaaS开发更上一层楼?

这些事情请搞懂。

一、一份代码多处部署

搞砸SaaS开发?你要知道这些事!

通常将用来跟踪代码修订的数据库称为代码库,对于Git来说,最上游的那份代码库的主干(通常是main分支)就是基准代码。

一个应用应当只是用一份基准代码(即分布式系统中的每个组件都应该是一个应用),每个应用都应该有自己独立的基准代码。如果你现在需要多个组件共用代码,应当将共用的部分分离出来,当作独立的库,然后通过依赖的方式加以管理。比如,我们在开发中经常会用到WebSocket,我们为此实现了sockjs-broker和sockjs-broker-client;http请求我们实现了es-fetch-api。

尽管每个应用只有一份基准代码,却可以同时部署在不同的环境中,每个部署是应用的一个实例。我们常见的部署包括一个生产环境的部署、一个或多个测试和准生产环境部署。此外,每个开发人员在本地开发环境也会运行一个应用实例,也相当于一份部署。

搞砸SaaS开发?你要知道这些事!

每个部署可以使用基准代码库的不同版本,比如,开发人员使用的版本应当永远比准生产环境更新,准生产环境的版本比生产环境更新,这些环境共享基准代码库,是相同应用的不同部署。

还有一些极端场景,也应当做到一份代码多处部署:一个场景是在不同客户的环境中私有化部署相同的应用并实现定制化的要求;另一个场景是接口应用的版本升级,同时在线兼容不同版本的客户端。对于这些极端场景,开发人员的代码设计能力、工程实践执行能力高低就会成为决定性的要素。

参考这里

二、依赖显式化

搞砸SaaS开发?你要知道这些事!

大多编程语言都有打包系统,以便分发库包(比如jar、dll、so等)。打包系统可以将这些库包进行分发(比如mvn deploy、yarn publish)供所有应用使用。

在SaaS的开发中,应用必须通过依赖清单确切地声明所有的依赖项,并且通过npm、maven这些工具来保证应用不会调用系统中存在但未声明的依赖项。这样做能够让生产和开发环境保持一致。

显式声明依赖还能简化开发环境的准备。只需要拉取基准代码、安装语言环境和依赖管理工具并执行依赖安装命令(比如npm i、yarn),就可以开始干活了。

同样的,如果应用需要依赖某些系统工具,比如make、jdk、curl,那么这些工具也应当通过显式声明进行安装。

三、配置只存在环境中

(而不是代码中)

搞砸SaaS开发?你要知道这些事!

应用的配置在不同的部署(比如准生产环境、生产环境、开发环境)之间差异很大,尤其是数据库和其他后端服务相关的配置、安全凭证相关的配置、域名等每份部署特有的配置等。在SaaS开发中,一定要避免在代码中使用常量保存配置,代码和配置要严格分离,才能做到:部署间存在大幅差别,代码却完全一致。这个要求是否满足的验证方法十分简单:看该代码是否可以立即开源而不会暴露任何敏感信息。

特别说明的是,像是Vue Routes这样的内部配置在不同部署间不存在差异,应该写入代码中。

做配置管理时,尽可能将应用的配置存储于环境变量中。环境变量可以随时修改而不需动代码。相比语言提供的配置文件支持(比如asp.net的web.config、java的properties文件),环境变量可以做到与语言和系统无关。

在实际开发中,还可以采用一些与环境变量完全相同的方案,比如,我们会在开发node.js应用时,使用dotenv-flow将环境变量持久化在.env文件中,我们可以使用.env.staging.local这样的文件来做到对环境变量配置的快速换模同时不影响基准代码。对于不同的环境部署,特别是同一个应用在不同客户环境中的部署,我们通过特性开关也得到了妥善的配置。

环境变量的粒度要尽可能小,并且相对独立,这样即便应用不断扩展出更多种类的部署时,也能够做到平滑过渡。

四、依靠无状态应用进程水平扩展

搞砸SaaS开发?你要知道这些事!

在SaaS开发中,应用的进程必须是无状态且无共享的,也就是说同一个服务处理逻辑对于任何两个不同的请求应当视为两个完全不相关的请求,需要持久化的数据都应存储在底层服务中(比如数据库)。如果一个SaaS应用的某个请求需要克隆代码库到本地磁盘并进行修改和提交,那么这个应用就不应当考虑将这个本地代码库留给后续的请求使用,也不应考虑留给其他应用使用。早期电商网站的开发经常会使用进程内的Session机制来保持用户的购物车,一旦服务器集群进行重启或扩展,就会导致数据丢失,所以按照无状态的要求,应该改为使用redis或memcached。

这样的SaaS才会具备无共享、水平分区的特点,当并发急需扩展时,才能通过增加进程数实现水平扩展。

五、开发环境视同线上环境

搞砸SaaS开发?你要知道这些事!

开发环境和线上环境之间总是存在差异,比如:

1、开发人员正在写的代码一段时间后才会上线,导致部署的代码版本差异(时间差异)。

2、开发人员写代码,而运维人员部署代码,信息不对称(人员差异)。

3、开发环境使用windows,线上环境使用linux(工具差异)。

这些差异会让持续部署变得困难重重,比如线上问题经常在开发环境无法复现这些怪现象。

所以SaaS开发应当持续不断地、尽可能地缩小本地与线上的差异,比如:

1、开发人员要学习如何做到可以几小时甚至几分钟内就完成代码修改并部署。

2、开发人员不仅要编写代码,更应该参与部署,关注代码的线上表现。

3、开发人员要尽力保证开发环境和线上环境的一致性。

后端服务也要保持一致。虽然很多开发框架提供了不同类型服务的适配器,几乎可以消除使用上的差异(比如用springboot开发,可以很容易做到本地开发使用sqlite,线上使用postgresql),但是,一旦出现偶发的不兼容,就会给持续部署带来阻力,整体来看,要消除这种阻力可是代价不菲。当然,后端服务适配器仍然是有用的,可以让移植和迁移后端服务变轻松。

六、日志即事件

搞砸SaaS开发?你要知道这些事!

日志能让我们看到应用的行为。通常,在基于服务器的环境中,日志会写入到磁盘文件中,但这只是一种格式。日志是按照时间顺序汇总的事件流,这些事件从所有运行的进程和底层服务中收集而来。日志的原始形态通常采用每行一个事件的文本格式,它没有固定的开始和结束,只要应用在运转,事件就会持续流入。

SaaS应用不应自己处理如何对输出流进行导流或存储(比如写入或管理日志文件),而是直接写入stdout。在本地开发环境,开发人员可以在终端看观察应用的行为。在准生产或生产环境中,每个进程的日志流都应当由执行环境捕获,与其他应用的流一起导流到最终存储,以便进行查看和长期存档。应用和配置要做到不知道这些日志存储的存在,因为运行环境会对这些最终的存储加以屏蔽和管理,开源的日志导流方案Logplex和Fluentd就是做这个用的。

事件流可以被导流到一个文件中,也可以通过终端进行实时的tail查看。事件流还可以被发送到Splunk这样的日志索引和日志分析系统中,或者Hadoop/Hive这种通用的数据仓库系统中。这些系统能让应用具备可观测性,比如找出过去一段时间的特定事件、绘制某种大规模的趋势(如QPS)、根据用户定义的条件触发情报(如每分钟报错超过报警线)。

?作者:李淳?

搞砸SaaS开发?你要知道这些事!

往期回顾

搞砸SaaS开发?你要知道这些事!

浅谈Kubernetes Operator

浅谈数据库发展历史

搞砸SaaS开发?你要知道这些事!

带你揭开WIFI的面纱

搞砸SaaS开发?你要知道这些事!

监控的分布式探索

公众号:EBCloud

赶快扫码关注我们吧!

原创文章,作者:EBCloud,如若转载,请注明出处:https://www.sudun.com/ask/33766.html

Like (0)
EBCloud的头像EBCloud
Previous 2024年4月2日
Next 2024年4月2日

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注