微服务革命:应用,数据的容器化

原文作者:Luke Marsden . 阅读全文需要大约17分钟

近几年来,微服务架构和基于容器的虚拟化技术已经越来越多地在软件开发社区中被提及。Adrian Cockcroft就是这方面公认的极有远见者之一,他在2014年欧洲的Dockercon上就提到微服务和Docker的结合将是一枚利器( 引PPT原文39页:the combination of microservices and Docker a “disruptor”),即微服务架构与Docker结合使用时,其优势将得到成倍的放大。微服务鼓励软件开发者将软件解耦为多个小的功能部件(部件运行时可能会出错)。容器技术承接了这一愿景,将软件与软件依赖的硬件部分分离开来。这使得我们在保证应用的高质量时,应用的构建和维护更加方便快捷。

在讨论微服务时,存储问题常常会被我们忽略,但是它却是大多数应用的核心。在本文中,我们将讨论微服务的优点以及我们为什么不能像数据库一样容器化有状态的服务,而这一点大大削减了微服务架构的优势。

更好,更快,更省:现代软件开发中的微服务

虽然微服务这个概念中的“微”没有精确的衡量标准,但是如果我们思考一下这个架构为什么以及现在怎样被使用,可以意识到其为软件团队带来的两大好处:敏捷与弹性。下面让我们分别讨论这两点:

敏捷

当我们提到敏捷的软件开发方案时,通常指的是其快速变更的能力。我们上面提到的Adrian Cockcroft,也是Netfilx的前云服务架构师、微服务组件设计者提到: 当我们构建的应用中基本所有的元素都是为了让我们可以比其他任何人更快地做出决策或者构建出某项事物时,快速的响应将成为重要的需求。

敏捷性是微服务架构最受欢迎的特性之一。根据杰出的微服务著作家与从业者 Martin Fowler 所说,敏捷性是来源于将运行中的系统解耦为“一套小型的服务”。

通过限制对系统其它部分的依赖这一特性,微服务架构可以更快地进行变更,从而响应bug或者新的需求。这与传统的一体式架构中“应用中一小部分的变更需要重新构建并部署应用整体”的现象是截然相反的。

弹性

Martin Fowler在他的文章中指出,由于微服务架构分布式的特点,每个独立的服务都需要“通过设计从而可以容忍其他服务的失败”。对于像Netflix这样基础设施遍布全球的公司来说,处理服务的失败和故障是常态。为了解决这一挑战,Netflix发布了著名的SimianArmy测试他们的系统,SimianArmy可以杀死部分运行中的软件从而测试系统是否可以在这些情况下正常运行。

微服务结构天然的分布式特性使这一点可以实现。系统中的服务要满足以下条件:

  1. 它们的依赖是远程解决的——这使得我们可以通过扩展不同的基础架构来缓解风险。每个服务不需要考虑它是与在下一个虚拟机、下一个机架甚至另一个大陆上的进程进行通信。
  2. 它们的依赖会有失败的可能——这迫使开发人员在开始的时候就要考虑服务的弹性问题,而不是将这一需求作为后续思考来完成。

Contino的CTO认为,“微服务虽然是构建弹性软件服务的强大手段,但是微服务并不是“免费的午餐”。和其他众多的架构一样,微服务架构的实现也可会有很多问题。除此之外,由于服务的通信是通过网络连接完成的,网络延迟将成为重要的考虑因素。尽管如此,微服务也广受 Netflix, Spotify, Twitter 和 Gilt 等公司的关注。正如Martin Fowler自己所说:“…对于我们的许多同事( ThoughtWorks )来说,这已经成为构建企业级应用的默认范式。”

走进容器的世界

微服务鼓励软件开发者将他们的服务解耦为许多容错的功能部件。如果做得好的话,这将为应用带来敏捷性和弹性的优势。

虽然微服务技术已经是复杂工程构建的新兴趋势,但是随着在2013年 Docker Inc.(曾称DotCloud)发布了Docker(开源工具,基于容器的虚拟化技术),微服务被推动到了更广泛的工程领域。

Docker的发布使人们对容器的兴趣和使用激增,而在此之前容器是一个只有最复杂的组织才能够使用的工具,像Google的所有东西就都是在容器中运行的。Adrian Cockroft在2014年欧洲的DockerCon主题演讲中总结如下:“在2014年,Docker几乎没有人关注。但是在2015年,每个人都感觉到了Docker的存在。”

Docker的吸引力主要有两方面:快速、可移植。

快速

