单片应用

用外行术语来说,整体应用程序是将应用程序的全部功能打包为单个单元或应用程序的地方。 该单元可以是JAR,WAR,EAR或其他一些归档格式,但是它们都集成在一个单元中。 例如,一个在线购物网站通常由客户,产品,目录,结帐和其他功能组成。 另一个例子是电影院。 这样的应用程序通常包括放映预订,添加/删除电影,门票销售,累积电影积分和其他功能。 对于单片应用程序,所有这些功能都将作为一个应用程序实现并打包在一起。

Movieplex7是这样的规范Java EE 7示例应用程序 ,其主要功能如下所示:

微服务,整体和NoOps

打包为WAR时,此应用程序如下所示:

微服务,整体和NoOps

档案库由一些构成UI的网页组成。 类实现业务逻辑,持久性,支持Bean等。最后,有一些配置文件定义了数据库连接,CDI配置等。

更具体地说,WAR的结构如下:

微服务,整体和NoOps

在这种WAR结构中,网页位于绿色框中,所有类位于橙色框中,配置文件位于蓝色框中。

该应用程序在某种程度上是模块化的,因为所有类通过不同的功能整齐地组织在包中。 网页和配置文件也遵循类似的模式。

整体应用的优势

这种应用程序样式具有一些优点:

  1. 众所周知 :到目前为止,这通常是构建应用程序的方式。 它易于概念化,所有代码都放在一个地方。 现有的工具,应用程序服务器,框架,脚本中的大多数都能够处理此类应用程序。
  2. 对IDE友好 :可以轻松为此类应用程序设置开发环境,例如NetBeans,Eclipse或IntelliJ。 IDE通常旨在轻松开发,部署,调试,分析单个应用程序。 遍历代码库很容易,因为代码库在一起。
  3. 易于共享 :具有所有功能的单个存档可以在团队之间以及在部署管道的不同阶段之间共享。
  4. 简化的测试 :成功部署应用程序后,所有服务或功能都将启动并可用。 这简化了测试,因为没有其他要等待的依赖关系才能开始测试。 该应用程序可用,在这种情况下,所有功能都可用,或者该应用程序根本不可用。 两种情况下都简化了访问或测试应用程序的过程。
  5. 易于部署 :易于部署,因为通常需要将一个存档复制到一个目录中。 部署时间可能会有所不同,但是过程非常简单。

单片应用的缺点

到目前为止,Monolith应用程序对我们的服务一直很好,并且很可能会在未来几年中继续运行。 像Etsy这样的网站每月有6000万访问者,每月页面浏览量为15亿,并且是作为一个大型整体构建/部署的。 他们将整体方案发挥到了极致,每天使用一个大型应用程序进行50次部署。 不幸的是,大多数公司并非如此。

无论模块如何模块化,随着团队的不断壮大,经验丰富的开发人员的离开和新人员的加入,应用程序范围的扩大,访问应用程序的新方法的增加,一个整体的应用程序最终将开始崩溃。 以跨越了多年经验和团队的任何整体应用程序为例,整个代码库看起来就像是一个臭虫 这就是软件演化的方式,尤其是在有交付压力的情况下。

让我们看一下整体应用程序的一些缺点

  • 有限的敏捷性 :对应用程序的任何微小更改都意味着完全重新部署了档案。 考虑用例,其中只需要更新应用程序中的一项功能,例如预订或添加/删除电影。 即使应用程序的其他部分没有更改,这也将要求重新构建并重新部署整个应用程序。 这意味着,如果开发人员想要查看在其工作区中进行快速更改的影响,则必须等待整个应用程序的部署。 即使不是故意的,但这可能需要在应用程序的不同功能之间紧密结合。 可能并非总是如此,尤其是当多个开发人员正在处理该应用程序时。 这降低了团队的敏捷性,并降低了交付新功能的频率。
  • 连续交付的障碍 :此处使用的示例应用程序很小,因此重建和部署归档文件所花费的时间不会太多。 但是现实生活中的应用程序会更大,并且部署时间可能令人沮丧且漫长而缓慢。 如果对应用程序进行单个更改将需要重新部署整个应用程序,则这可能会成为频繁部署的障碍,从而阻碍了连续部署。 如果您正在为移动应用程序提供服务,而用户一直在期待最新的超酷新功能,则这可能是一个严重的问题。
  • 被技术栈“卡住” :在开始开发应用程序之前,应评估并确定此类应用程序的技术选择。 团队中的每个人都必须使用相同的语言,持久性存储,消息传递系统,并使用类似的工具使团队保持一致。 但这就像在圆Kong中安装一个方形钉一样。 MySQL是否适合存储图数据库? Java是构建前端响应式应用程序的最合适的语言吗? 在不丢弃或重写现有应用程序的重要部分的情况下,通常不可能在中间阶段更改技术堆栈。
  • 技术债务 :“不间断,不解决”的方法在开发的软件中非常普遍,对于单片应用程序更是如此。 这很方便,可以使应用程序保持运行状态。 糟糕的系统设计或编写不好的代码很难修改,因为应用程序的其他部分可能正在以意想不到的方式使用它。 除非对其进行重构,否则系统的软件熵会在一段时间内增加。 通常,这样的应用程序是由团队维护的,这些团队要维持与创建该应用程序完全不同的代码库。 这增加了应用程序的技术负担,使以后重构应用程序变得更加困难。

