文档章节

如何利用Spring Cloud构建起自我修复型分布式系统

harries
 harries
发布于 06/24 10:16
字数 4512
阅读 21
收藏 0
点赞 0
评论 0

利用Netflix所打造的组件及各类大家熟知的工具,我们完全可以顺利应对由微服务以及分布式计算所带来的技术挑战。

在过去一年当中,微服务已经成为软件架构领域一个炙手可热的新名词,而且我们也能轻松举出由其带来的诸多比较优势。然而,我们必须清醒意识到的是,一旦开始遵循微服务思路而对现有架构体系进行拆分,就意味着我们将不可避免地进入分布式系统领域。在之前的文章中我们曾经探讨过分布式计算的八大认识误区*,由此可见此类系统本身充满着风险,而且一旦犯下这八种错误中的任何一种、我们都将面对灾难性的后果。

在我个人看来,如果要将这些误区总结成一句观点,那就是:对于一套分布式系统来说,任何关于一致性或者可靠性的表达都毫无保障可言。我们需要假定系统当中的各种行为以及组件位置始终处于不断变化状态。由此产生的后果主要有两点:组件有时候会导致糟糕的服务质量甚至令服务直接离线,我们则只能将其统称为“故障”、而很难具体阐明到底是哪里出了问题。一旦没能得到妥善处理,此类故障将引中断与停机,这意味着系统将无法按照既定设计方案为用户提供服务项目。

有鉴于此,为了享受微服务所带来的诸多优势(包括松散耦合、自治服务、分散化治理以及易于持续交付等等),我们必须避免由单一故障依次递进而最终导致系统崩溃的恐怖状况。关于这一点,Erlang语言之父Joe Armstrong曾经在题为《如何构建永远运行、自我修复且可扩展的系统》一文中作出过透彻的表述。在他看来,此类系统看起来与我们所说的微服务架构非常相近,但其着重强调的是其作为自我修复系统的容错能力。那么对我们来说,如何才能建立起这样一套坚实可靠的系统方案?

Netflix公司在微服务架构的实施与推动方面一直扮演着先行者的角色。作为其业务构建的原则性方针之一,Netflix公司认为系统方案必须要能够承受任意组件的突发性故障,而整体系统仍能继续正常运转(这意味着我们仍然能够在该平台上观看电影,而Netflix也可以继续记录用户的观看喜好)。在尝试建立这样一套系统时,我们遭遇到以下这些常见的技术挑战:

  • 由于需要将系统拆分成多个分布式进程,我们要如何在保证一致性与可靠性的前提下将这些配置分发至这些进程当中?
  • 当这些配置方案需要加以修改时,我们该如何在无需重新部署全部进程的前提下对配置内容进行更新?
  • 在这样一套系统当中,特别是对于部署于云环境内的系统,各个进程不仅内容经常变动、所在位置亦会不断转换(特别是在进行故障转移的情况下)。我们要如何准确判断那些需要进行协同的进程的具体位置?
  • 一旦我们检测到了当前进程关联性的几种可能位置,我们该如何选择接下来要进行通信的进程实例?
  • 假设在选定一个进程实例并与该实例进行通信的过程当中该实例出现了故障,我们该如何防止由此引发的连锁故障?
  • 在系统综合运作行为不断给自治服务带来演进拓扑结构的情况下,我们要如何对其状态保持可视化监控、从而作出有针对性的准确调整?

事实上,大家可以部署多种样板模式及开源工具来解决上述技术挑战。Netflix公司就构建出多种组件且加以开源,并在生产环境中进行了一系列测试。从理论角度讲,我们能够利用这些工具来建立起有能力“永远运行、自我修复且实现规模化扩展”的系统。对刚刚着手建立分布式系统的朋友们来说,我们目前的第一要务在于理解这些实现模式、掌握Netflix组件并加以应用,而后将这些组件部署、管理并集成至自己的系统当中。由于采取任何新的技术依赖关系都会给软件工程方案带来前所未见的复杂性元素,因此我们建议大家最好直接采用Netflix的堆栈来尽可能减少此类潜在摩擦。

Spring工程技术团队从建立之初至今一直在努力打造出足以应对Java复杂性的强大武器。我们的早期关注重点在于消除J2EE给企业级应用程序开发者带来的生产效率影响。而着眼于最近一段时间,我们的主要精力则转移到了实现云-本地应用程序构建身上,而且这方面的大部分工作成果都被纳入或者围绕着Spring Cloud项目所展开。

