从微服务开始(一):微服务的优势与注意事项

简介

目前,在没有提出术语“微服务”的情况下,是无法对原生云架构进行单独的讨论的。随着越来越多的开发人员和架构师考虑利用这种架构风格,出现了很多优秀的文章,但是有一些新的文章完全忽略了微服务的要点。一个典型的例子是,有的文档建议,将应用程序包构建的更小(“微”),就是微服务

本篇博客是四部系列文章中的开始,帮助大家更好的理解什么是微服务,并且如何高效的使用它们。在这篇介绍性文章中,我们将介绍微服务的优势,讨论一些在创建基于微服务的应用时会遇到的挑战。第二部分当中,我们将介绍如何将微服务和容器进行结合使用,如果利用编排和容器管理工具,比如Kubernetes。第三部分讨论微服务的设计原则和微服务DevOps最佳实践。该系列的最后一部分是介绍Oracle当前以及未来对支持基于微服务的应用所提供的令人兴奋的特性。

微服务的优势

在了解微服务为什么具有如此的吸引力之前,我们应该先看看微服务是什么。尽管对于微服务架构还没有标准,业内所公认的微服务架构需要遵循如下的所提的几个设计要点和特点:

通常,你会考虑使用微服务架构来设计由小型的自主服务组成的应用。这些服务是松耦合的,只通过API进行通信,复杂性也更低,它们通常只专注于应用中某个业务功能(有边界上下文)的单个功能。基本上,由服务组成的应用将会取代基于大型单一代码库的单体应用程序,每一个服务具有它自己的代码库和状态,能够由更小规模的敏捷开发团队进行独立的管理。这能够使企业对他们的应用的一部分使用更快、更敏捷的方式进行开发、部署和更新工作,因此能够对新的市场需求和竞争状况进行更及时更灵活的响应。Netflix和其他“生于云的企业”就是通过微服务架构获得成功的最佳代表。

下图展示了一个使用微服务架构创建的简单应用。

图1:一个基于微服务的应用,有三个微服务

随着快速的市场响应和敏捷性成为使用微服务架构的主要动力,最大的问题就是,为什么会有这样的敏捷性和速度?答案就是微服务的最主要的优势。

独立部署

对于大型的单体应用,快速可靠地部署会成问题。考虑这样的场景,你需要引入一个新的特性,比如为用户配置增加一个新的字段,或者简单的修复一个bug。单体应用通常都作为一个单一的整体应用进行创建和部署,在对整个应用的创建和测试时,要确保小的变化不会影响到应用的其他组件。整个应用必须也要被重新部署,包括所有其他没有变化的组件。不算应用的大小、技术和流程所需的事件,单单进行创建、部署和更新就要花费很多时间。

基于微服务的架构中,就像图1中所展示的,如果你遵循了松耦合的最佳实践,你只需要对需要进行特性变化或者关键bug修复的那个服务进行更新和部署。如果你对一个服务的修改需要进行回滚,它能够在不影响生产环境中其他服务的情况下完成。这使得让大型应用保持敏捷,并且能够更快和更频繁的进行部署更新成为可能。

独立扩展

在云端,应用通常是靠增加主机数量来实现扩展的,称之为实例。基本上,每一个应用会创建多个主机实例,每一个主机实例都带有一个应用实例,并且为这些实例提供负载均衡。在单体应用中,如果仅仅有一个应用特性需要进行额外的扩展,整个应用都需要被扩展,因此有更多的主机实例需要被添加,相比微服务模式,需要更高的成本。

微服务架构能够提供使每一个服务根据需要进行扩展的能力,并且将服务部署到与他们的资源要求更加匹配的实例。如果订单服务需要根据需要进行扩展,他能够在不需要对应用的其他组件服务进行扩展的情况下实现。如果配置服务需要更多的内存,只需要简单的将它部署到内存更多的实例上即可。它仍然能够将多个服务部署到相同的实例,但是我们有能力在我们的部署中更好的优化成本和规模。

不同的技术堆栈和冲突的依赖性

单体应用通常使用一种开发语言,在一种技术堆栈之上进行开发,经常会基于堆栈的特定版本。如果应用的一个组件希望使用技术堆栈的最新版本中的新特性,可能会因为应用中其他组件无法支持而不会去采用它。所以,在单体应用中,对更先进的技术的利用会严重的滞后。

使用微服务架构的应用是由独立的服务组成的,这些服务可以使用不同框架、不同版本的库,甚至完全不同的操作系统平台。这就可以让开发人员选择最合适的技术来实现功能特性,避免功能特性和库之间技术堆栈版本的冲突。

比如,图1中的配置服务可能会采用Java进行实施,使用到Elastic Search特性;同时订单服务使用Node.js,并且使用强一致性和报告特性的事务型数据库,比如Oracle数据库。开发人员甚至可以使用同一种语言的不同版本或者技术堆栈进行服务的开发,不需要担心依赖冲突。

使用微服务时的注意事项

在微服务架构带了很多好处的同时,你需要认识到的很重要的一点,你正在进入分布式计算的世界。分布式计算总是一个复杂的课题,微服务也不例外。在开始使用微服务时,有几件事你需要注意到。

复杂性增加

