为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

慕的地6264312 2018-10-29 04:04:37
如何利用Spring Cloud构建起自我修复型分布式系统
查看完整描述

1 回答

?
慕沐林林

TA贡献2016条经验 获得超9个赞

  Spring Cloud项目的既定目标在于为Spring开发人员提供一整套易于使用的工具集,从而保证其轻松构建起自己需要的分布式系统方案。为了实现这一目标,Spring Cloud以Netflix OSS堆栈为基础将大量实现堆栈加以整合并打包。这些堆栈而后可以通过大家所熟知的各类基于注释的配置工具、Java配置工具以及基于模板的编程工具实现交付。下面就让我们一起了解Spring Cloud当中的几类常见组件。
  Spring Cloud Config Server
  Spring Cloud Config Server能够提供一项具备横向扩展能力的集中式配置服务。它所使用的数据被保存在一套可插拔库层当中,后者目前能够支持本地存储、Git以及Subversion。通过利用一套版本控制系统作为配置存储方案,开发人员能够轻松实现版本与审计配置的内容调整。
  配置内容会以Java属性或者YAML文件的形式体现。该Config Server会将这些文件合并为环境对象,其中包含易于理解的Spring属性模型以及作为REST API存在的配置文件。任何应用程序都能够直接调用该REST API当中所包含的配置数据,但我们也可以将智能客户端绑定方案添加到Spring Boot应用程序当中,并由后者自动将接收自Config Server的配置信息分配至任意本地配置当中。
  Spring Cloud Bus
  Spring Cloud Config Server是一套强大的配置分发机制,能够在保障一致性的前提下将配置内容分发到多个应用程序实例当中。然而根据其设计思路的限定,我们目前只能在应用程序启动时对其配置进行更新。在向Git中的某一属性发送新值时,我们需要以手动方式重启每个应用程序进程,从而保证该值被切实纳入应用当中。很明显,大家需要能够在无需重启的前提下完成对应用程序配置内容的更新工作。
  Spring Cloud Bus的任务正是为应用程序实例添加一套管理背板。它目前依靠将一套客户端绑定至一组AMQP交换与队列当中来实现,但这一后端在设计上也实现了可插拔特性。Spring Cloud Bus为我们的应用程序带来了更多管理端点。在图二中,我们可以看到一个面向greeting属性的值被发送至Git当中,而后一条请求被发送至应用A中的/bus/refresh端点。该请求会触发以下三个事件:
  应用A从Config Server处请求获取最新版本的配置内容。任意注明了@RefreshScope的Spring Bean都会被重新初始化并载入新的配置内容。
  应用A向AMQP交换机制发送一条消息,表明其已经收到更新指示。
  通过监听AMQP队列而被纳入Cloud Bus的应用B与应用C会获取到上述消息,并以与应用A同样的方式实现配置更新。
  现在我们已经有能力在无需重启的情况下对应用程序配置进行更新了。
  Spring Cloud Netflix
  Spring Cloud Netflix针对多种Netflix组件提供打包方案,其中包括Eureka、Ribbon、Hystrix以及Zuul。接下来我将分别对它们作出讲解。
  Eureka是一套弹性服务注册实现方案。其中服务注册属于服务发现模式的一种实现机制
  
  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当中,从而实现客户端负载均衡(如图四所示)。
  
  在此类任务当中,我们可以利用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-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还能够提供来自各断路机制的重要遥测指标流,具体包括请求计量、响应时间直方图以及成功、失败与短路请求数量等(如图六所示)。
  
  Zuul能够处理全部指向Netflix边缘服务的输入请求。它能够与Ribbon以及Hystrix等其它Netflix组件相结合,从而提供一个灵活且具有弹性的Netflix服务路由层。
  Netflix公司在Zuul当中加载动态过滤机制,从而实现以下各项功能:
  验证与安全保障: 识别面向各类资源的验证要求并拒绝那些与要求不符的请求。
  审查与监控: 在边缘位置追踪有意义数据及统计结果,从而为我们带来准确的生产状态结论。
  动态路由: 以动态方式根据需要将请求路由至不同后端集群处。
  压力测试: 逐渐增加指向集群的负载流量,从而计算性能水平。
  负载分配: 为每一种负载类型分配对应容量,并弃用超出限定值的请求。
  静态响应处理: 在边缘位置直接建立部分响应,从而避免其流入内部集群。
  多区域弹性: 跨越AWS区域进行请求路由,旨在实现ELB使用多样化并保证边缘位置与使用者尽可能接近。
  除此之外,Netflix公司还利用Zuul的功能通过金丝雀版本实现精确路由与压力测试。
  Spring Cloud已经建立起一套嵌入式Zuul代理机制,从而简化常见用例当中UI应用需要将调用代理至一项或者多项后端服务处的对应开发流程。这项功能对于要求将用户界面代理至后端服务的用例而言极为便捷,其避免了管理CORS(即跨域资源共享)以及为全部后端进行独立验证等复杂流程。Zuul代理机制的一类重要应用在于实现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得到切实验证。我个人建议大家在着手建立理想中的“永远运行、自我修复且具备可扩展能力”的系统方案之前,首先对它们进行一番尝试与体验。



查看完整回答
反对 回复 2018-11-17
  • 1 回答
  • 0 关注
  • 695 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信