与每次启动都必须启动全新操作系统实例的虚拟机不同,Docker容器通过在主机的操作系统上共享内核来承载docker容器。这意味着Docker容器可以在几百毫秒的时间内完成启动、停止的操作,而不需要像虚拟机一样等待几分钟的时间。

其带来的提速意味着使用Docker容器构建的软件系统可以实现比之前基于VM的解决方案更高的灵活性,原先基于VM实现的微服务架构也是如此。此外,根据2014年IBM的研究报告所述“容器几乎在所有的情况下都可以达到与虚拟机相同甚至更好的性能”,意味着“容器化”的应用可以实现与虚拟机和裸机相媲美的性能。

可移植性

使用基于VM的解决方案时,可移植性通常限制在一个云提供商的可用区域内或者企业在自己的数据中心内运行应用的场景。这是因为不同的云提供商通常会使用不同的虚拟机格式。虽然使用 Packer 这样的工具可以帮助我们构建虚拟机映像来在不同的云上运行,但是这需要大量的额外工作。实际上,这导致用户常常被绑定在一个平台上。其中的更多原因是我们下面要解决的问题。

Docker容器“一次写入,到处运行”的设计使开发者可以摆脱这一限制。工程和运维团队可以将他们的基础架构部署到不同的云提供商上,只要其上的Docker守护进程还在运行,那么就可以在其中运行他们的应用。与云提供商的解耦为IT团队提供了更大的自由度,我们可以通过选择多个提供商来进一步提升软件解决方案的弹性。

微服务 + Docker容器:1 + 1 > 2

还记得我们开头说Adrian Cockcroft在2014年欧洲的Dockercon上就提到微服务和Docker的结合是一枚利器,现在我们已经很清楚这么说的原因了,与Docker结合使用的微服务架构的优势确实可以得到成倍的放大。微服务架构鼓励我们将软件分解为更小的容错的功能块,这为我们带来了敏捷性和弹性;Docker将软件与底层硬件分离开来,为我们提供了比基于VM的解决方案更好的可移植性与更快的速度。

状态

虽然从Google Trends 上可以看到人们从2014年起对微服务Docker容器的关注程度在不断增长,但是他们的增长也面临着一个重要的阻碍,即我们下面将讨论的无状态应用设计问题。

无状态应用设计

微服务架构的构建者会尽可能选择无状态的服务而不是有状态的服务。无状态应用设计的主要好处是我们可以通过增添或者删减服务实例来动态响应时间,而这一过程中无需对应用进行大幅的变更或者重新配置。举例来说,如果负载突然增加,那么可以填加更多的无状态web服务器来应对;当一个无状态服务异常结束时,我们可以通过简单的替换来解决。通过无状态的服务,我们可以更加容易地去实现敏捷性和弹性。

有状态的服务

尽管有着无状态应用设计的趋势,但是在很多系统中,状态的出现是无法避免的。任何保存数据的系统都必须管理状态,而且有状态的组件的数量和种类会随着时间不断增长。MongoDB. PostgreSQL. RabbitMQ. Redis. Cassandra. Riak. MySQL. ElasticSearch. 现代开发人员使用的数据服务也是如此。随着微服务架构成为常态,开发人员和架构师正在不断尝试将不同的数据服务与他们的应用不同组件进行结合。需要解析数十亿级的日志记录?ElasticSearch。工作队列?Redis 或 RabbitMQ。用户注册?MySQL 或 MongoDB。所有这些问题都可能发生在同一个应用当中。

那么问题来了,在现代化的无状态应用架构中,状态实际上是处处可见的——而且这些状态需要被管理。

如何处理这些状态?

在Docker的爆炸式增长之下,很多关键问题还没有来得及解决或者还只有部分答案;其中最大的问题就是状态问题,它也常被称为持久化问题和存储问题。

在刚开始的时候,一些人认为由于状态的问题,Docker不可能被广泛采用。虽然他们的预测没有成功,但是状态的问题也没有得到明确的答案。Xebia Labs的产品管理副总裁Andrew Phillips在8 Questions You Need to Ask About Microservices, Containers & Docker in 2015一文中将“存储”排在了第一位。

由于通过Docker来管理有状态的服务(如数据库)的信息或者解决方案都很少,软件开发社区在使用容器时很大程度上会忽略状态问题。在大多数的情况下,容器仅仅用来处理应用程序中的无状态部分;任何有状态的服务(如数据库)会作为"Backing Services"来在正常的应用生命周期之外进行管理。虽然这个解决方案很受欢迎,但它将数据——一个应用的核心变成了其他人的问题(somebody else’s problem,见链接文章的评论区)。它严重消减了整个应用通过完全采用基于容器的微服务获得的好处。