什么是微服务?

为了满足快速发展的业务需求,对敏捷性,灵活性和可伸缩性的需求不断增长,因此强烈需要更快,更高效地交付软件。

认识微服务!

微服务是一种软件架构样式,需要对应用程序进行功能分解。 整体应用程序分为多个较小的服务,每个服务都部署在其自己的存档中,然后使用标准的轻量级通信(例如,基于HTTP的REST)组成单个应用程序。 微服务中的术语“微”并不表示服务中的LOC,它仅表示范围仅限于单个功能。

我们已经使用微服务已有几年了。 考虑一下一个简单的移动应用程序,它可以告诉您酒店的等级,查找目的地的天气,预订酒店,找到前往酒店的路线,找到附近的餐厅等等。 该应用程序可能使用不同的服务,例如Yelp,Google Maps,Yahoo Weather API等来完成这些任务。 每个功能都有效地作为独立服务运行,并在此单个移动应用程序中组合在一起。 Forrester的四层参与平台也凸显了移动应用的爆炸式增长及其对不断增长的业务需求的支持,服务是其中的关键部分。

让我们看看基于微服务的应用程序的特征是什么。

微服务的特征

让我们看一下使用微服务构建的应用程序的特征。

  • 领域驱动设计 :使用Eric Evans定义的领域驱动设计原则,可以实现应用程序的功能分解。 这不是破坏应用程序的唯一方法,但肯定是非常普遍的方法。 每个团队负责围绕该领域或业务功能构建整个功能。 构建服务的团队包括所有开发人员,因此遵循全栈开发方法,并且包括用户界面,业务逻辑和持久性方面的技能。
  • 单一责任原则 :每个服务应对功能的一部分负责,并且应该做到这一点。 这是SOLID原则之一,Unix实用程序已经很好地证明了这一点。
  • 显式发布的接口 :每个服务都发布一个显式定义的接口,并始终遵守该接口。 消费服务仅在乎该接口,而对消费服务没有任何运行时依赖性。 这些服务在域模型,API,有效负载或某些其他约定上达成一致,并且仅使用该约定进行通信。 可以引入该接口的更新版本,但是以前的版本将继续存在,或者更新的服务向后兼容。 您不能通过更改合同来破坏兼容性。
  • 独立部署,升级,扩展,替换 :可以独立部署和重新部署每个服务,而不会影响整个系统。 这样可以轻松升级服务,例如添加更多功能。 每种服务还可以按照可扩展性Art中的定义,分别在X轴(水平重复)或Z轴(面向查找的拆分) 上缩放 只要发布了完全相同的合同,该服务甚至底层技术堆栈的实现都会发生变化。 这是可能的,因为其他服务仅依赖于已发布的接口。
  • 潜在的异构/多语言 :一个服务的实现细节应该与另一服务无关。 这样可以使服务彼此分离,并允许构建服务的团队选择最适合它们的语言,持久性存储,工具和方法。 需要在RDBMS中存储数据的服务可以选择MySQL,而另一个需要存储文档的服务可以选择Mongo。 不同的团队可以选择Java EE,NodeJS,Python,Vert.x或对其最有效的工具。
  • 轻量级通信 :服务之间使用轻量级通信进行通信,例如REST over HTTP。 这本质上是同步的,因此可能存在一些潜在的瓶颈。 另一种机制是使用支持异步消息传递的发布-订阅机制。 可以在其中使用满足需要的任何消息传递协议,例如AMQP,STOMP,MQTT或WebSocket。 提供可靠的异步结构的简单消息传递实现(例如ActiveMQ)非常适合此类用法。 同步和异步消息传递的选择非常针对每种服务。 他们甚至可以结合使用两种方法。 同样,协议的选择对于每个服务都是非常特定的,但是对于每个构建服务的团队来说,都有足够的选择和独立性。

Netflix公司是一个典范微服务和一些 物品 公布 他们的收养微服务的。 netflix.github.io上提供了支持其架构的各种实用程序。

