微服务简介

我们先来看看你为什么要考虑使用微服务。

构建单体应用

让我们假设你们要开始制定一个全新的出租车招标程序,旨在与Uber和Hailo进行竞争。经过一些初步会议和需求收集之后,您将手动或者使用Rails,Spring Boot,Play或Maven附带的生成器来创建一个新项目。这个新的应用程序将具有模块化的六角架构,如下图所示:

应用程序的核心是业务逻辑,它由服务定义,领域对象和事件的模块实现。围绕核心的是与外部世界接口的适配器。适配器的示例包括数据库访问组件,生成和使用消息的消息传递组件以及暴露API或实现UI的Web组件。

尽管有一个逻辑上的模块化架构,应用程序被打包和部署为一个整体。实际格式取决于应用程序的语言和框架。例如,许多Java应用程序打包为WAR文件并部署在诸如Tomcat或Jetty之类的应用程序服务器上。其他Java应用程序作为自包含的可执行JAR打包。类似地,Rails和Node.js应用程序被打包为目录层次结构。

以这种风格写的应用是非常常见的。它们易于开发,因为我们的IDE和其他工具专注于构建单个应用程序。这些应用程序也很容易测试。您可以通过简单地启动应用程序并使用Selenium测试UI来实现端到端测试。单体应用程序也易于部署。您只需将打包的应用程序复制到服务器即可。您还可以通过在负载均衡器后面运行多个副本来扩展应用程序。在项目的早期阶段,它运作良好。

迈向单体应用的尽头

不幸的是,这种简单的方法有很大的局限性。成功的应用程序随着时间的增长最终变得很大。在每个冲刺期间,您的开发团队都会执行更多的故事,当然这也意味着添加了许多代码行。几年后,您的小而简单的应用程序将成长为一个怪异的整体。为了给出一个极端的例子,我最近与一个开发人员交谈过,他正在编写一个工具来分析数百万行代码(LOC)应用程序中数以千计的JAR之间的依赖关系。我敢肯定,多年来开发人员一直在努力创造这样一个野兽。

一旦您的应用程序成为一个庞大而复杂的整体,您的开发组织可能处于一个痛苦的世界。任何敏捷开发和交付的尝试都将踉跄前行。一个主要问题是应用程序变得异常复杂。它太大以至于对任何一个开发人员来说很难完全理解。因此,正确修复错误和实现新功能变得困难和耗时。此外,这往往是一个向下的螺旋。如果代码库难以理解,那么更改将不会正确。你最终会遇到一个可怕的,不可理解的"大泥球"。

应用程序的规模也将减缓发展。应用程序越大,启动时间越长。例如,在最近的调查中,一些开发人员报告启动时间长达12分钟。我也听说过启动时间长达40分钟的应用程序的轶事。如果开发人员经常需要重新启动应用服务器,那么他们当天的很大一部分时间将会花在等待上,而且他们的生产力会受到影响。

大型复杂的单体应用程序的另一个问题是它是持续部署的障碍。今天,SaaS应用的最先进的技术就是每天将变更推到生产环境中。这对一个复杂的整体应用非常的困难,因为您必须重新部署整个应用程序才能更新其中的任何一部分。我之前提到的漫长的启动时间也不会有帮助。此外,由于变更的影响通常没有被很好的理解,因此您可能需要进行广泛的手动测试。因此,持续部署是不可能做到的。

当不同的模块具有相冲突的资源需求时,单体应用程序也可能难以扩展。例如,一个模块可能会执行CPU密集型图像处理逻辑,并且理想地部署在Amazon EC2 Compute Optimized实例中。另一个模块可能是内存数据库,最适合EC2内存优化实例。但是,由于这些模块部署在一起,您必须妥协选择硬件。

单体应用的另一个问题是可靠性。由于所有模块都在同一进程中运行,因此任何模块中的错误(如内存泄漏)都可能会导致整个过程失效。此外,由于应用程序的所有实例都相同,所以该错误将影响整个应用程序的可用性。

