微服务架构已经很流行了,并且有大量文章描述相对单体架构,微服务架构带来的众多优点。
怎么从单体架构更优雅地转化为微服务架构呢?
有一种被实践证明有效的方法论:The Twelve-Factor App[1]
1、Codebase
一份基准代码,多份部署
尽管每个应用只对应一份基准代码,但可以同时存在多份部署。每份部署相当于运行了一个应用的实例。通常会有一个生产环境,一个或多个预发布环境。此外,每个开发人员都会在自己本地环境运行一个应用实例,这些都相当于一份部署
2、Dependencies
显式声明依赖关系
12-Factor规则下的应用程序不会隐式依赖系统级的类库。它一定通过依赖清单 ,确切地声明所有依赖项
3、配置
在环境变量中存储配置
通常,应用的配置在不同部署 (预发布、生产环境、开发环境等等)间会有很大差异。这其中包括:
•数据库,Memcached,以及其他 后端服务 的配置•第三方服务的证书,如 Amazon S3、Twitter 等•每份部署特有的配置,如域名等
有些应用在代码中使用常量保存配置,这与12-Factor所要求的代码和配置严格分离显然大相径庭。配置文件在各部署间存在大幅差异,代码却完全一致。
4、后端服务
把后端服务(backing services)当作附加资源
后端服务是指程序运行所需要的通过网络调用的各种服务,如数据库(MySQL,CouchDB),消息/队列系统(RabbitMQ,Beanstalkd),SMTP 邮件发送服务(Postfix),以及缓存系统(Memcached)。
每个不同的后端服务是一份资源 。例如,一个 MySQL 数据库是一个资源,两个 MySQL 数据库(用来数据分区)就被当作是 2 个不同的资源。12-Factor 应用将这些数据库都视作 附加资源 ,这些资源和它们附属的部署保持松耦合。
5、构建,发布,运行
基准代码 转化为一份部署(非开发环境)需要以下三个阶段:
•构建阶段 是指将代码仓库转化为可执行包的过程。构建时会使用指定版本的代码,获取和打包 依赖项,编译成二进制文件和资源文件。•发布阶段 会将构建的结果和当前部署所需 配置 相结合,并能够立刻在运行环境中投入使用。•运行阶段 (或者说“运行时”)是指针对选定的发布版本,在执行环境中启动一系列应用程序 进程。
12-factor 应用严格区分构建,发布,运行这三个步骤。举例来说,直接修改处于运行状态的代码是非常不可取的做法,因为这些修改很难再同步回构建步骤。
6、进程
以一个或多个无状态进程运行应用
运行环境中,应用程序通常是以一个和多个进程运行的。
12-Factor 应用的进程必须无状态且无共享。任何需要持久化的数据都要存储在后端服务内,比如数据库。
7、端口绑定
通过端口绑定(Port binding)来提供服务
互联网应用有时会运行于服务器的容器之中。例如 PHP 经常作为 Apache HTTPD 的一个模块来运行,正如 Java 运行于 Tomcat 。
12-Factor 应用完全自我加载 而不依赖于任何网络服务器就可以创建一个面向网络的服务。互联网应用 通过端口绑定来提供服务 ,并监听发送至该端口的请求。
8、并发
通过进程模型进行扩展
任何计算机程序,一旦启动,就会生成一个或多个进程。互联网应用采用多种进程运行方式。例如,PHP 进程作为 Apache 的子进程存在,随请求按需启动。Java进程则采取了相反的方式,在程序启动之初 JVM 就提供了一个超级进程储备了大量的系统资源(CPU和内存),并通过多线程实现内部的并发管理。上述2个例子中,进程是开发人员可以操作的最小单位。
9、易处理
快速启动和优雅终止可最大化健壮性
应用程序的进程应该是一次性的,以便它们可以快速启动、停止和重新部署,而不会丢失数据。这有助于快速弹性扩展、代码和配置更改的快速部署以及生产部署的稳健性。
10、开发环境与线上环境等价
尽可能的保持开发,预发布,线上环境相同
从以往经验来看,开发环境(即开发人员的本地 部署)和线上环境(外部用户访问的真实部署)之间存在着很多差异。这些差异表现在以下三个方面:
•时间差异:开发人员正在编写的代码可能需要几天,几周,甚至几个月才会上线。•人员差异:开发人员编写代码,运维人员部署代码。•工具差异:开发人员或许使用 Nginx,SQLite,OS X,而线上环境使用 Apache,MySQL 以及 Linux。
12-Factor 应用想要做到 持续部署 就必须缩小本地与线上差异。再回头看上面所描述的三个差异:
•缩小时间差异:开发人员可以几小时,甚至几分钟就部署代码。•缩小人员差异:开发人员不只要编写代码,更应该密切参与部署过程以及代码在线上的表现。•缩小工具差异:尽量保证开发环境以及线上环境的一致性。
11、日志
把日志当作事件流
将日志流式传输到选定的位置,而不是将它们转储到日志文件中。日志可以定向到任何地方。例如,它们可以被定向到 NoSQL 中的数据库、另一个服务、存储库中的文件、日志索引和分析系统或数据仓库系统。
12、管理进程
后台管理任务当作一次性进程运行
将管理任务与应用程序的其余部分分开,以防止一次性任务导致正在运行的应用程序出现问题。容器使这很容易,因为可以启动容器只是为了运行任务然后将其关闭。
References
[1]
The Twelve-Factor App: https://12factor.net