在微服务架构中,有很多可移动的组件,所以对服务的管理将变得更加复杂。相比于单节点应用的部署,你要部署成百上千的服务,还要让它们在一起无缝的工作。这需要服务注册和服务发现解决方案,以便一个新的或者更新的服务能够让自己被系统知道,能够被其他服务检测到。你也需要确保所有的服务都启动并且在运行当中,没有耗尽磁盘空间或者其他资源,并且保证足够的性能。所有的服务通常都会需要负载均衡,并且使用同步或者异步的消息发送来进行通讯。集群管理和编排工具会帮助你解决一些问题,但是也需要你了解这些工具是如何进行工作的。在这系列博客的第二部分,我们将更深入的了解集群管理和编排如何帮助微服务进行工作的。

网络拥塞和延迟

微服务用来通讯的API使用的是标准协议,比如HTTP,所以网络成为重要因素。想象一下在一个应用中有数百个服务,通常一个请求就会跨多个不同的服务,不难看出,如果网络方面没有给予足够的重视的话,将会对应用的整体性能造成多大的影响。另一个经常被忽略的地方是数据的序列化和反序列化。有时,相同的数据从一个服务传递到另一个服务,它会被序列化和发序列化多次,从而大大增加了网络的延迟。有几种模式可以使用,比如数据缓存和服务,来限制请求的数量。对于序列化问题,你可以使用高效的序列化格式,并且在整个服务框架中使用这个共用的格式。这可能会在服务间传递数据时减少一些步骤,不需要再次序列化。

数据一致性

因为每一个微服务通常都会有它自己的状态存储,所以你必须要面临分散数据所带来的数据一致性和完整性挑战。考虑下面的场景,订单服务所引用的数据在另一个服务当中,比如产品目录服务,你就需要维护该服务中的数据完整性。现在你在每个服务中都有一些相同的数据,必须要保证一致性;如果一个服务节点中的数据变更,其他节点中的数据必须一起进行变更。如果在产品目录服务中的数据被删除或者更新,比如有效产品项的数量,订单服务就需要知道这种变化。处理这种一致性挑战,以及诸如此类的数据一致性概念,可能很难得到正确的结果,但是幸运的是,这个问题已经被解决了。比如,你可以使用事件源或者通知服务之类的模式,将变化的数据发布给已经订阅这种变化和更新的数据消费服务。

容错和弹性

微服务应用的特性之一是,即便在发生灾难性故障时,它仍能够实现容错。由于在网络中存在很多微服务,因此,在微服务架构中,故障也更为普遍,也更具挑战性。你可能想知道,这是怎么发生的呢?因为微服务通常都运行在它们自己的进程或者容器当中,其他的微服务是不会直接影响到它的进程的。所以,一个坏的微服务怎么会击倒整个应用?我们来看个例子,如果一个微服务花费太长时间来进行相应,在服务调用中耗尽所有的线程资源,它就会引起整个调用链的级联故障。对故障进行合适的处理,也会对应用正常运行时间的SLA产生影响。我们假设你的应用需要有99.9%的正常运行时间的SLA,也就是说每个月只允许大约44分钟的停机。你的应用包含3个微服务,每个都提供99.9%的正常运行时间。每一个服务都有可能在不同的时间出现停止服务,你就会看到潜在的停机时间大约是132分钟,明显影响了整个应用正常运行时间的SLA。

要进行故障处理,让你的应用实现容错,你需要实现弹性模式,比如超时、重试、熔断机制和隔离机制,这对于开发人员来说都是非常具有挑战性的。

诊断

在微服务应用中,日志和追踪需要一个合理的策略。需要对日志聚合和分析进行认真的思考,因为微服务应用中有成百上千个服务,生成了大量的日志。此外,请求通常会跨越多个服务,所以,找到一种方法在整个系统中对请求进行标记非常重要,让你能够看清跨越所有服务的整个请求。这通常都是通过使用关联或者传递给所有下游服务的活动ID来实现的,每一个服务都会将这个ID写入它的日志。由于服务是由不同的团队开发的,所以确定一种统一的日志格式也很重要。微服务应用的总体诊断与调试是很有挑战性的,必须在一开始就计划好。在本系列的第三部分,我们将介绍一些诊断的最佳实践。

版本控制

在单体系统中,调用一个接口的代码通常与接口的实现部署在一起。接口的中断变更通常是在集成测试或者构建期间被捕获。在微服务世界中,一个微服务接口的变更不需要调用它的微服务立即进行处理,因为他们可能有不同的发布节奏。为了保证调用服务仍然能够按照预期进行工作,需要整个团队考虑并且认可服务版本控制技术。

DevOps

现金的DevOps,自动化和监控是微服务运营成功的关键。在生产环境中进行测试通常是一个目标,实现这个目标需要更多的强调监控,使我们能够快速的检测到异常和问题,并且根据需进行回滚。在自动化方面进行投资,使用诸如Blue-Green Deployment、Canaries、A/B Testing和特性标志等工具和最佳实践,非常重要。建立起一个定义良好的工作流,让开发和运营一起工作,带来敏捷、高质量的发布,非常有挑战性。本系列博客的第三部分将对DevOps的流程进行更详细的介绍。

总结

本文中我们介绍了使用微服务所带来的好处,解释了为什么微服务对很多企业有如此的吸引力。我们也介绍了基于微服务应用所带来的一些挑战。后续,我们将更详细的介绍如何应对这些挑战。下一部分,我们将介绍如何使微服务与容器一起工作,在微服务的世界里,诸如Kubernetes之类的角色编排和容器管理工具是如何工作的。

猜你喜欢

转载自blog.csdn.net/jiahao1186/article/details/84888893