最后但不是最终,单体应用程序使得采用新的框架和语言变得非常困难。例如,我们假设您使用XYZ框架编写了200万行代码。重写整个应用程序以使用较新的ABC框架将非常昂贵(在时间和成本上),即使该框架更好。因此,采用新技术是一个巨大的障碍。您在项目开始时所做的任何技术选择都被困扰。

总结一下:您有一个成功的关键业务应用程序已经成长为一个怪异的整体,很少开发人员(如果有的话)能够理解它。它是使用过时,非生产性技术编写的,这使得聘请有才华的开发人员变得困难。应用程序难以扩展,不可靠。因此,敏捷开发和应用交付是不可能的。

那么你能做些什么呢?

微服务 - 解决复杂性

许多组织,如亚马逊,eBay和Netflix,都通过采用现在称为“微服务架构”模式解决了这个问题。而不是构建一个单一的怪异的单体应用程序,而是将应用程序分解成一组较小的互连服务。

服务通常实现一组不同的特征或功能,例如订单管理,客户管理等。每个微服务都是具有自己的六角架构的小型应用程序,包括业务逻辑以及各种适配器。一些微服务将暴露由其他微服务或应用程序客户端所要使用的API。其他微服务可能会实现一个Web UI。在运行时,每个实例通常都是一个云虚拟机或一个Docker容器。

例如,前面描述的系统的可能分解如下图所示:

应用程序的每个功能区域现在都由其自己的微服务实现。此外,Web应用程序被分为一组更简单的Web应用程序(例如一个用于乘客,一个用于我们的出租车中的司机)。这使得为特定用户,设备或专门用例部署不同体验更容易。

每个后端服务公开REST API,大多数服务都使用其他服务提供的API。例如,司机管理使用通知服务器告诉潜在的行程给一个可用的司机。 UI服务调用其他服务以呈现网页。服务也可能使用异步的基于消息的通信。

本系列后面将会详细介绍业务间通信。 一些REST API也暴露给司机和乘客使用的移动应用程序。然而,应用程序不能直接访问后端服务。相反,通信由称为API网关的代理来协调。 API网关负责负载均衡,缓存,访问控制,API测量和监控等任务,可以使用NGINX有效实现。文章的后面系统将介绍API网关。

微服务架构模式对应于Scale Cube的Y轴缩放,Scale Cube是优秀的“可扩展性艺术”的3D可扩展性模型。另外两个缩放轴是X轴缩放,其中包括在负载均衡器之后运行应用程序的多个相同的副本以及Z轴缩放(或数据分区),其中请求的属性(例如,主键的一行或一个客户的身份)用于将请求路由到特定的服务器。

应用程序通常将三种缩放方式一起使用。 Y轴缩放将应用程序分解为微服务,如本节第一个图所示。在运行时,X轴缩放运行负载均衡器后面的每个服务的多个实例,以获得吞吐量和可用性。某些应用程序也可能使用Z轴缩放来对服务进行分区。下图显示了在Amazon EC2上运行的Docker如何部署行程管理服务。

在运行时,Trip Management服务由多个服务实例组成。每个服务实例都是一个Docker容器。为了高可用,容器在多个云虚拟机上运行。服务的前面是一个负载均衡器,如NGINX,可以跨实例分发请求。负载均衡器也可以处理其他问题,如缓存,访问控制,API测量和监视。

微服务架构模式会显著影响应用程序与数据库之间的关系。而不是与其他服务共享单个数据库模式,每个服务都有自己的数据库模式。一方面,这种方法与企业级数据模型的想法不相符。而且,这通常会导致一些数据的重复。但是,如果您希望从微服务中获益,则每个服务都具有数据库模式是至关重要的,因为它确保松耦合。下图显示了示例应用程序的数据库体系结构。

每个服务都有自己的数据库。此外,服务可以使用最适合其需要的一种数据库,即所谓的通晓的持久性架构。例如,司机管理,司机发现附近的潜在乘客必须使用支持高效地理位置查询的数据库。

表面上,微服务架构模式类似于SOA。通过这两种方法,架构由一组服务组成。然而,思考微服务架构模式的一个方法是,SOA没有商业化和Web服务规范(WS- *)及企业服务总线(ESB)易被欺骗的部分。基于微服务的应用程序支持更简单,轻量级的协议,如REST,而不是WS- *。他们也可尽量避免使用ESB,而不是在微服务器本身中实现类似ESB的功能。 微服务架构模式还拒绝SOA的其他部分,例如规范模式的概念。

