#Spring Cloud

前言在微服务架构中,我们将系统拆分成了一个个的服务单元,各单元应用间通过服务注册与订阅的方式互相依赖。由于每个单元都在不同的进程中运行,依赖通过远程调用的方式执行,这样就有可能因为网络原因或是依赖服务自身问题出现调用故障或延迟,而这些问题会直接导致调用方的对外服务也出现延迟,若此时调用方的请求不断增加,最后就会出现因等待出现故障的依赖方响应而形成任务积压,线程资源无法释放,最终导致自身服务的瘫痪,进一步甚至出现故障的蔓延最终导致整个系统的瘫痪。如果这样的架构存在如此严重的隐患,那么相较传统架构就更加的不稳定。为了解决这样的问题,因此产生了断路器等一系列的服务保护机制。 针对上述问题,在Spring Cloud Hystrix中实现了线程隔离、断路器等一系列的服务保护功能。它也是基于Netflix的开源框架 Hystrix实现的,该框架目标在于通过控制那些访问远程系统、服务和第三方库的...

前言 此文所述处理方式为本人在实践过程中研究分析得出的一种解决方案。 本文不仅希望能为 SC 学习者提供一种如题问题的一种解决方案,并且希望通过本文引出各位 SC 的朋友对如题问题的共同探讨和最佳实践方案的分享。 场景及痛点 单个项目是通过 Jersey 来实现 restful 风格的架构 发生异常时异常信息总是提示没有回调方法,不能显示基础服务抛出的异常信息 暂时没有考虑发生异常之后进行回调返回特定内容 业务系统通过 feign 调用基础服务,基础服务是会根据请求抛出各种请求异常的(采用标准http状态码),现在我的想法是如果调用基础服务时发生请求异常,业务系统返回的能够返回基础服务抛出的状态码 当然基础服务抛出的请求异常不能触发 hystrix 的熔断机制 问题解决方案分析解决思路 通过网上一些资料的查询,看到很多文章会说 HystrixBadRequestException...

Spring Cloud Config是Spring Cloud团队创建的一个全新项目,用来为分布式系统中的基础设施和微服务应用提供集中化的外部配置支持,它分为服务端与客户端两个部分。其中服务端也称为分布式配置中心,它是一个独立的微服务应用,用来连接配置仓库并为客户端提供获取配置信息、加密/解密信息等访问接口;而客户端则是微服务架构中的各个微服务应用或基础设施,它们通过指定的配置中心来管理应用资源与业务相关的配置内容,并在启动的时候从配置中心获取和加载配置信息。Spring Cloud Config实现了对服务端和客户端中环境变量和属性配置的抽象映射,所以它除了适用于Spring构建的应用程序之外,也可以在任何其他语言运行的应用程序中使用。由于Spring Cloud Config实现的配置中心默认采用Git来存储配置信息,所以使用Spring Cloud Config构建的配置服务...

通过前两篇《Spring Cloud构建微服务架构:服务消费(基础)》和《Spring Cloud构建微服务架构:服务消费(Ribbon)》,我们已经学会了在Spring Cloud中基本的服务调用方式。本文我们将继续介绍Spring Cloud中的另外一个服务消费的工具:Spring Cloud Feign。 Spring Cloud FeignSpring Cloud Feign是一套基于Netflix Feign实现的声明式服务调用客户端。它使得编写Web服务客户端变得更加简单。我们只需要通过创建接口并用注解来配置它既可完成对Web服务接口的绑定。它具备可插拔的注解支持,包括Feign注解、JAX-RS注解。它也支持可插拔的编码器和解码器。Spring Cloud Feign还扩展了对Spring MVC注解的支持,同时还整合了Ribbon和Eureka来提供均衡负载的HT...

通过上一篇《Spring Cloud构建微服务架构:服务消费(基础)》,我们已经学会如何通过LoadBalancerClient接口来获取某个服务的具体实例,并根据实例信息来发起服务接口消费请求。但是这样的做法需要我们手工的去编写服务选取、链接拼接等繁琐的工作,对于开发人员来说非常的不友好。所以,下来我们看看Spring Cloud中针对客户端负载均衡的工具包:Spring Cloud Ribbon。 Spring Cloud RibbonSpring Cloud Ribbon是基于Netflix Ribbon实现的一套客户端负载均衡的工具。它是一个基于HTTP和TCP的客户端负载均衡器。它可以通过在客户端中配置ribbonServerList来设置服务端列表去轮询访问以达到均衡负载的作用。 当Ribbon与Eureka联合使用时,ribbonServerList会被Discov...

