Spring Cloud微服务架构介绍

  Spring Cloud的目标是为Spring开发人员提供一套易于使用的工具来构建分布式系统。它主要通过包装其他实现堆栈,从Netflix OSS堆栈开始。然后,这些堆栈将通过基于注释的配置,Java配置和基于模板的编程的熟悉工具进行消耗。我们来看几个Spring Cloud的组件。

Spring Cloud配置服务器

Spring Cloud Config Server(配置服务器)提供了可水平扩展的集中式配置服务。它使用可插拔存储库层作为其数据存储,当前支持本地存储,Git和Subversion。通过利用版本控制系统作为配置存储,开发人员可以轻松地对配置更改进行版本化和审核。


配置表示为Java属性或YAML文件。Config Server将这些文件合并到环境对象中,将对Spring属性和配置文件的理解模型呈现为REST API。这个REST API可以直接由任何应用程序查询来获取配置数据,但可以将智能客户端绑定添加到 Spring Boot 应用程序中,这些应用程序将自动协调任何本地配置与配置服务器接收的配置。

Spring Cloud总线

Spring Cloud Config Server是一种强大的机制,用于在一组应用程序实例中一致地分发配置。然而,就目前而言,我们目前仅限于在应用程序启动时更新此类配置。将属性的新值推送到Git后,我们需要手动重新启动每个应用程序流程以获取新值。我们想要的是在不重新启动的情况下刷新应用程序配置的功能。


Spring Cloud Bus为您的应用程序实例添加一个管理背板。它目前被实现为客户端绑定到一组AMQP交换和队列,但这个后端也被设计为可插拔。Cloud Bus为您的应用程序添加了更多的管理端点。在图中,我们看到上POST到App A的/bus/refresh端点的一个请求,由此获得Git的greeting属性新值。此请求触发三个事件:

1. App A从配置服务器请求最新的配置。 使用@RefreshScope注释的任何Spring Bean 将重新初始化到新配置。

2.应用程序A向AMQP交换机发送消息,指示它已经接收到刷新事件。

3.通过聆听适当的AMQP队列参与Cloud Bus的应用程序B和C以与App A相同的方式接收消息并更新其配置。现在我们可以刷新应用程序的配置而无需重新启动。

Spring Cloud Netflix

Spring Cloud Netflix提供了几个Netflix组件的封装:Eureka,Ribbon,Hystrix和Zuul。下面依次讨论这些。

Eureka是一个有弹性的服务注册表实现。服务注册表是用于服务发现的一种机制

Spring Cloud Netflix通过简单地将spring-cloud-starter-eureka-server依赖关系添加到Spring Boot应用程序,然后用@EnableEurekaServer来标注该应用程序的配置类.

 

应用程序可以通过添加spring-cloud-starter-eureka依赖关系并注释@EnableDiscoveryClient其配置类来参与服务发现。此注释提供了将DiscoveryClient正确配置的实例注入任何Spring Bean的功能。 DiscoveryClient是服务发现的抽象,在这种情况下恰好是通过Eureka实现的,但也可以提供与其他候选技术栈(如Consul)的集成。 DiscoveryClient 能够提供位置信息(例如网络地址),并提供根据服务逻辑标识符在Eureka注册服务实例的其它元数据。

Eureka提供的负载平衡算法只限于轮循。 Ribbon提供了一个复杂的客户端IPC库,具有可配置的负载平衡和容错能力。可以从Eureka服务器获取的动态服务器列表导出轮询列表。Spring Cloud Netflix通过向Spring Boot添加spring-cloud-starter-ribbonSpring添加依赖关系来提供轮询Ribbon的集成。这个额外的库也提供了将LoadBalancerClient正确配置的实例注入任何Spring Bean的能力,这将使客户端获得负载平衡(图4)。

除了其他任务之外,使用Ribbon还可以实现额外的负载平衡算法,例如可用性过滤,加权响应时间和可用性区域密切关系。

Spring Cloud Netflix将通过自动创建一个RestTemplate的可以注入到任何Spring Bean中的Ribbon增强实例进一步增强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 为分布式系统提供了常见的容错模式的实现(如断路器 和隔板)。断路器通常被实现为状态机,其示例在图5中找到。


断路器可以放置在服务和其远程依赖之间。如果电路关闭,则对依赖关系的调用正常通过。如果呼叫失败,则计算该失败。如果故障次数在可配置的时间段内达到阈值,则电路跳闸以打开。在打开状态下,调用不再发送到依赖项,并且生成的行为是可自定义的(抛出异常,返回伪数据,调用不同的依赖关系等)。

定期地,状态机将转换到“半开”状态,以确定依赖关系是否再次健康。在这种状态下,请求再次通过。如果请求成功,机器将返回到关闭状态。如果请求失败,机器将转回到打开状态。

Spring Cloud应用程序可以通过添加spring-cloud-starter-hystrix 依赖关系并注释@EnableCircuitBreaker其配置类来利用Hystrix。然后,您可以通过以下方式对任何Spring Bean方法用@HystrixCommand添加断路器:

@HystrixCommand(fallbackMethod = "getProducerFallback")
public ProducerResponse getValue() {
return restTemplate.getForObject("http://producer", ProducerResponse.class);
}

此示例指定一个名为getProducerFallback的后备方法。当断路器处于断开状态时,这种方法将被用来代替getValue:

private ProducerResponse getProducerFallback() {
return new ProducerResponse(42);
}

除了提供状态机行为外,Hystrix还会从每个断路器发出一个指标流,提供重要的遥测,如请求测量,响应时间直方图以及成功,失败和短路请求的数量(图6)。


Zuul处理Netflix边缘服务的所有传入请求。它与其他Netflix组件(如Ribbon和Hystrix)结合使用,为Netflix服务提供灵活而有弹性的路由选择层。

Netflix使用动态加载到Zuul中的过滤器执行以下功能:

1.身份验证和安全性: 识别每个资源的身份验证要求,并拒绝不满足他们的请求。

2.洞察和监控: 跟踪边缘的有意义的数据和统计数据,以便我们准确地了解生产情况。

3.动态路由: 根据需要将请求动态路由到不同的后端集群。

4.压力测试: 逐渐增加到集群的流量,以衡量性能。

5.卸载: 为每种类型的请求分配容量并删除超过限制的请求。

6.静态响应处理: 直接在边缘构建一些响应,而不是将它们转发到内部集群。

7.多区域弹性: 跨AWS地区的路由请求,以使我们的ELB使用多样化,并使我们的边缘更接近我们的成员。

此外, Netflix利用Zuul的功能,通过canary 版本执行外部路由和压力测试。

对于一个UI应用程序想要代理对一个或多个后端服务的呼叫等非常常见的用例,Spring Cloud已经创建了一个嵌入式的Zuul代理,以简化开发。该功能便于用户前端对其所需的后端服务进行代理,避免了对所有后端单独管理CORS(跨原始资源共享)和身份验证问题的需求。Zuul代理是API网关模式的一个重要应用(图7)

Spring Cloud增强了嵌入式Zuul代理,提供文件上传的自动处理功能,并且通过添加Spring Cloud Security可以轻松提供OAuth2 SSO,以及向下游服务提供令牌继承。Zuul使用Ribbon作为其客户端和所有出站请求的负载均衡器。Ribbon的动态服务器列表通常由Eureka导入,但Spring Cloud能够从其他来源导入。

进入微服务世界使我们直接进入分布式系统的世界,分布式系统并不总是“正常工作”,所以我们必须假设我们系统的组件的行为和位置往往会是以不可预知的方式不断变化。

微服务

Spring源码应用

Springcloud专题