2.4 DevOps工程师的故事:构建运行时的严谨性

对于DevOps工程师来说,微服务的设计关乎在投入生产后如何管理服务。编写代码通常是很简单的,而保持代码运行却是困难的。
虽然DevOps是一个丰富而新兴的IT领域,在本书后面,读者将基于4条原则开始微服务开发工作并根据这些原则去构建。这些原则具体如下。
(1)微服务应该是独立的和可独立部署的,多个服务实例可以使用单个软件制品进行启动和拆卸。
(2)微服务应该是可配置的。当服务实例启动时,它应该从中央位置读取需要配置其自身的数据,或者让它的配置信息作为环境变量传递。配置服务无需人为干预。
(3)微服务实例需要对客户端是透明的。客户端不应该知道服务的确切位置。相反,微服务客户端应该与服务发现代理通信,该代理将允许应用程序定位微服务的实例,而不必知道微服务的物理位置。
(4)微服务应该传达它的健康信息,这是云架构的关键部分。一旦微服务实例无法正常运行,客户端需要绕过不良服务实例。
这4条原则揭示了存在于微服务开发中的悖论。微服务在规模和范围上更小,但使用微服务会在应用程序中引入了更多的活动部件,特别是因为微服务在它自己的分布式容器中彼此独立地分布和运行,引入了高度协调性的同时也更容易为应用程序带来故障点。
从DevOps的角度来看,必须解决微服务的运维需求,并将这4条原则转化为每次构建和部署微服务到环境中时发生的一系列生命周期事件。这4条原则可以映射到以下运维生命周期步骤。
服务装配——如何打包和部署服务以保证可重复性和一致性,以便相同的服务代码和运行时被完全相同地部署?
服务引导——如何将应用程序和环境特定的配置代码与运行时代码分开,以便可以在任何环境中快速启动和部署微服务实例,而无需对配置微服务进行人为干预?
服务注册/发现——部署一个新的微服务实例时,如何让新的服务实例可以被其他应用程序客户端发现。
服务监控——在微服务环境中,由于高可用性需求,同一服务运行多个实例非常常见。从DevOps的角度来看,需要监控微服务实例,并确保绕过微服务中的任何故障,而且状况不佳的服务实例会被拆卸。
图2-6展示了这4个步骤是如何配合在一起的。
构建12-Factor微服务应用程序
本书最大的希望之一就是读者能意识到成功的微服务架构需要强大的应用程序开发和DevOps实践。这些做法中最简明扼要的摘要可以在Heroku的12-Factor应用程序宣言中找到。此文档提供了12种最佳实践,在构建微服务的时候应该始终将它们记在脑海中。在阅读本书时,读者将看到这些实践相互交织成例子。我将其总结如下。
代码库——所有应用程序代码和服务器供应信息都应该处于版本控制中。每个微服务都应在源代码控制系统内有自己独立的代码存储库。
依赖——通过构建工具,如Maven(Java),明确地声明应用程序使用的依赖项。应该使用其特定版本号声明第三方JAR依赖项,这样能够保证微服务始终使用相同版本的库来构建。
配置——将应用程序配置(特别是特定于环境的配置)与代码分开存储。应用程序配置不应与源代码在同一个存储库中。
后端服务——微服务通常通过网络与数据库或消息系统进行通信。如果这样做,应该确保随时可以将数据库的实施从内部管理的服务换成第三方服务。第10章将演示如何将服务从本地管理的Postgres数据库移动到由亚马逊管理的数据库。
构建、发布和运行——保持部署的应用程序的构建、发布和运行完全分开。一旦代码被构建,开发人员就不应该在运行时对代码进行更改。任何更改都需要回退到构建过程并重新部署。一个已构建服务是不可变的并且是不能被改变的。
进程——微服务应该始终是无状态的。它们可以在任何超时时被杀死和替换,而不用担心一个服务实例的丢失会导致数据丢失。
端口绑定——微服务在打包的时候应该是完全独立的,可运行的微服务中要包含一个运行时引擎。运行服务时不需要单独的Web或应用程序服务器。服务应该在命令行上自行启动,并通过公开的HTTP端口立即访问。
并发——需要扩大时,不要依赖单个服务中的线程模型。相反,要启动更多的微服务实例并水平伸缩。这并不妨碍在微服务中使用线程,但不要将其作为伸缩的唯一机制。横向扩展而不是纵向扩展。
可任意处置——微服务是可任意处置的,可以根据需要启动和停止。应该最小化启动时间,当从操作系统收到kill信号时,进程应该正常关闭。
开发环境与生产环境等同——最小化服务运行的所有环境(包括开发人员的台式机)之间存在的差距。开发人员应该在本地开发时使用与微服务运行相同的基础设施。这也意味着服务在环境之间部署的时间应该是数小时,而不是数周。代码被提交后,应该被测试,然后尽快从测试环境一直提升到生产环境。
日志——日志是一个事件流。当日志被写出时,它们应该可以流式传输到诸如Splunk或Fluentd这样的工具,这些工具将整理日志并将它们写入中央位置。微服务不应该关心这种情况发生的机制,开发人员应该在它们被写出来的时候通过标准输出直观地查看日志。
管理进程——开发人员通常不得不针对他们的服务执行管理任务(数据移植或转换)。这些任务不应该是临时指定的,而应该通过源代码存储库管理和维护的脚本来完成。这些脚本应该是可重复的,并且在每个运行的环境中都是不可变的(脚本代码不会针对每个环境进行修改)。
 
 
原文地址:https://www.cnblogs.com/mongotea/p/11973148.html