微服务:基本实践

在开始尝试并探索为成功实现微服务架构而必须掌握的实践之前,让我们简要地刷新一下对单片应用程序的理解。

单片应用

整体式 整体式应用程序被构建为一个单元,随着时间的推移,其尺寸会增加。 虽然功能的增加必然会导致系统复杂性的增加,但单片式体系结构却往往使该复杂性成倍增长。 其背后的原因部分是由于倾向于对所有用例强制实施的分层方法。 您从一个具有四个层次的设计开始; API,业务层(BL),数据访问层(DAL)和数据库本身。 建立后,您将制定规则,以所有层都被使用的方式开发所有新功能。 这是很合理的。 功能部件1通过API层接收请求,该请求传递到业务层,而业务层又到达数据访问层,以便它到达数据库。 一旦到达最低点,方向就会改变,从而产生响应。 数据库将一些数据返回到DAL,DAL将其传递到BL,然后从那里发送到生成响应的API。 听起来很合逻辑(有一阵子)。

以此方式开发了越来越多的功能,但是随着时间的流逝,事情不再是线性的。 方向很快就不再纯粹是垂直的,我们开始具有对角线关系。 单个API类开始调用多个BL类,这又可能需要调用多个DAL类并处理多个数据库实体。 交流不仅是垂直的,而且是对角线的。 来自多个类的越来越多的方法被调用,使代码越来越多。

整体特征

你们中的许多人此时会说,发生这种情况是因为没有完善的治理,并且可以通过更好的代码审查将其全部修复。 有时可以解决。 更多情况下,可以减少耦合。 人们开始采用捷径。 这样做是我们的本性,尤其是在面临紧迫的最后期限时。

每增加一项新功能,整体应用程序的复杂性就会增加,开发,测试和部署速度也会随之降低。 这是不可避免的。 代码库越大,开发所需的时间就越多,这是因为依赖关系的数量以及开发过程中需要考虑的事物数量都在增加。 类似的声明对测试和部署有效。 应用程序越大,每次发生更改时,我们就需要花费更多的时间来测试它。 这就是一些公司在敏捷方法论上苦苦挣扎的原因之一。 连续测试应用程序的成本太高,因此最终要进行测试(结果往往很惨)。 如果测试是手动的,则应用程序越大,需要投入的工时就越多。 另一方面,如果测试是自动化的,则应用程序越大,由于代码错误以外的其他原因(太多的依赖项,要设置的数据太多,等等)导致不稳定的测试失败的可能性就越大。 )。 架构是实现大多数eXtreme编程实践(如持续集成,测试驱动的开发,较短的开发周期等)的关键。

结果是我们在尝试应用更改时面临的困难增加了。 开发新功能会花费越来越多的时间。 重构开始变得越来越少,这是因为潜在的风险是事情会崩溃,因此,著名的短语经常重复出现; 如果有效,请勿触摸。 我们一天之内就能开发出的东西,需要一周的时间。 由于需要扩展,业务开始受到越来越多的影响。 它需要新功能,需要更大的团队,还需要能够增加系统的使用率。 但是,结果相反。 开发功能需要花费更多时间,大型团队的效率要比小型团队低,并且如果我们唯一的选择是将所有内容相乘,那么扩展应用程序的效率将不高。 将大型应用程序运行的服务器数量乘以这相当于高中毕业失败。 即使您侧接一两个主题,并愿意花更多的时间学习它们而受益,但您还是必须重复整个一年1 。 结果,即使您的问题只是数学,您也要花两年时间参加所有学科的课程。 处理这种情况的正确方法是参加额外的数学课。 评估您的表现不足的班级。

整体缩放

微服务,实践和工具

微服务都是关于拥有小型专用应用程序的。 它们应该是自治的,只有通过API的一个入口。 它们应彼此分离(API除外)。 这种去耦是通过物理隔离实现的。 如果它们在物理上是分开的,则不能从其他服务调用类和方法或函数。 最后,它们是垂直组织的。 它们代表业务功能或实体,而不是技术功能(例如,水平层)。 有关优缺点的更多信息,请查阅Monolithic Servers vs Microservices文章。 这篇文章的目的是探讨成功应用微服务架构必不可少的实践和工具。

连续交付或部署(CD)

随着微服务的出现,缩短了开发周期,从而缩短了产品上市时间。 与单片应用程序内部的等效功能相比,开发,测试和部署微服务所需的时间更少。 如果您想从速度的提高中完全获利,那么必须确保过程中没有瓶颈,CD可能是我们可以采取的最佳途径,这样我们才能以没有阻碍我们发布产品的方式工作尽早。 我有意跳过将持续集成(CI)归入这一组,因为尽管它确实提高了速度,但最后需要手动进行。 此外,CD将证明您值得挑战,因为所有其他实践也将需要高度自动化。

货柜

没有容器,您的环境将很快变得一团糟。 从一个(大型)应用程序切换到许多小型服务的部署意味着需要处理的事物数量成倍增加。 尽管使用单个应用程序服务器和很少的运行时依赖关系可能还不错,但如果微服务启用了它们的自由度,它们将大大增加这些依赖关系。 一种服务可能使用JDK 7,而另一种服务则可能会受益于JDK 8引入的流功能。一种服务可能仅使用nginx处理静态文件,而另一种可能需要应提供动态内容的应用程序服务器。 一个可以从关系数据库中受益,而另一个可以通过ElasticSearch更好。 这是我们要通过微服务实现的自由类型。 可以为当前任务自由选择最佳工具,框架,编程语言等。 价格带来的巨大优势是增加了运营成本。 直到最近,对于大多数组织来说,这个价格还是太大了。 随着Docker的出现,问题(大部分)已经得到解决。 不要在服务器上安装任何东西(Docker守护进程除外)。 而是将完全自给自足的服务打包并运行为容器。 这些容器内应有所有物品。 应用程序服务器,依赖项和运行时库,编译的代码,配置等。 我们要做的就是将服务打包为容器运行,并确保它们可以相互通信(稍后将进一步讨论该主题)。

配置管理(CM)

有人声称,如果所有部署都是使用Docker完成的,则无需进行配置管理。 我不敢苟同。 CM仍然是重要且必不可少的工具。 但是,CM应该执行的任务范围比以前要小得多。 例如,部署不应再由CM负责。 我们拥有更好的工具,从简单的工具(如Docker Compose)到更复杂的工具(如KubernetesDocker SwarmMesos) 。 无论选择如何,CM最多只能运行将执行这些工具之一的命令。 CM的真正范围应确保非常底层的功能正常运行。 您的操作系统是否已更新? 是否创建了所有系统用户? 我们是否正确设置了防火墙? 由于范围的这种变化,需要使用不同的CM工具。 我们需要ChefPuppet使用的客户端-服务器拉模型吗? 不,我们不。 我们需要复杂的Ruby语法吗? 不,我们不。 实际上,即使没有Docker,我也不认为这些工具很好。 他们以前很棒,但现在再也没有了。 那么替代品是什么? Ansible 。 它在某些方面和Chef and Puppet一样好,而在其他方面则更好。 SSH Push系统是比pull更好的原理。 这让我想知道,自从SSH诞生以来,就一直没有人想到过它。 长话短说,CM是必须的,而Ansible是我们今天可以找到的同类最佳工具。 随着RedHat最近的收购,Ansible必将被传统企业组织采用。

我几乎忘了提到管理应用程序配置的任务也应该不在CM工具的范围之内。 我们应该如何管理它们? 关键字是:服务发现。

服务发现

管理应用程序配置始终是一件容易的事。 即使出现了CM工具并有望解决该问题,我们仍在努力。 现在比以往任何时候都更加重要,因为我们不再期望(或多或少)具有静态配置。 配置变得越来越动态。 以缩放为例。 如果流量增加,我们应该增加运行服务的节点数。 一旦流量减少,我们应该缩小规模,让节点做其他事情。 这种类型的动态需要同样灵活的重新配置,这几乎是不可能的,并且肯定过于复杂,并且使用CM工具需要时间。 这就是服务发现的源头。我们不需要预先定义(服务X将在服务器Y和Z上运行),而是只需确保每个服务在部署时就宣布其存在。 该公告存储在某种形式的注册表中,并且可能需要该公告的任何其他服务使用。 这是一个相对简单的过程,并且工具数量不断增加。 注册您自己或有一个过程可以检测到您的存在,并将该数据存储在任何人都可以查询的高可用性和分布式注册表中。 Registrator是一个很好的解决方案,可以轻松地与etcdConsul之类的注册表结合使用。 放入诸如confdConsul Template之类的混合工具中,突然所有的配置都被存储起来,供需要它们的任何人使用,并创建正确的过程和配置文件。 最好的部分是,一切都是自动的,并且可以在任何规模下运行,无论是一台,几百台还是数千台服务器,并且服务不断在它们周围移动。

最后,受这种动态设置影响最大的服务是代理。

代理服务

甚至不要试图使微服务直接相互对话。 如果您已经熟悉Docker,则可能会认为在所有情况下使用链接都是一个好主意。 在某些情况下是,在大多数情况下不是。 通过1.9版中引入的Docker的网络改进,链接比以前更具吸引力,但仍不能消除对代理的需求。 设置nginxHAProxy服务,并确保每次部署新服务时都更新配置。 服务发现工具将为您做到这一点,并且代理将始终将所有请求重定向到目标服务的任意数量的实例。 剩下的就是以(几乎)总是向代理发出请求的方式开发服务。

通过这种方式,您可以开始针对零停机时间部署。

蓝绿色部署

蓝绿色部署是已经使用了很长一段时间,但直到最近才变得真正容易实现的另一件事。 该想法的主旨是与当前版本并行部署新版本,对其进行测试,直到您确定一切都能按预期进行,然后简单地将代理更改为指向新版本。 决不会有停机时间(至少不是由部署引起的)。 为什么以前这么难,现在很容易? 因为在单片应用程序占据整个服务器之前,我们需要将容量增加一倍。 因为在此之前,我们必须预先配置所有内容。 由于微服务的资源使用率较低,并且服务发现最终会更新代理服务,因此蓝绿色部署很容易完成,并且不会破坏您的预算,因为两种微服务版本都可以短暂地在同一台服务器上运行。

说到预算,群集和扩展也比以往任何时候都便宜。

聚类和扩展

我供职的大多数组织都浪费了很多资源,但始终需要越来越多的服务器。 例如,他们可能有五台服务器专用于一个大型应用程序,另外两台用于夜间运行的批处理任务。 这种分离看似很方便,但人们很容易发现白天应用服务器(或多或少)已被完全占用,而批处理服务器则大多处于空闲状态。 到了晚上,情况就会逆转。 最重要的是,当应用程序服务器面临繁忙的流量时,其内存几乎已全部占用,但CPU永远不会超过50%。 另一方面,批处理可能会占用大量CPU资源,并且不需要太多内存。 这是一个非常简化的映像,但要点是,如果每个服务器都专用于预定义的目的,则其资源将被部分浪费。 其背后的原因是我们大多数人习惯于将服务器与其用途相关联的关联。 我们甚至给他们起名字。 哦,是的,该应用程序在Gandalf(服务器名称)上运行,而那个应用程序在Mordor(服务器的另一名称)上安装。 但是,奇怪的是,我们对CPU的处理方式不同。 我们没有指定某些进程应该在第三个CPU上运行。 另一个例子是Java。 我们可能会为在JDK上运行的程序指定最小和最大内存,但是(不包括特殊情况)我们没有说在任何给定时刻应使用的确切内存量是多少。

我们应该改变管理服务器的方式,并将所有服务器视为一个数据中心或服务器场。 我们应该考虑所有内容的总和,并根据该信息确定部署位置。 对我们来说幸运的是,有一些工具可以做到这一点。 KubernetesMesosphere DCOSDocker Swarm只是我们可以使用的一些工具。 通过它们,我们可以将我们的服务和应用程序部署到数据中心内部没有足够资源来运行它的服务,而不是将其部署到特定服务器上。 该决定是基于容器的数量,可用内存,硬盘类型以及许多其他组合来决定的。 这些决策应不断进行重新评估,以便根据当前或预期的必要性对服务进行连续扩展和缩减。 一旦建立了这样的系统,不仅我们将获得前所未有的灵活性,而且基础设施成本也将急剧下降。