通过上一篇《Spring Cloud构建微服务架构:服务注册与发现》,我们已经成功地将服务提供者:eureka-client或consul-client注册到了Eureka服务注册中心或Consul服务端上了,同时我们也通过DiscoveryClient接口的getServices获取了当前客户端缓存的所有服务清单,那么接下来我们要学习的就是:如何去消费服务提供者的接口? 使用LoadBalancerClient在Spring Cloud Commons中提供了大量的与服务治理相关的抽象接口,包括DiscoveryClient、这里我们即将介绍的LoadBalancerClient等。对于这些接口的定义我们在上一篇介绍服务注册与发现时已经说过,Spring Cloud做这一层抽象,很好的解耦了服务治理体系,使得我们可以轻易的替换不同的服务治理设施。 从LoadBalancerCl...

已经有非常长的时间没有更新《Spring Cloud构建微服务架构》系列文章了,自从开始写Spring Cloud的专题内容开始就获得了不少的阅读量和认可,当然也有一些批评,其中也不乏一些很中肯的意见和深度的问题,对我来说也是进一步提高的契机,在此感谢所有关注我博客的读者们。 由于之前主要精力都花在的编写《Spring Cloud微服务实战》一书上,所以该系列文章就没有得到持续的维护和更新。由于漫长的写书过程和繁琐的出版流程,在本书一面世的时候,在版本上已经落后于当前的最新版本。虽然在书中前前后后加入了一些版本更新的注意事项,但是认识过程不是一蹴而就的,总是随着实践的深入慢慢发现的。所以,决定重写一下该系列文章,一方面将Spring Cloud的版本更新到Dalston,另一方面重新组织内容并增加一些之前没有写过的重要组件。希望通过这个系列,来帮助准备使用Spring Cloud的...

之前在我博客的问答平台和Spring4All社区均有关于Spring Cloud的发布策略实现问题。虽然大家都给力很多不错的思路和建议,但是都没有Charles He的这篇文章详细。因此经得作者同意,在这里转载了该篇内容,为了更好的阅读体验,稍作一些格式调整,分享给更多Spring Cloud爱好者。更多关于Spring Cloud的干货内容请持续关注我的博客和Spring4All社区。 Spring Cloud 实践源码地址:https://github.com/charlesvhe/spring-cloud-practice 项目结构config 配置中心端口:8888,方便起见直接读取配置文件,生产环境可以读取git。application-dev.properties为全局配置。先启动配置中心,所有服务的配置(包括注册中心的地址)均从配置中心读取。 consumer 服...

相信关注我们Spring Cloud中文社区(bbs.springcloud.com.cn)的朋友们最近已经在最新的横幅中发现了一个全新的社区:spring4all.com,相信从名字大家也能猜到该域名寓意Spring For All,那么我们为什么要重新创建这样一个社区呢? 关于Spring For All截止至今天,我们的论坛注册用户也已经有1000+名了,在维护Spring Cloud中文社区的过程中,我们收到了各种各样关于Spring Boot和Spring Cloud的不同问题。虽然我们论坛的核心定位在Spring Cloud,但是很多问题并非由Spring Cloud本身负责的,而是其他Spring项目所负责。那么为了说清楚这些内容,还是需要用户对Spring的其他相关项目有一定的了解之后才能弄明白其基本原理。 事实上,我们在实战过程中,就算采用了Spring Boo...

在前几天发布的《Spring Cloud实战小贴士:Zuul统一异常处理(一)》一文中,我们详细说明了当Zuul的过滤器中抛出异常时会发生客户端没有返回任何内容的问题以及针对这个问题的两种解决方案:一种是通过在各个阶段的过滤器中增加try-catch块,实现过滤器内部的异常处理;另一种是利用error类型过滤器的生命周期特性,集中地处理pre、route、post阶段抛出的异常信息。通常情况下,我们可以将这两种手段同时使用,其中第一种是对开发人员的基本要求;而第二种是对第一种处理方式的补充,以防止一些意外情况的发生。这样的异常处理机制看似已经完美,但是如果在多一些应用实践或源码分析之后,我们会发现依然存在一些不足。 不足之处下面,我们不妨跟着源码来看看,到底上面的方案还有哪些不足之处需要我们注意和进一步优化的。先来看看外部请求到达API网关服务之后,各个阶段的过滤器是如何进行调度的:...