在容器中运行有状态服务的好处

一条链的强度取决于其中最脆弱的一环。如果工程和运维团队希望通过微服务架构和Docker实现最大程度的弹性和敏捷,他们需要让他们的有状态服务像无状态服务一样快速与可移植,而不是通过将它们丢在控制力更弱的应用之外进行管理。基于这个想法,我们将有状态服务引入到基于容器的微服务架构究竟可以获得怎样的具体优势呢?

优势1:开发环境与生产环境等价

Barry Boehm 和 Philip N. Papaccio首先指出在开发进程之后捕获的错误将花费更大的成本去修复【1】。在这篇1988年的论文当中,作者认为在“现场”发现的bug的修复成本将是开发过程中修复相同bug成本的50-200倍。Barry Boehm and Victor R. Basili在2001年的文章中进行了跟进研究并得出了一个并不是那么严重的结果——五倍【2】,尽管数值大小上有着差异,但是两者得到的整体趋势是一致的。

最近的研究指出工程师修复在生产环境中bug花费的时间是在code review和单元测试中修复bug成本的40倍,是系统测试中修复成本的5倍。

无论是哪一份研究报告,有一点是明确的,那就是bug的捕捉越早越好,但是开发者如何做到这一点呢?假设工程师已经维护了一套可以由开发者运行的自动化测试套件,但是可能还有一件事情会为IT组带来困扰,那就是测试时没有实现开发环境与生产环境的等价

当开发环境与线下环境等价(dev/prod parity)背后的主要观点——缩减代码开发环境dev与代码运行/用户使用环境prod之间的差异被纳入Heroku的Twelve-Factor App manifesto之后得到了广泛的认同。

理由很简单,如果代码在一个环境中测试然后在另一个不同的环境中运行,那么原来的测试结果很可能是无效的,团队可能需要更多的精力来修复之后可能在生产中出现的问题。

由于容器所需的内存相比VM有了大幅下降,开发者可以在他们的开发机上运行更多的容器。想象一下如果你在生产环境上要运行10个VM;而在普通的开发机上运行10个VM几乎是不可能的,无论他们有多小。

而为了让开发人员能够进行本地测试,他们必须通过一些捷径来实现,比方说在开发环境中使用SQLite,然后祈祷在实际的生产环境中也可以一切正常。然而Heroku的JVM语言负责人Joe Kutner明确指出过: " SQLite  ≠ MySQL  ≠ PostGresQL " 每个这样的“捷径”的使用都会削减线上环境与线下环境的等价性,伴随而来的还有在后期交付阶段更昂贵的错误成本。

在开发机上运行10个Docker容器是很容易的,这为开发人员在开发环境中模拟生产环境来实现两者之间的等价带来了可能。

这个一般原则通过使开发环境和生产环境之间保持一致(包络应用的所有部分,像数据库这样有状态的服务也应该在本地完成测试,就像和在线上运行一样)提升了提前发现bug的可能性。

优势2:避免被供应商绑架

随着越来越多的公司开始使用基于云的方案来增强或者取代其内部的基础架构,被单一的供应商绑架成为了越来越令人担忧的问题。在2014年对全球超过650名的IT专业人员的调查中发现近91%的受访者计划在未来的一年当中部署新的基于云的产品。超过77%的受访者在同一阶段有在不同云提供商上的部署计划。

在容器出现之前,在多个云上运行应用是很棘手的。互为竞品的云服务商通常会采用不同的虚拟机格式,这使得在多个云上运行所需的配置管理成本非常昂贵。

由于Docker容器已经包含了运行时环境和运行应用所需的操作系统,因此只需要在底层的基础架构上运行Docker即可。此时软件公司只需要为每个所需的云提供商维护相应支持Docker的VM镜像即可。

Docker的一次编写,到处运行将终结被供应商绑架的担忧。但是如果你仅仅为应用的无状态化部分使用了容器,那么这个优势将不复存在。

除此之外,由于数据库在物理上靠近应用服务器时的效能是最高的,所以如果数据并没有实现容器化就意味着当你无法容忍两者由于物理上带来的延迟时无状态的应用服务器移动能力将受到限制。而一旦数据库与其中的数据实现了容器化,即使操作问题需要迁移整个数据中心,我们也可以通过容器来在数据中心之间移动容器化的整个应用。

由于长距离移动大规模数据集带来的挑战,这可能并不是运维团队希望定期完成的操作。但是如果将上面提到的整个应用的迁移换成局部的迁移,通过实现这一点可以极大地减少团队对任何单一云提供商的依赖,这是极具吸引力的一点。