微服务的优势

  • 易于开发,理解和维护 :微服务中的代码仅限于业务的一项功能,因此更易于理解。 IDE可以非常轻松地加载小型代码库,并保持开发人员的生产力。
  • 比整体启动速度更快 :每个微服务的范围都比整体范围小得多,因此存档也更小。 结果,部署和启动速度更快,从而使开发人员保持生产力。
  • 可以轻松部署本地更改 :可以独立于其他服务部署每个服务。 开发人员可以轻松进行服务本地的任何更改,而无需与其他团队进行协调。 例如,可以通过更改基础实现来改善服务的性能。 结果,这保持了微服务的敏捷性。 这也是CI / CD的重要推动者。
  • 独立扩展:每种服务都可以根据需要使用X轴克隆和Z轴分区进行独立扩展。 这与可能具有非常不同的要求但必须一起部署的单片应用程序完全不同。
  • 改进故障隔离 :行为异常的服务(例如内存泄漏或数据库连接未关闭)只会影响该服务,而不是整个单体应用程序。 这样可以改善故障隔离能力,并且不会使整个应用程序崩溃,仅仅是整个应用程序的一部分。
  • 没有任何堆栈的长期承诺 :开发人员可以自由选择最适合其服务的语言和堆栈。 尽管组织可能会限制技术的选择,但是您不会因过去的决定而受到处罚。 它还可以使用更好的语言和技术来重写服务。 这样就可以自由选择技术,工具和框架。

微服务似乎可以解决很多软件问题。 它们起到了很好的作用,但绝非易事 这些操作需要大量的操作开销, Infoworld的这篇文章清楚地指出了这一点。

使用微服务时,一些技术债务注定会从开发人员转移到操作人员,因此您最好有一支精干的开发人员团队

这非常关键,因为现在您的一个整体已拆分为多个微服务,并且它们必须彼此通信。 每个微服务可能使用不同的平台,堆栈,持久性存储,因此将具有不同的监视和管理要求。 然后,每个服务都可以在X轴和Z轴上独立缩放。 每天可以多次重新部署每个服务。

微服务和NoOps

这对您的基础结构提出了其他要求。 这些通常放在一起并称为NoOps 从本质上讲,这些是一组服务,可为部署应用程序提供更好的过程,并使它们保持运行状态。

  • 服务复制 :每个服务都需要复制,通常使用X轴克隆或Y轴分区。 每个服务是否需要构建其逻辑以进行扩展? 例如,Kubernetes提供了一种使用Replication Controller轻松复制服务的好方法。
  • 服务发现 :多个服务可能正在协作以提供应用程序的功能。 这将需要一项服务才能发现其他服务。 在服务短暂的云环境中,可能会棘手,并且可能会向上和向下扩展。 因此,解决服务所需的服务是所有其他服务的通用功能。 服务需要在中央注册表中注册,其他服务需要查询此注册表以解决​​所有依赖性。 Netflix EurekaEtcdZookeeper是该领域的一些选项( 更多详细信息 )。
  • 弹性 :无论您进行多少测试和多努力,软件都会发生故障。 关键问题不是“如何避免失败”,而是“如何应对失败”。 这在微服务中尤为突出,在微服务中,服务遍布Internet。 对于服务自动采取纠正措施并确保不影响用户体验很重要。 迈克尔·尼加德(Michael Nygard)的书Release It! 引入了断路器模式来处理软件弹性。 Netflix的Hystrix提供了这种设计模式的实现( 更多详细信息 )。
  • 服务监视 :分布式系统最重要的方面之一是服务监视和日志记录。 例如,如果服务正在消耗意外的资源,则这可以采取主动措施。

重构为微服务

微服务也并不意味着您需要丢弃现有的应用程序。 在大多数情况下(99.9%?),您不能丢弃该应用程序。 因此,您必须构建一种有关如何使用微服务重构现有应用程序的方法。 但是,您需要将整体程序带到可以进行重构的阶段。 分布式大泥球突出显示:

如果您无法构建整体,那么什么使您认为微服务才是答案?

重构可能并非易事,但从长远来看,它具有很多好处,这在Infoworld先前引用的文章中也有强调:

重构大型整体应用程序(使用微服务)可以等同于大笔付款(用于减少技术债务)……您可以一次偿还一项服务的技术债务

整体的功能分解非常重要,否则与基于微服务的应用程序相反,它会成为分布式整体。

未来的博客

随后在blog.arungupta.me上的博客将展示如何使用微服务重构现有的Java EE应用程序。

其他问题将在后续博客中得到解答……。

  • 与SOA有何不同?
  • REST是交换数据的唯一方法吗? 什么消息协议?
  • 微服务是否简化/需要CI / CD?
  • 它与容器和DevOps有什么关系? 运行微服务是否需要容器?
  • 微服务是否有任何标准?
  • 我们是否正在将问题推向业务流程?
  • PaaS在启用微服务方面扮演什么角色?
  • 如何利用现有投资?
  • 微服务成熟度模型

翻译自: https://www.javacodegeeks.com/2015/04/microservices-monoliths-and-noops.html

相关文章: