10个坏漫画中的春天云

通过约翰·卡内尔(John Carnell)的著作《 Spring Microservices in Action》 (主题,而不是可怕的图片) 启发,通过一些相当糟糕的图纸快速浏览了组合的Spring Cloud / Netflix OSS微服务堆栈。

使用微服务构建设计良好的应用程序可能需要大量的成熟度。 服务发现,负载平衡和妥善处理故障等方面实际上是强制性的,但实施起来可能很麻烦。

Spring Cloud汇集了许多陈旧的工具,这些工具有助于简化分布式系统的许多核心模式,使其更易于连接和管理。 更具体地说,这可能涉及Consul,Zookeeper和Netflix OSS堆栈之类的技术。

现在,我们将通过可怕的图纸,通过利用Spring Cloud和相关工具来检验一些可用的模式。

Netflix OSS

Netflix OSS堆栈支持此处提供的大量功能。 Netflix的工具集支持服务发现,负载平衡,容错和网关路由功能,尽管完整的堆栈功能远不止这些。 在下面的图片中,我标记了我们稍后将要检查的特定库,并提供了一些有关其一般用途的注释。

使用Spring Cloud进行配置管理

上世纪末,美国宇航局向火星发送了一个轨道器,目的是调查这颗红色星球,以了解其水历史,并寻找证据表明那里曾经有生命。 经过十个月的艰苦跋涉,飞船抵达目的地,只是为了灾难降临,它在距离原先计划的行星表面近105英里处飞行后,在火星大气层中燃烧。 后来发现,其原因是由于两个独立的开发团队对整个系统使用的部队存在误解。 一方面,洛克希德·马丁公司的推进工程师使用了标准的磅力表示法。 但是,在太空工程中,常用的单位是牛顿,并且NASA工程师没有想到在集成组件时会出现任何不匹配的问题。 一磅力大约是4.45牛顿,相差足以引起灾难。

那么这与配置管理有什么关系呢? 好吧,这是一个单一事实来源的重要性的相当原始的例子,以及系统中各个组件之间的错误通信如何导致灾难性的结果。 这里的工作原理适用于分布式系统中的服务-最特别地,在这种情况下,与那些服务的配置以及配置漂移的概念有关。 让我们看一下这个的定义:

配置漂移是一种现象,由于手动进行的临时更改和更新以及一般的熵,随着时间的流逝,基础架构中正在运行的服务器变得越来越不同。

DZone dzone.com/articles/configuration-drift

微服务的实例应该完全不明显,并且可以完全替换。 将一项独特的配置引入一项服务的机会可能会导致生产设置中出现意外问题,并且与服务的单个实例相关联的任何类型的属性/配置文件都可以提供这种机会。

这是集中配置策略可以提供帮助的地方。 所有服务都指向单一的事实来源,因此不太可能在它们之间出现配置差异。 作为第二个附加功能,能够更改一条信息以立即影响所有家属的功能可以简化分布式应用程序中的常规配置管理。

Ribbon&Eureka的服务发现!

分布式系统的另一个重要方面是首先如何将所有这些运动部件实际连接在一起! 当然,在服务启动时静态配置一组地址很容易,但是如果这些端点之一消失或变得不正常怎么办?

尤里卡! 它的合作伙伴Ribbon旨在帮助解决此问题。 在服务启动时,它会向中央Eureka服务注册。 这样,任何从属服务都可以通过此中心点找到与谁交谈。

Eureka通过推荐其运行状况检查API来保持对服务实例的标签,以确保该服务实例可用并乐于提供。 如果发现实例不可用或正在报告问题,则将其从工作列表中删除。

功能区使这种安排的客户端变得简单。 它是一个与Eureka保持联系的请求方库,以跟踪充当特定功能的地址。 它为位置透明的引用抽象了物理地址,我们可以在代码中使用该引用来将我们的服务与任何上游的资源分离。

Hystrix成功失败

Netflix的Hystrix是一个容错库,旨在防止整个分布式系统中的级联故障-几乎肯定会在某个时刻发生故障。

通常,应用程序体系结构的设计足以应付大规模故障,这意味着服务器完全停机等情况。 复制数据库以使它们可以丢失集群成员,并且仍然不受阻碍。 API调用通常跨应用程序的多个相同实例进行负载平衡,以避免任何单点故障。

但是,较小规模的故障或QoS的下降螺旋通常不太好处理。 具体而言,间歇性故障和上游响应的等待时间不断增加等方面无法很好地解决,因此请求最终会备份并淹没系统。