优势3:缩减运维人员的操作面

Cloudscaling Inc.的CTO和联合创始人 Randy Bias 在2012年的演讲当中,将Bill Baker著名的"pets vs. cattle"(宠物 vs. 奶牛)比喻应用在了服务器之上。"你为它们分别命名,如果它们'生病'了,那么你需要进行诊断让其恢复健康",这就是系统管理员对待"宠物"式的服务器时需要的管理方式。这就导致了操作者不仅仅需要知道它们正在管理的服务器,而且还需要知道部署在他们上面的软件分别是什么。这种维护服务器的方式将导致大量雪花式服务器(他们的行为是独特、微妙的,并且很难进行变更)的产生。

充满雪花式服务器的数据中心带来的一个结果就是开发人员与运维人员之间的敌对关系,因为两者的期望是冲突的。开发者希望可以最大化变更因为他们需要发布最新的软件来证明自己的工作,而运维人员希望最小化改动因为他们需要维持已有软件的稳定性来证明自己的工作是有效的。

这个僵局的解决方案分为两个方面。在团队组织方面,Devops运动尝试将开发团队与运维团队更紧密地结合起来以调整他们的工作绩效评定方案。同时在技术上,运维人员必须改变他们看待服务器的方式,“你给他们编号,当它们出现问题时,你需要像射杀牛一样清除掉他们”,Bias解释道。

这种实现将首先导致大量寿命较短的服务器的诞生,也被称作"凤凰式服务器",因为在每次软件变更时他们都无可避免地需要重新部署,所以它们也被称作"不可变服务器"。Docker容器的出现使不可变服务器成为了可能。

像对待牛一样处理服务器使Netflix等公司在处理大规模的服务器时也可以保证其灵活性与弹性。“标准化、可移植的部署方式节省了大量的时间和精力”,Adrian Cockroft如此说道。这种方案为运维人员提供了小而明确的管理平面,相反地也意味着,为有状态和无状态的应用维护不同的工具集将是在向错误的方向上行进。

Google云平台的全球解决方案负责人Mike Ward在15年时就曾提到:“如果你现在正在构建应用,你可以通过购置主机然后在本地进行虚拟化,也可以借助公有云或者私有云,除此之外还有大量可用的Pass解决方案。你将有多达六种的方式来打包部署你的应用!通过容器对格式进行标准化,你可以在不同的提供商上获得一致的体验...”

从这一优势来看,如果仅仅对无状态化的应用程序组件进行容器格式的标准化,那么标准化的优势将会削减,因为至少有两个系统需要管理:有状态的和无状态的。

通过在所有的应用组件(包括有状态的组件和无状态的组件)之间提供小而明确的操作平面,我们将有机会进一步改善开发人员和运维人员之间的敌对关系。通过为整套应用提供一套一致的工具,原本混乱的局面将得到改善。

优势4:不牺牲多租户的前提下达到接近裸机的性能

"你认为推动技术业务决策的驱动力是什么?"在2014年DockerCon上IBM的Boden Russel被问到这样一个问题,他的答案是:“收益,收益,收益。”

虚拟机的一个主要卖点就是它往往可以更高效地利用底层硬件,这个指标也被称作'密度' ( density )。原因是显而易见的,因为运维部门常常喜欢在服务器中对应用进行隔离,如果这种隔离体现在物理机上就意味着服务器常常会处于空置的状态,但是消耗的成本并不会减少。而虚拟机可以实现底层硬件的共享,从而实现更高的密度和更低的成本,也就代表着更多的收益。

但是虚拟化并不是没有任何问题,尤其是倾向于I/O密集型操作的数据库的性能会大打折扣。这也是为什么大多数的服务提供商会将服务器单独作为服务进行售卖,而且使用的往往是容器而不是虚拟化。比如说在Rackspace设计其基于云的关系型数据库"Rackspace 云数据库"时,它选择了通过Linux容器而不是虚拟机来实现。虚拟机"对要求数据库正常运行的用户带来了性能损失,但用户并不关心提供商是否使用了虚拟化技术",J.R. Arredondo在2013的白皮书上这样解释。

在白皮书当中还概述了使用容器的原因以及这么做带来的好处,Arredondo解释说传统的两种虚拟化选项——硬件虚拟化和半虚拟化会将Rackspace带入"第22条军规"的两难之中。硬件虚拟化可以提升用户操作系统的性能但是需要更多的整体资源。半虚拟化可以获得更好的性能但是会降低可移植性。

"基于容器的虚拟化所使用的资源开销往往都很小,一般在2%左右,而传统的硬件虚拟化往往会使用可用CPU资源的10%-30%",Arredondo解释说。