微服务的优点

微服务架构模式具有许多重要的优点。首先,它解决了复杂性的问题。它将一个怪异的整体应用程序分解成一组服务。虽然功能总量不变,但应用程序已分解为可管理的块或服务。每个服务都有一个明确界定的RPC或消息驱动API的边界。微服务架构模式实施了一个模块化水平,实际上使用单体应用代码基础实现非常困难。因此,个人服务的开发要快得多,易于理解和维护。

第二,这种架构使每个服务都能够由专注于该服务的团队独立开发。开发人员可以随意选择任何技术,只要该服务符合API合同。当然,大多数组织都希望避免完全无政府状态并限制技术选择。然而,这种自由意味着开发商不再有义务使用在新项目开始时存在的可能过时的技术。在撰写新服务时,他们可以选择使用当前的技术。此外,由于服务相对较小,因此使用当前技术重写旧服务变得可行。

第三,微服务架构模式使每个微服务都能独立部署。开发人员不再需要协调部署本地服务的变更。这些变化可以在测试后立即部署。例如,UI团队可以执行A / B测试,并快速迭代UI更改。 微服务架构模式使得持续部署成为可能。

最后,微服务架构模式使每个服务都可以独立调整。您可以仅部署满足其容量和可用性限制的每个服务的实例数。此外,您可以使用最符合服务资源需求的硬件。例如,您可以在EC2 Compute Optimized实例上部署CPU密集型图像处理服务,并在EC2内存优化实例上部署内存数据库服务。

微服务的缺点

就像弗雷德·布鲁克斯(Fred Brooks)近30年前所写的,没有任何银子弹。像其他技术一样,微服务架构也有其缺陷。一个缺点是名称本身。术语microservice过度强调服务规模。事实上,有些开发者主张构建极细粒度的10-100 LOC服务。虽然小型服务是最好的,但重要的是要记住,它们是一种手段,而不是主要目标。微服务的目标是充分分解应用程序,以便于敏捷应用程序开发和部署。

微服务器的另一个主要缺点是由于微服务应用程序是分布式的系统,从而有相应的复杂性。开发人员需要选择和实现基于消息传递或RPC的进程间通信机制。此外,他们还必须编写代码来处理部分失败,因为请求的目的地可能很慢或不可用。虽然这些都不是火箭科学,但它比通过语言级方法/过程调用模块互相调用的单体应用程序复杂得多。

微服务的另一个挑战是分区数据库架构。更新多个业务实体的业务交易是相当普遍的。由于存在单个数据库,所以这些交易在单体应用程序中实现是微不足道的。但是,在基于微服务的应用程序中,您需要更新不同服务所拥有的多个数据库。使用分布式事务通常不是一个选项,而不仅仅是因为CAP定理。许多今天高度可扩展的NoSQL数据库和邮件代理都不支持它们。您最终不得不使用最终的一致性方法,这对开发人员来说更具挑战性。

测试微服务应用程序也要复杂得多。例如,使用诸如Spring Boot之类的现代框架,编写一个启动单体Web应用程序并测试其REST API的测试类是不重要的。相反,服务类似的测试类将需要启动该服务及其所依赖的任何服务(或至少为这些服务配置存根)。再次,这不是火箭科学,但重要的是不要低估这样做的复杂性。

微服务架构模式的另一个主要挑战是实现跨多个服务的更改。例如,我们假设您正在实施一个需要更改服务A,B和C的故事,其中A依赖于B和B取决于C.在单体应用程序中,您可以简单地更改相应的模块,整合更改,并一次性部署。相比之下,在微服务架构模式中,您需要仔细规划和协调对每个服务的更改。例如,您将需要更新服务C,然后更新服务B,然后再次服务A.幸运的是,大多数更改通常仅影响一个服务,需要协调的多服务更改相对较少。