Spring Cloud项目的既定目标在于为Spring开发人员提供一整套易于使用的工具集,从而保证其轻松构建起自己需要的分布式系统方案。为了实现这一目标,Spring Cloud以Netflix OSS堆栈为基础将大量实现堆栈加以整合并打包。这些堆栈而后可以通过大家所熟知的各类基于注释的配置工具、Java配置工具以及基于模板的编程工具实现交付。下面就让我们一起了解Spring Cloud当中的几类常见组件。

Spring Cloud Config Server

Spring Cloud Config Server能够提供一项具备横向扩展能力的集中式配置服务。它所使用的数据被保存在一套可插拔库层当中,后者目前能够支持本地存储、Git以及Subversion。通过利用一套版本控制系统作为配置存储方案,开发人员能够轻松实现版本与审计配置的内容调整。

如何利用Spring Cloud构建起自我修复型分布式系统

图一:Spring Cloud Config Server

配置内容会以Java属性或者YAML文件的形式体现。该Config Server会将这些文件合并为环境对象,其中包含易于理解的Spring属性模型以及作为REST API存在的配置文件。任何应用程序都能够直接调用该REST API当中所包含的配置数据,但我们也可以将智能客户端绑定方案添加到Spring Boot应用程序当中,并由后者自动将接收自Config Server的配置信息分配至任意本地配置当中。

Spring Cloud Bus

Spring Cloud Config Server是一套强大的配置分发机制,能够在保障一致性的前提下将配置内容分发到多个应用程序实例当中。然而根据其设计思路的限定,我们目前只能在应用程序启动时对其配置进行更新。在向Git中的某一属性发送新值时,我们需要以手动方式重启每个应用程序进程,从而保证该值被切实纳入应用当中。很明显,大家需要能够在无需重启的前提下完成对应用程序配置内容的更新工作。

如何利用Spring Cloud构建起自我修复型分布式系统

图二: 配备Spring Cloud Bus的Spring Cloud Config Server

Spring Cloud Bus的任务正是为应用程序实例添加一套管理背板。它目前依靠将一套客户端绑定至一组AMQP交换与队列当中来实现,但这一后端在设计上也实现了可插拔特性。Spring Cloud Bus为我们的应用程序带来了更多管理端点。在图二中,我们可以看到一个面向greeting属性的值被发送至Git当中,而后一条请求被发送至应用A中的/bus/refresh端点。该请求会触发以下三个事件:

  1. 应用A从Config Server处请求获取最新版本的配置内容。任意注明了@RefreshScope的Spring Bean都会被重新初始化并载入新的配置内容。
  2. 应用A向AMQP交换机制发送一条消息,表明其已经收到更新指示。
  3. 通过监听AMQP队列而被纳入Cloud Bus的应用B与应用C会获取到上述消息,并以与应用A同样的方式实现配置更新。

现在我们已经有能力在无需重启的情况下对应用程序配置进行更新了。

Spring Cloud Netflix

Spring Cloud Netflix针对多种Netflix组件提供打包方案,其中包括Eureka、Ribbon、Hystrix以及Zuul。接下来我将分别对它们作出讲解。

Eureka是一套弹性服务注册实现方案。其中服务注册属于服务发现模式的一种实现机制(如图三所示)。

如何利用Spring Cloud构建起自我修复型分布式系统

图三:利用服务注册实现服务发现

Spring Cloud Netflix通过直接将spring-cloud-starter-eureka-server关联性添加到Spring Boot应用程序、随后将该应用程序的配置类与@EnableEurekaServer相整合的方式病嵌入式Eureka服务器的部署工作。

应用程序能够通过添加spring-cloud-starter-eureka关联性并将其配置类与@EnableDiscoveryClient相整合的方式加入到服务发现流程当中。通过整合,我们能够将经过配置的适合DiscoveryClient实例注入至任意Spring Bean内。在我们所列举的实例中,DiscoveryClient作为服务发现的一种抽象机制恰好可以通过Eureka实现,不过大家也可以将其与Consul等其它备选堆栈相集成。DiscoveryClient能够通过服务的逻辑标识符提供位置信息(例如网络地址)以及其它与已注册至Eureka的服务实例相关的元数据。