在上一篇《Spring Cloud源码分析(四)Zuul:核心过滤器》一文中,我们详细介绍了Spring Cloud Zuul中自己实现的一些核心过滤器,以及这些过滤器在请求生命周期中的不同作用。我们会发现在这些核心过滤器中并没有实现error阶段的过滤器。那么这些过滤器可以用来做什么呢?接下来,本文将介绍如何利用error过滤器来实现统一的异常处理。 过滤器中抛出异常的问题首先,我们可以来看看默认情况下,过滤器中抛出异常Spring Cloud Zuul会发生什么现象。我们创建一个pre类型的过滤器,并在该过滤器的run方法实现中抛出一个异常。比如下面的实现,在run方法中调用的doSomething方法将抛出RuntimeException异常。 public class ThrowExceptionFilter extends ZuulFilter { pri...

通过之前发布的《Spring Cloud构建微服务架构(五)服务网关》一文,相信大家对于Spring Cloud Zuul已经有了一个基础的认识。通过前文的介绍,我们对于Zuul的第一印象通常是这样的:它包含了对请求的路由和过滤两个功能,其中路由功能负责将外部请求转发到具体的微服务实例上,是实现外部访问统一入口的基础;而过滤器功能则负责对请求的处理过程进行干预,是实现请求校验、服务聚合等功能的基础。然而实际上,路由功能在真正运行时,它的路由映射和请求转发都是由几个不同的过滤器完成的。其中,路由映射主要通过pre类型的过滤器完成,它将请求路径与配置的路由规则进行匹配,以找到需要转发的目标地址;而请求转发的部分则是由route类型的过滤器来完成,对pre类型过滤器获得的路由地址进行转发。所以,过滤器可以说是Zuul实现API网关功能最为核心的部件,每一个进入Zuul的HTTP请求都会经过...

由于我们在之前所有的入门教程中,对于HTTP请求都采用了简单的接口实现。而实际使用过程中,我们的HTTP请求要复杂的多,比如当我们将Spring Cloud Zuul作为API网关接入网站类应用时,往往都会碰到下面这两个非常常见的问题: 会话无法保持 重定向后的HOST错误 本文将帮助大家分析问题原因并给出解决这两个常见问题的方法。 会话保持问题通过跟踪一个HTTP请求经过Zuul到具体服务,再到返回结果的全过程。我们很容易就能发现,在传递的过程中,HTTP请求头信息中的Cookie和Authorization都没有被正确地传递给具体服务,所以最终导致会话状态没有得到保持的现象。 那么这些信息是在哪里丢失的呢?我们从Zuul进行路由转发的过滤器作为起点,来一探究竟。下面是RibbonRoutingFilter过滤器的实现片段: public class RibbonRouting...

今天在博客的交流区收到一条不错的问题,拿出来给大家分享一下。具体问题如下: 因为项目里面用到了redis集群,但并不是用spring boot的配置方式,启动后项目健康检查老是检查redis的时候状态为down,导致注册到eureka后项目状态也是down。问下能不能设置spring boot不检查 redis的健康状态 "redis": { "status": "DOWN", "error": "org.springframework.data.redis.RedisConnectionFailureException: Cannot get Jedis connection; nested exception is redis.clients.jedis.exceptions.JedisConnectionException: Could not g...

本文将继续讨论基于Consul的分布式锁实现。信号量是我们在实现并发控制时会经常使用的手段,主要用来限制同时并发线程或进程的数量,比如:Zuul默认情况下就使用信号量来限制每个路由的并发数,以实现不同路由间的资源隔离。 信号量(Semaphore),有时被称为信号灯,是在多线程环境下使用的一种设施,是可以用来保证两个或多个关键代码段不被并发调用。在进入一个关键代码段之前,线程必须获取一个信号量;一旦该关键代码段完成了,那么该线程必须释放信号量。其它想进入该关键代码段的线程必须等待直到第一个线程释放信号量。为了完成这个过程,需要创建一个信号量VI,然后将Acquire Semaphore VI以及Release Semaphore VI分别放置在每个关键代码段的首末端,确认这些信号量VI引用的是初始创建的信号量。如在这个停车场系统中,车位是公共资源,每辆车好比一个线程,看门人起的就是...