通过采用基于容器的存储方案,Rackspace能够从两个方面上提高营收:密度的提升降低了底层硬件资源的消耗;性能的提升使他们的产品在市场上更具竞争力。

Rackspace的实例不仅仅说明了服务提供商为什么应当选取基于容器的解决方案。因为随着越来越多的企业依赖软件来为客户提供服务,优化基础架构、提升产品性能将成为服务提供商们的共同目标。而在容器中运行数据库有助于提升营收。

结论

本文讨论了容器技术的爆炸式的增长以及其如何改变了尖端公司的构建、交付、维护软件的方式。当其与微服务技术融合时,容器技术将以前所未有的规模提供强大的敏捷性。

但是在这个巨大转变的初期,一些挑战常常被人们忽略,尤其是存储方面。越来越多的公司意识到了容器化技术和微服务架构的好处,但是如果存储解决方案不能与容器技术一起使用,微服务革命带来的好处将无法得到充分发挥,而且这一挑战也会变得越来越严峻。

引用文献

1 . Boehm, Barry W. and Philip N. Papaccio. 'Understanding and Controlling Software Costs,' IEEE Transactions on Software Engineering, v. 14, no. 10, October 1988, pp. 1462-1477

2 . Beohm, Barry and Victor R. Basili. 'Software Defect Reduction Top 10 List,' Computer, v. 34, no. 1, January 2001, pp 135-137.

本文的版权归 ArrayZoneYour 所有,如需转载请联系作者。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏阮一峰的网络日志

云主机是什么?

一、共享主机和云主机 从互联网诞生至今,大部分站长都是从"共享主机"(shared hosting)开始学习建站的。所谓"共享主机",就是一台服务器上有许多网站...

47711
来自专栏SDNLAB

老网工:再谈SD-WAN的几种典型部署和实践

2112
来自专栏Java架构师学习

阿里P8架构师详说分布式架构的应用原理简介什么是分布式?分布式和集群的关系计算机发展历史分布式架构发展的里程碑架构的发展演变过程如何把单击扩展到分布式

作为一名架构师,我们要专业,要能看懂代码,及时光着臂膀去机房,也能独挡一面!及时同事搞不定问题,或者撂挑子,你也能给老大一个坚定的眼神:不怕,有我在!还能在会议...

1235
来自专栏企鹅号快讯

管理混合云的5个秘诀

如今,“混合”与复杂性似乎是同义词,企业通常担心在IT部门增加更多的工作量,却没有额外的资源来应对。当企业试图找出解决新出现的混合问题的最佳方法时,他们会以安全...

1846
来自专栏Golang语言社区

微服务架构崛起 能否成为下一代云计算?

复杂度可控、灵活可扩展与独立部署 IT架构一直从all in one到近两年热门的微服务架构,技术不断进步,微服务架构模式(Microservice Arch...

2765
来自专栏SDNLAB

基于SDN和NFV的云安全体系——云安全防护体系建设与特点

随着云计算、虚拟化、SDN以及NFV等新技术的发展,传统硬件设备对应用所需要的灵活性、动态性、可调度性支持的缺失,使人们更多的希望通过新技术来解决这些问题,基于...

3497
来自专栏腾讯云数据库(TencentDB)

腾讯云数据库智能化海量运维的建设与实践

作者介绍:鲁越,腾讯云数据库架构师团队负责人,主要负责腾讯云数据库MySQL、Redis、Oracle等数据库售前架构、运维、调优等工作,曾就职于网易和尼比鲁。

97537
来自专栏腾讯云数据库(TencentDB)

不知道CynosDB为什么叫真正的云原生数据库?腾讯云数据库的产品欧巴今天跟你聊一聊

注:本文摘自2018年11月22日腾讯云数据库CynosDB新品发布会的演讲实录。随着互联网信息的发展,大家也对云这个词汇也不是特别陌生了,作为全球首选的云服务...

1111
来自专栏JAVA高级架构

京东架构专家分享京东架构之路

京东咚咚架构演进 咚咚是什么?咚咚之于京东相当于旺旺之于淘宝,它们都是服务于买家和卖家的沟通。 自从京东开始为第三方卖家提供入驻平台服务后,咚咚也就随之诞生了。...

3519
来自专栏BestSDK

管理混合云的5个秘诀

如今,“混合”与复杂性似乎是同义词,企业通常担心在IT部门增加更多的工作量,却没有额外的资源来应对。当企业试图找出解决新出现的混合问题的最佳方法时...

3165

扫码关注云+社区