部署基于微服务的应用程序也复杂得多。单一应用程序简单地部署在传统负载均衡器后面的一组相同的服务器上。每个应用程序实例都配置有基础架构服务(如数据库和消息代理)的位置(主机和端口)。相比之下,微服务应用通常由大量服务组成。例如,根据Adrian Cockcroft的说法,Hailo有160个不同的服务,Netflix有600多个服务。每个服务将有多个运行时实例。更多的移动部件需要配置,部署,扩展和监控。此外,您还需要实现一项服务发现机制(稍后讨论),使服务能够发现需要与之通信的任何其他服务的位置(主机和端口)。传统的基于故障单和手动操作的方法无法扩展到这种复杂程度。因此,成功部署微服务应用程序需要开发人员更好地控制部署方法,并实现高度自动化。

自动化的一种方法是使用现成的PaaS,如Cloud Foundry。 PaaS为开发人员提供了一种轻松部署和管理其微服务的方法。它使他们免于采购和配置IT资源等问题。同时,配置PaaS的系统和网络专业人员可以确保遵守最佳做法和公司政策。自动部署微服务的另一种方法是开发您自己的PaaS。一个典型的起点是使用诸如Kubernetes的聚类解决方案与Docker等技术结合使用。在本系列的后面,我们将介绍基于软件的应用交付方式,如NGINX,它可以轻松处理缓存,访问控制,API计量和微服务级别的监控,可以帮助解决这个问题。

总结

构建复杂应用本质上是困难的。单体架构只适用于简单轻便的应用程序。如果您将其用于复杂的应用程序,您将最终陷入痛苦的世界。尽管存在缺点和实施难题,但微服务架构模式是复杂且不断发展的应用程序的更好选择。

在随后的文章中,我将介绍微服务架构模式各个方面的细节,并讨论诸如服务发现,服务部署选项以及将单体应用程序重构为服务的策略等主题。

本文分享自微信公众号 - IT技术精选文摘(ITHK01),作者:Chris Richardson

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2017-09-05

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 分布式系统关键技术之服务调度

    服务关键程度要通过对业务的梳理来发现。服务依赖关系用Spring Cloud的一套方法就能够非常好的解决,但是千万不要出现循环依赖,解决方式是通过第三方的消息队...

    用户1263954
  • 将单体应用重构为微服务

    微服务重构概述 将单体应用程序转换为微服务的过程是应用程序现代化的一种形式。这是几十年来开发人员一直在做的事情。因此,在将应用程序重构为微服务时,有一些方法可以...

    用户1263954
  • 快速正确的搭建一个微服务架构需要了解的那几个点

    用户1263954
  • 微服务 —— 你需要付出什么?又能有何收获?

    如果您阅读过我的文章 —— 微服务中的语义扩散,您可能会识得此标题。本文是那篇文章的一个延续,其目的是强调,只有当我们付出足够的努力来处理我们将要面对的组织和分...

    StoneDemo
  • 平台服务将成通往云计算的要道

    迄今为止关于云计算的大部分讨论都还只是集中于把应用程序迁往云计算的话题上。虽然云计算服务的增长速度是比较高的,但是这一发展态势甚至都没有让云计算相关开支占...

    静一
  • 为什么要使用微服务

    单体模式所有的功能打包在一个包里,包含了 DO/DAO,Service,UI等所有逻辑。

    分母为零
  • 微服务架构体系——它适合您的软件开发吗?

    “Microservice architecture provides a range of technical benefits that contribut...

    程序你好
  • 云计算,构建智能App和快速部署的关键

    2006年Amazon Elastic Compute Cloud作为第一个主流商业云服务公开亮相,2007年苹果公司推出iPhone。Amazon Elast...

    APICloud
  • 微服务和传统中间件平台

    微服务与部署在中间件平台(esb、应用服务器)上的传统服务有何不同?什么是微服务体系结构模式,它解决了什么问题?本文将讨论所有这些重要的主题,并描述如何管理、管...

    程序你好
  • 干货 | Node.js 在转转的微服务实践(一)

    微服务是一种架构风格,一个大型复杂软件应用由一个或多个微服务组成。系统中的各个微服务可被独立部署,各个微服务之间是松耦合的。每个微服务仅关注于完成一件任务并很好...

    五月君

扫码关注云+社区

领取腾讯云代金券