Eureka提供的负载均衡机制仅支持单循环条件。而Ribbon提供的客户端IPC库则更为精巧,其同时具备可配置负载均衡机制与故障容错能力。Ribbon能够通过获取自Eureka服务器的动态服务器列表进行内容填充。Spring Cloud Netflix通过将spring-cloud-starter-ribbon关联性添加至Spring Boot应用程序的方式实现与Ribbon的集成。这套额外库允许用户将经过适当配置的LoadBalancerClient实例注入至Spring Bean当中,从而实现客户端负载均衡(如图四所示)。

如何利用Spring Cloud构建起自我修复型分布式系统

图四:使用客户端负载均衡机制

在此类任务当中,我们可以利用Ribbon实现额外负载均衡算法,包括可用性过滤、加权响应时间以及可用域亲和等。

Spring Cloud Netflix还通过自动创建能够被注入至任意Spring Bean的Ribbon强化型RestTemplate实例的方式进一步改进了Spring开发者的Ribbon使用方式。在此之后,开发人员能够轻松将URL所提供的逻辑服务名称递交至RestTemplate:

@Autowired
@LoadBalanced
private RestTemplate restTemplate;
@RequestMapping(“/”)
public String consume() {
ProducerResponse response = restTemplate.getForObject(“http://producer”, ProducerResponse.class);
return String.format(“{\”value\”: %s}”, response.getValue());
}

Hystrix能够为断路器以及密闭闸门等分布式系统提供一套通用型故障容错实现模式。断路器通常会被作为一台状态机使用,具体如图五所示。

如何利用Spring Cloud构建起自我修复型分布式系统

图五:断路器状态机

断路器能够介于服务及其远程关联性之间。如果该电路处于闭合状态,则所有指向该关联性的调用通常将直接通过。如果某一调用失败,则故障将被计入计数。而一旦失败次数达到可配置时间区间内的阈值,该电路将被跳闸至断开。在处于断开状态时,调用将不再被发往该关联,而由此产生的结果将可自行定制(包括报告异常、返回虚假数据或者调用其它关联等等)。

该状态机会定期进入所谓“半开”状态,旨在检测关联性是否处于健康运作状态。在这种状态下,请求一般仍将继续得以通过。当请求成功通过时,该设备会重新回归闭合状态。而如果请求失败,则该设备会重新回归断开状态。

Spring Cloud应用程序能够通过添加spring-cloud-starter-hystrix关联性并将其配置类与@EnableCircuitBreaker相整合的方式利用Hystrix。在此之后,大家可以通过与@HystrixCommand整合的方式将断路器机制纳入到任意Spring Bean方法内:

@HystrixCommand(fallbackMethod = “getProducerFallback”)
public ProducerResponse getValue() {
return restTemplate.getForObject(“http://producer”, ProducerResponse.class);
}
以上实例中指定了一个名为getProducerFallback的备用方法。当该断路器处于断开状态时,此方法将替代getValue接受调用:private ProducerResponse getProducerFallback() {
return new ProducerResponse(42);
}

 

除了实现状态机机制之外,Hystrix还能够提供来自各断路机制的重要遥测指标流,具体包括请求计量、响应时间直方图以及成功、失败与短路请求数量等(如图六所示)。

如何利用Spring Cloud构建起自我修复型分布式系统

图六:Hystrix仪表板

Zuul能够处理全部指向Netflix边缘服务的输入请求。它能够与Ribbon以及Hystrix等其它Netflix组件相结合,从而提供一个灵活且具有弹性的Netflix服务路由层。

Netflix公司在Zuul当中加载动态过滤机制,从而实现以下各项功能:

  • 验证与安全保障: 识别面向各类资源的验证要求并拒绝那些与要求不符的请求。
  • 审查与监控: 在边缘位置追踪有意义数据及统计结果,从而为我们带来准确的生产状态结论。
  • 动态路由: 以动态方式根据需要将请求路由至不同后端集群处。
  • 压力测试: 逐渐增加指向集群的负载流量,从而计算性能水平。
  • 负载分配: 为每一种负载类型分配对应容量,并弃用超出限定值的请求。
  • 静态响应处理: 在边缘位置直接建立部分响应,从而避免其流入内部集群。
  • 多区域弹性: 跨越AWS区域进行请求路由,旨在实现ELB使用多样化并保证边缘位置与使用者尽可能接近。

除此之外,Netflix公司还利用Zuul的功能通过金丝雀版本实现精确路由与压力测试。

Spring Cloud已经建立起一套嵌入式Zuul代理机制,从而简化常见用例当中UI应用需要将调用代理至一项或者多项后端服务处的对应开发流程。这项功能对于要求将用户界面代理至后端服务的用例而言极为便捷,其避免了管理CORS(即跨域资源共享)以及为全部后端进行独立验证等复杂流程。Zuul代理机制的一类重要应用在于实现API网关模式(如图七所示)。

如何利用Spring Cloud构建起自我修复型分布式系统

图七:API网关模式

Spring Cloud对嵌入式Zuul代理进行了强化,从而使其能够自动实现文件上传处理。而与Spring Cloud Security配合之后,其能够轻松实现OAuth2 SSO以及将令牌传递至下游服务等工作。Zuul利用Ribbon作为其客户端与全部出站请求的负载均衡机制。Ribbon的动态服务器列表内容通常由Eureka负责填充,但Spring Cloud也能够通过其它来源填充该列表。Spring Cloud Lattice项目就已经能够通过轮询Cloud Foundry Diego的Receptor API填充Ribbon的服务器列表。

跨入微服务领域的决定意味着我们将正式迎接分布式系统所带来的诸多挑战,而分布式系统绝不是那种能够“凑合使用”的方案。因此,我们必须假设系统内各组件的行为及位置始终处于不断变化当中,甚至经常表现出不可预知状态。在今天的文章中,我们已经谈到了几种能够帮助大家解决此类挑战的现成模式,而且这些模式已经在Netflix OSS与Spring Cloud得到切实验证。我个人建议大家在着手建立理想中的“永远运行、自我修复且具备可扩展能力”的系统方案之前,首先对它们进行一番尝试与体验。

*备注:这八大误区分别为:

1.网络环境是可靠的

2.延迟水平为零

3.传输带宽是无限的

4.网络环境是安全的

5.拓扑结构不会变化

6.总会有管理员帮助解决问题

7.流量成本为零

8.网络内各组成部分拥有同质性

原文标题:Build self-healing distributed systems with Spring Cloud

本文转载自:http://www.liuhaihua.cn/archives/524832.html

共有 人打赏支持
harries
粉丝 44
博文 99
码字总数 86900
作品 3
朝阳
其他
Spring Cloud-honghu Cloud分布式微服务云系统

简介 鸿鹄云Cloud是基于SpringCloud来封装的,是一系列框架的有序集合。利用Spring Boot的开发模式简化了分布式系统基础设施的开发,如服务发现、注册、配置中心、消息总线、负载均衡、断路器...

itcloud
04/25
0
0
Springcloud应用在阿里云Kubernetes上的IP互通实践

问题 在应用微服务化方案中,Springcloud是比较常见的选择,毕竟其对于Java 的程序员来说比较友好,基于Springboot的编程方式也使得门槛比较低。但是在将Springcloud的应用运行到Kubernetes容...

了哥-duff
06/25
0
0
【Spring Cloud】分布式必学springcloud(一)——简介和看法

一、前言 开篇之前,我想说,springcloud会完胜dubbo。 小编以前做分布式是用的webservice、dubbo。最近的项目中,开始使用了springcloud,springcloud包含了很多的组件,这些组件是dubbo没有...

kisscatforever
04/16
0
0
史上最简单的 SpringCloud 教程

《史上最简单的 SpringCloud 教程》系列: 史上最简单的 SpringCloud 教程 | 第一篇: 服务的注册与发现(Eureka) 史上最简单的SpringCloud教程 | 第二篇: 服务消费者(rest+ribbon) 史上最...

外星人et59
04/21
0
0
SpringCloud实战9-Stream消息驱动

官方定义 Spring Cloud Stream 是一个构建消息驱动微服务的框架。   应用程序通过 inputs 或者 outputs 来与 Spring Cloud Stream 中binder 交互,通过我们配置来 binding ,而 Spring Clo...

狂小白
05/29
0
0
EurekaServer高可用

前言 之前一篇文章文章《服务注册与发现---eureka》介绍了单点EurekaServer。但是实际环境中,这种单点的的模式可能会有很多隐形的问题。比如EurekaServer发生宕机,或者某些意外情况发生,很...

dalaoyang
06/15
0
0
springcloud 高效率本地加Redis双级缓存

在springcloud中我们可以使用spring-boot-starter-data-redis已经为我们处理好分布式缓存,但是我们还是不满足于只存在于网络中传输的缓存,我们现在来扩展成本地加Redis双级缓存,这样就可以...

dounine
04/19
0
0
SpringCloud 微服务 (十一) Spring Cloud Stream MQ-API

壹 上节学习了基础的RabbitMQ,本次继续学习MQ相关API---SpringCloud Stream 看到Stream大致会联想到流,input,output等信息,官网解释SpringCloud Stream是给微服务应用构建消息队列驱动的能力...

___大侠
07/05
0
0
springcloud架构搭建(一) Eureka服务器搭建及配置

springcloud架构搭建(一) Eureka服务器搭建及配置 今天开始准备学习一下springcloud的相关知识以及环境部署,并且搭建一套springcloud分布式框架: 本文只针对刚开始接触或者没有接触过spr...

itcloud
05/21
0
0
Spring Cloud Config采用数据库存储配置内容

在之前的《Spring Cloud构建微服务架构:分布式配置中心》一文中,我们介绍的Spring Cloud Server配置中心采用了Git的方式进行配置信息存储。这一设计巧妙的利用Git自身机制以及其他具有丰富...

程序猿DD
06/15
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

NNS拍卖合约

前言 关于NNS的介绍,这里就不多做描述,相关的信息可以查看NNS的白皮书http://doc.neons.name/zh_CN/latest/nns_background.html。 首先nns中使用的竞价货币是sgas,关于sgas介绍可以戳htt...

红烧飞鱼
38分钟前
0
0
从MySQL全备文件中恢复单个库或者单个表

从MySQL全备文件中恢复单个库或者单个表 提取建库语句 sed -n '/^-- Current Database: db_cms/,/^-- Current Database: `/p' backup.sql > db_cms.sql & 提取ddl sed -e'/./{H;$!d;}' -e ......

yysue
今天
0
0
Java IO类库之管道流PipeInputStream与PipeOutputStream

一、java管道流介绍 在java多线程通信中管道通信是一种重要的通信方式,在java中我们通过配套使用管道输出流PipedOutputStream和管道输入流PipedInputStream完成线程间通信。多线程管道通信的...

老韭菜
今天
0
0
用Python绘制红楼梦词云图,竟然发现了这个!

Python在数据分析中越来越受欢迎,已经达到了统计学家对R的喜爱程度,Python的拥护者们当然不会落后于R,开发了一个个好玩的数据分析工具,下面我们来看看如何使用Python,来读红楼梦,绘制小...

猫咪编程
今天
0
0
Java中 发出请求获取别人的数据(阿里云 查询IP归属地)

1.效果 调用阿里云的接口 去定位IP地址 2. 代码 /** * 1. Java中远程调用方法 * http://localhost:8080/mavenssm20180519/invokingUrl.action * @Title: invokingUrl * @Description: * @ret......

Lucky_Me
今天
1
0
protobuf学习笔记

相关文档 Protocol buffers(protobuf)入门简介及性能分析 Protobuf学习 - 入门

OSC_fly
昨天
0
0
Mybaties入门介绍

Mybaties和Hibernate是我们在Java开发中应用的比较多的两个ORM框架。当然,目前Mybaties正在慢慢取代Hibernate,这是因为相比较Hibernate而言Mybaties性能更好,响应更快,更加灵活。我们在开...

王子城
昨天
2
0
编程学习笔记之python深入之装饰器案例及说明文档[图]

编程学习笔记之python深入之装饰器案例及说明文档[图] 装饰器即在不对一个函数体进行任何修改,以及不改变整体的原本意思的情况下,增加函数功能的新函数,因为这个新函数对旧函数进行了装饰...

原创小博客
昨天
1
0
流利阅读笔记33-20180722待学习

黑暗中的生物:利用奇技淫巧快活生存 Daniel 2018-07-22 1.今日导读 如果让你在伸手不见五指的黑暗当中生存,你能熬过几天呢?而大千世界,无奇不有。在很多你不知道的角落,有些生物在完全黑...

aibinxiao
昨天
6
0
Hystrix降级逻辑中如何获取触发的异常

通过之前Spring Cloud系列教程中的《Spring Cloud构建微服务架构:服务容错保护(Hystrix服务降级)》一文,我们已经知道如何通过Hystrix来保护自己的服务不被外部依赖方拖垮的情况。但是实际...

程序猿DD
昨天
2
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部