软件组织正在快速地实施云技术,但迁移始终是一个无法回避的挑战。哪些部分是需要你密切留意的?哪些应用程序更适合于进行迁移?如何对应用程序进行重构以适用于云端?经历了这一转变的先行者为我们留下了什么启示?在这一系列文章中,你将从那些在帮助企业成功地迁移至云环境方面富有经验的专家那里获得实用的建议。这一领域应得到高度关注,我们希望你也能够参与这方面的讨论。
软件企业正在实施云基础设施的道路上不断加速,随着这种转变的持续推进,理解在云环境中运行对于应用程序来说意味着什么,这一点也变得十分重要。
传统意义上,应用程序依赖于冗余的、并且高度优化的基础设施以维持高可用性及可靠性,而不是依赖于软件架构。其结果是基础设施的能力往往没有得到充分的发挥,那些额外的运行能力就意味着金钱的浪费。随着现代化的组织对于节约成本、提高效率以及改进灵活性的需求的浮现,这种浪费是不可接受的,也这是软件组织向云环境迁移的重要驱动力。
Cloud Native 应用
在云环境中运行的应用程序本身要承担起更大的责任,它的架构方式必须能够提高它的正常运行时间、容错性以及可伸缩性。虽然许多云提供商不断地宣传它们的服务是多么可靠,但真正的范式转变在于:正常运行时间的职责已经转移到应用程序的层面,取决于应用程序对基础设施的感知以及控制能力。对于要成为“cloud native”的应用来说,这一点是最基本的。
对 cloud native 的应用来说,首先,也是最重要的一点在于在架构与设计时必须考虑到故障的应对。Netflix 公司是在创建 cloud native 的应用方面得到业界高度评价的专家,他们经常在博客中提到如何为应对故障而进行设计。在这方面已经出现了许多优秀的模式与实践,不仅能够帮助你从意外的故障情况中进行恢复,还能够确保当意外发生时让应用程序能够优雅地退化。Netflix 提供了大量的工具对故障与延迟情况进行模拟,以帮助他们创建cloud native 的应用。
想要理解怎样架构与设计cloud native 的应用程序,阅读与学习十二要素方法是一种很好的上手方式。十二元素方法提供了一系列元素,可以在创建交付为服务的现代化软件时应用在任何编程语言中。
现在让我们来回顾一下十二元素原则中的部分内容,看看它是如何帮助我们架构cloud native 的应用的。“所有的进程都必须是无状态且无共享的”,无论是用于保存状态还是其它原因而存在的数据,它都会限制某个进程成为分布式并且轻易地实现水平伸缩的能力。这就意味着你在某个进程的架构中不应预期某个数据片段会被持久化,而是使用某种附加的服务在进程之外将所有数据进行持久化,例如某个数据库或其它数据存储系统。
另一个基本原则是“依赖应当被显式地声明并且进行隔离”。在实践中,这就意味着应用程序本身对于运行的环境是不可知的,除了已经显式声明的工具或库之外不会使用其它任何外部依赖。与依赖的定义与隔离相关的一点在于:配置文件中保存的内容对于每个执行环境都是独立的,例如开发环境与生产环境上的认证信息。无论是连接字符串、身份认证还是不同的主机名都应保存在某种类型的配置文件中,并与使用它的代码区分开来。以上只是一部分模式与实践的示例,为了让所创建的现代化应用能够适用于在云环境中进行部署,了解这些模式与实践是十分必要的。
你能做些什么
在开始下一个项目之前,请确保你和你的团队都已经充分地了解了什么是满足十二元素的应用,可以在十二元素应用网站上获得更多的信息。
现代化应用的未来
那么打造cloud native 应用的下一步是什么呢?在软件工程中,有些新兴的趋势与技术正在热火朝天的发展中。在 CenturyLink Labs ,我们已经开展了容器化方面的工作,对于容器在架构、分布式以及部署软件方面未来所扮演的角色进行了研究。容器正在变得越来越流行,在应用程序容器化之外,它就变得非常容易打包、发布并且随处运行。与传统的虚拟化技术不同,容器在应用程序层面提供了一个轻量级的虚拟化功能,因此它能够更充分地利用一点一滴的可用能力。
容器的另一个优点在于它们能够快速地启动与中止(次秒级),这样一来,只需简单地启动新的容器,就能够实现水平伸缩与故障恢复了。而快速启动与中止的能力正是十二元素应用的核心原则之一,即易处理性(disposability)。虽然容器并没有涵盖这方面的细节,但确实是因为容器的能力让易处理性的实现变得非常容易。
IBM 在一篇优秀的论文中对于虚拟机的性能与Linux 容器进行了详细的说明,如果你想要对容器与VM 的能力进行比较,可以在这篇论文中找到大量的细节对比。
容器承诺它们能够带来更快的速度、成本的节约以及灵活性。它们也为软件的架构带来了一些新的思想,例如使用短期的容器实现异步处理及工作流。如果你对容器在这方面的应用感兴趣,请参考一下CenturyLink Labs 发布的 dray.it 项目。
你能做些什么
如果你还没有开始学习容器技术,网上有大量的资源可以参考,例如 Docker 以及 CenturyLink Labs 的博客。也可以考虑在你的公司内部进行一次概念验证,以获得一些实际的动手经验。
不可变基础设施及部署
由于容器的出现,使得另一个新兴的实践在软件工程社区内产生了大量的讨论与争辩,这就是不可变基础设施与部署的概念。这一实践是指永远不要改动运行中的基础设施或应用程序,而总是将应用或基础设施销毁后再重新生成。但是为什么要这么做呢?
从根本上说,原因是十分简单的:比起创建新的内容,对已有的内容进行变更并追踪这些变更要更加困难,它要求你对于某个复杂系统中的一切变量都充分理解并且具有控制权。对于小型应用程序来说这一点或许问题不大,但大多数现代化的复杂应用程序都是通过特性与补丁的无数次迭代混合而成的。在这种复杂应用中进行手动变更几乎是不可能的。因此,要点在于整个系统必须处于一种“已知”的状态,具体来说就是一种经过了充分测试的环境,并且你能够在任意一种环境中轻易地重建整个系统。
你能做些什么
如果你在配置管理工具(Puppet、Chef、Ansible 等等)方面还没有投入过多的精力,那么你可以考虑学习不可变基础设施与部署的实践,这种方式或许更易于让系统保持在一种已知的状态,同时对于部署的速度、应用的稳定性与可测试性都有所帮助。
微服务
我们最后讨论的一种趋势是基于微服务架构的兴起。微服务是一种面向服务的模型,应用程序中的每一种细分功能都被分解为一个独立的自包含程序(即服务)。这意味着多数现代 web 应用都至少需要操作 10 个以上的微服务。容器再度体现出它的不凡功用,它能够简化应用初始时的生成操作,并提供了高度的封装能力。
不过,微服务并非分布式应用架构的一剂灵丹妙药,人们最终意识到这一架构通常只在某些情况下能够发挥作用。它主要针对的情形是应用程序本身与团队非常庞大,并且大多数开发者都在一个代码库中进行工作的复杂性已经开始影响到了团队的生产力。如果你也遇到了这种问题,那么将你的架构重构为微服务或许是个好点子。在开始设计下一个特性的时候,不要将它加入已有的代码库中,而是将其分解为一种微服务。然后逐渐让你的应用逐渐演化,从一体性架构或面向宏服务的架构分解为微服务应用。
将系统分解为较小的块,这种做法比起一体性的应用更易于进行错误诊断、变更以及迭代。而不同的成员也可以专注于不同的微服务所提供的特定功能。
你能做些什么
如果你也体会到大型的代码库与大型团队所带来的问题,那么多学习一些微服务方面的知识。可以在这个演讲中了解微服务的优势与陷阱:“ Gilt 的大规模化:从一体性 Ruby 应用转为分布式 Scala 微服务架构”。对于任何一种新兴的架构范式来说,都需要理解其中的权衡之处,微服务也不例外。在 Martin Fowler 的一篇优秀博文“一体性优先”(Monolith First)中,他谈到了以微服务的方式设计一个全新的应用时存在的各种陷阱。
学习与探索
了解新兴技术、模式或实践的权衡之处是十分重要的。世上没有免费的午餐,虽然有些技术或实践能够在某些方面带来一些改进,但很可能会让其它方面变得更加复杂。以上所谈到的新趋势大多还不具备成熟的工具。软件企业应当始终对新兴技术的权衡做到充分理解,通过在实际应用中的概念验证,对这些技术进行持续地测试、探索与学习。同时软件企业还需要设计专门的人员,让他们专门负责了解这些新兴技术,以及它们潜在的益处与影响。
在未来的几年中,cloud native 应用、应用容器、不可变基础设施与微服务等技术注定将对现代化应用的创建、交付与运维产生实质性的影响,它们将对改进每个商业机构的基础成本、效率以及灵活性起到关键的作用。
关于作者
Ross Jimenez 相信伟大的人造就了伟大的技术。他在 web 方面的经验已经超过 20 年,曾经在 Hewlett-Packard、Compaq Computer 与 Sandia National Laboratories 等公司担任过技术领导职位。他目前在 CenturyLink Innovation Labs 担任工程总监。
本文是 InfoQ__ 的“云迁移”系列文章中的一篇,你可以通过RSS订阅获取关于新文章的通知。
查看英文原文: Transitioning to Cloud Native Applications and Beyond
评论