断路器

断路器的功能类似于电气断路器。 但是,它没有检测电涌,而是试图防止由于大量请求而使陷入困境的上游服务压力越来越大的情况。 它通过监视远程服务调用的生命周期来做到这一点。 如果等待时间开始增加,则会切断连接以保护其依赖性。

一旦断开连接,断路器的行为就会有所变化。 随着呼叫继续进入断路器所属的服务,将测试上游端点,直到我们看到恢复了良好的服务为止,此时断路器再次闭合,并且允许请求​​再次自由流通。

可以想象,如果断路器断开,则请求将无法成功完成。 尽管有利于保护上游服务,但对于最初提出请求的客户端来说,这并不好。

这是扩展此模式的地方。

后备

我们不仅仅允许请求崩溃,还可以通过对未完成的API调用提供回退来更轻松地失败。 这可以由高速缓存,替代项或什至只是普通的旧存根数据提供。 重要的是,对于局外人来说,它看起来就像真实的东西。

例如,假设您是一家提供一些个性化建议的服务,但是建议引擎已断开。 通过提供一些常规的预缓存建议,最终用户将不会注意到它们之间的差异,除非他们真正开始四处寻找。

您是否曾经遇到过性能问题,其中运行缓慢的资源(无论是数据库还是API调用)导致备份请求并最终消耗了应用程序中的所有线程。 原因是您的应用程序就像是一艘巨大的空心划艇-一次泄漏,水最终消耗了整个设备。

隔板模式(参考船舶的隔板)是一种将不同的远程调用隔离到自己的线程池中的方法。 如果一个远程资源导致请求排队,那么问题将被隔离到该单个资源上,从而保护应用程序的其余部分尽可能正常地进行。

祖尔

Zuul(就像来自Ghostbusters的噩梦般的狗怪物一样)充当了整套微服务的看门人。 所有请求的单个入口点使您可以在一个地方管理多个跨领域关注点。 仅举几个方面,例如安全性,监视和日志记录。

Zuul可以在请求的生命周期中的三个不同点截获请求,从而使您可以适当地修饰其他功能。

  • 前置过滤器会添加自定义逻辑,以在请求进入您的“域”时对其进行处理
  • 回复过滤器是您离开平台的最后一站。 例如,记录请求的完成情况。
  • 路由过滤器会在请求向上游传播之前对其进行拦截,从而使您有机会更改其目的地。 非常适合管理A / B测试和类似策略。

此外,Zuul与Eureka服务发现引擎无缝集成,从而能够动态确定健康的上游资源。

基于事件的架构

微服务通常通过RESTful API调用进行通信。 REST意味着同步,因为请求/响应自然地捆绑在一起,因此导致两个服务之间的紧密耦合。

不幸的是,这种紧密的耦合在诸如容错之类的方面(即我们前面讨论的Hystrix库)中管理通信变得有些复杂。 同步通信还受普遍缓慢的影响,使得正常降级成为棘手的前景。

通过通过某种消息总线解耦服务,我们可以通过异步消息传递获得许多优势。 轻松扩展,应对中断和停机以及发展体系结构以支持更多用户的能力都是巨大的好处,它们可以使您的系统更具弹性和灵活性。

齐普金

至少可以说,随着所有这些技术以分布式方式消失,它可能会使调试生产问题变得非常困难。

OpenTracing计划旨在通过提供独立于供应商,语言和框架的解决方案(Zipkin是其成员)来缓解此问题。

单个请求流或跟踪在我们的网关(例如Zuul)处启动,并在整个遍历中传播。 每个跟踪都分为多个范围,这些范围代表某些服务处理步骤,例如数据库调用。

仅对一小部分请求(默认为10%)捕获跟踪并将其记录到中央服务。 最终结果是通过系统直观显示请求的生命周期,并在每个阶段(跨度)附带一些关键指标,使您能够跟踪那些令人担忧的隐患区域。

Spring Cloud可以大大简化一套健壮,干净集成的微服务的开发。 但是,对于这种集成在非Spring服务中的普及程度还存在一个开放的问题—当然,微服务的口头禅是为每项工作使用正确的工具,这可能会导致整个技术领域的多元化很多团队。 我想可能是服务网格最有意义的情况。 但是,如果您刚开始使用少量基于Java的服务,则可能会比采用Spring Cloud框架及其关联者做的糟得多。