为了达到目标而缺少的要素之一是健康检查和自我修复系统。

自我修复系统

大多数用途都有某种形式的健康检查。 在应用程序级别,我们倾向于捕获异常并在问题发生时对问题做出反应。 您甚至可能拥有应用某些较新概念的应用程序,例如具有Akka的 actor,它们倾向于提供新的更好的方法来处理故障,更重要的是,从故障中恢复过来。 第二层检查通常是在系统层上,在该层上,我们倾向于不断验证应用程序是否已启动并正在运行。 最后,还有一个硬件级别检查,它使我们可以监视诸如内存,CPU,硬盘等资源。 Nagios是第二和第三级检查的常用工具之一。 有许多其他类似的问题,其中大多数都有两个主要问题。 首先,它们又大又笨重,可以用更轻巧的东西代替,同时利用服务注册表中的信息。 其次,也是更重要的问题是,诸如Nagios之类的工具倾向于简单地监视和通知潜在问题。 在它们下面,我们有一组响应这些通知的运算符。 服务器宕机,它们开始四处运行并执行一些过程,这些过程将使系统回到正确的状态。 人工操作人员的问题在于操作缓慢。 需要花时间做出反应并解决问题。 另一方面,如果实施了先前的建议,则所有可以解决问题的工具都已经到位。 如果由于某种原因服务停止运行(例如由于进程终止或整个服务器关闭),监视系统不仅应检测到故障,还应通过例如Docker Swarm重新运行部署,而后者又反过来,将其放置在数据中心内的某个位置。 在大多数情况下,操作员应该只收到一条通知,上面写着“出现错误并已解决。 继续玩纸牌游戏。” 听起来像科幻小说吗? 好吧,不是。 如果您重新考虑我们所说的所有工具,那么没有什么可以阻止我们这样做的。 每5秒ping服务一次,如果没有响应或响应不是200,请启动部署。 通过这些ping监视响应时间,如果响应时间超过500毫秒,则按比例放大。 工具在那里,我们只需要让它们完成工作即可。 例如,执行这些ping操作的监视工具可以很容易地由Consul本身(我们已经讨论过)。 我们可以使用其运行状况检查并在某些状态为紧急状态时运行部署。 您可能拥有一个自我修复系统,该系统既具有反应性(在发生故障后起作用)又具有预防性(在达​​到某些阈值时起作用)。 Mesos和Kubernetes之类的工具已经在软件包中包含了故障转移策略。

摘要

本文的简短版本如下。

  • 使用Dockerrkt将微服务打包到容器中。
  • 不要手动配置环境。 使用Ansible之类的CM工具为您做到这一点。
  • 不要手动或使用CM工具配置应用程序。 将服务发现与ConsulRegistratorConsul TemplateetcdRegistratorconfd组合使用
  • 使用代理服务(例如nginxHAProxy )(几乎)是发出请求的唯一方法(是从外部还是从您的一项服务到另一项服务)。
  • 通过采用蓝绿色程序来避免因部署而导致的停机时间。
  • 将所有服务器视为一个大实体。 使用KubernetesMesosphere DCOSDocker Swarm之类的工具来部署服务。
  • 不要将自己的职业花在监视工具的仪表板上。 设置一个自我修复系统,当出现问题或达到某个阈值时将重新启动部署。

我知道所有这些事情听起来都很令人生畏,但是一旦它们启动并运行,您就可以花时间在为组织带来真正价值的事情上。 您可以将时间和金钱用于开发可带来业务价值的功能,并让系统在提交代码后接管所有后续工作。

  1. 在您所在的国家/地区,学校的工作方式可能不同。 如果是这样,请想象一下,如果没有一个科目会导致整个一年的重复。

翻译自: https://www.javacodegeeks.com/2015/11/microservices-the-essential-practices.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值