Spring Cloud

2016年,我在博客中发表过一篇《微服务架构的基础框架选择:Spring Cloud还是Dubbo?》获得了很大的阅读量和转载量。在这篇文章中,我主要对比了Spring Cloud与Dubbo所具备的能力,并阐述了个人推崇Spring Cloud的原因。但是,最近各大技术社区出现了不少类似的文章,观点比较激进,对于Spring Cloud的褒扬远胜于Dubbo,但是这些评价很多都忽略了Spring Cloud与Dubbo在设计视角上的不同。其实在前文中我也说明了Dubbo与Spring Cloud的对比本身就不公平,因为两者产出的目标格局是不一样的。所以,就目前阶段来说,大家对于框架的选择上,还是要综合考虑自身团队与遗留业务系统的特点来确定更合适的技术栈,而不是盲从于“时髦”的架构体系。 昨天看到了开源中国对Dubbo社区维护者的访谈,内容非常不错。所以这里分享给大家。其实,在最近...

之前在写Spring Boot基础教程的时候写过一篇《Spring Boot中使用RabbitMQ》。在该文中,我们通过简单的配置和注解就能实现向RabbitMQ中生产和消费消息。实际上我们使用的对RabbitMQ的starter就是通过Spring Cloud Stream中对RabbitMQ的支持来实现的。下面我们就通过本文来了解一下Spring Cloud Stream。 Spring Cloud Stream是一个用来为微服务应用构建消息驱动能力的框架。它可以基于Spring Boot来创建独立的、可用于生产的Spring应用程序。它通过使用Spring Integration来连接消息代理中间件以实现消息事件驱动的微服务应用。Spring Cloud Stream为一些供应商的消息中间件产品提供了个性化的自动化配置实现,并且引入了发布-订阅、消费组以及消息分区这三个核心概念...

通常微服务架构中的依赖通过远程调用实现,而远程调用中最常见的问题就是通信消耗与连接数占用。在高并发的情况之下,因通信次数的增加,总的通信时间消耗将会变的不那么理想。同时,因为对依赖服务的线程池资源有限,将出现排队等待与响应延迟的情况。为了优化这两个问题,Hystrix提供了HystrixCollapser来实现请求的合并,以减少通信消耗和线程数的占用。 HystrixCollapser实现了在HystrixCommand之前放置一个合并处理器,它将处于一个很短时间窗(默认10毫秒)内对同一依赖服务的多个请求进行整合并以批量方式发起请求的功能(服务提供方也需要提供相应的批量实现接口)。通过HystrixCollapser的封装,开发者不需要去关注线程合并的细节过程,只需要关注批量化服务和处理。下面我们从HystrixCollapser的使用实例,对其合并请求的过程一探究竟。 Hystr...

在微服务架构下,你的服务可能由不同的团队提供和维护,在这种情况下,接口的开发和维护可能会带来一些问题,比如服务端调整架构或接口调整而对消费者不透明,导致接口调用失败。 为解决这些问题,Ian Robinson提出了一个以服务消费者定义契约为驱动的开发模式:“Consumer-Driver Contracts(CDC)”,就是:消费者驱动契约。 通常我们开发中主要由服务提供方约定接口,虽然提供方架构调整或改变接口之前通常会通知消费者,但可能还存在上述风险,如果上线出现问题就GG了,而CDC则是以消费者提出接口契约,交由服务提供方实现,并以测试用例对契约进行产生约束,所以服务提供方在满足测试用例的情况下可以自行更改接口或架构实现而不影响消费者。 消费者驱动的契约测试(Consumer-Driven Contracts,简称CDC),是指从消费者业务实现的角度出发,驱动出契约,再基于契约...

简介本文章对应spring cloud的版本为(Dalston.SR4),具体内容如下: 开启Zuul功能 通过源码了解Zuul的一次转发 怎么开启zuul的重试机制 Edgware.RC1版本的优化 开启Zuul的功能首先如何使用spring cloud zuul完成路由转发的功能,这个问题很简单,只需要进行如下准备工作即可: 注册中心(Eureka Server) zuul(同时也是Eureka Client) 应用服务(同时也是Eureka Client) 我们希望zuul和后端的应用服务同时都注册到Eureka Server上,当我们访问Zuul的某一个地址时,对应其实访问的是后端应用的某个地址,从而从这个地址返回一段内容,并展现到浏览器上。 注册中心(Eureka Server)创建一个Eureka Server只需要在主函数上添加@EnableEurekaServ...

如何在Zuul中使用fallback功能我们在项目中使用Spring cloud zuul的时候,有一种这样的需求,就是当我们的zuul进行路由分发时,如果后端服务没有启动,或者调用超时,这时候我们希望Zuul提供一种降级功能,而不是将异常暴露出来。 在Dalston版本中,Spring cloud zuul提供这种降级功能,操作步骤如下: 在主函数上添加@EnbaleZuulProxy注解。 实现ZuulFallbackProvider接口。 对应ZuulFallbackProvider源码如下: public interface ZuulFallbackProvider { /** * The route this fallback will be used for. * @return The route the fallback will be used f...

前言我们知道Eureka分为两部分,Eureka Server和Eureka Client。Eureka Server充当注册中心的角色,Eureka Client相对于Eureka Server来说是客户端,需要将自身信息注册到注册中心。本文主要介绍的就是在Eureka Client注册到Eureka Server时RetryableClientQuarantineRefreshPercentage参数的使用技巧。 Eureka Client注册过程分析Eureka Client注册到Eureka Server时,首先遇到第一个问题就是Eureka Client端要知道Server的地址,这个参数对应的是eureka.client.service-url.defaultZone举个例子,在Eureka Client的properties文件中配置如下: eureka.client....

本篇源于Spring Cloud Config的一个问题,但这个问题并非所有人都会遇到。如果您遇到了,那必须得看看这篇,如果没有遇到您也应该看看,防患于未然! 问题描述之前有朋友提出Spring Cloud Config的配置中心在运行一段时间之后,发现修改了配置信息,但是微服务应用并拿不到新的配置内容。同时,发现配置中心存储配置的目录/tmp 的配置内容被清空了。 原因与解决首先,分析一下上面的问题,其实已经有一定的线索。表面现象是微服务从配置中心获取配置信息的时候获取不到最新的配置,而其根本原因就是在/tmp目录下的缓存仓库已经被清空了,所以导致无法正常的通过Git获取到最新配置,那么自然各个微服务应用就无法获取最新配置了。 其实该问题在Spring Cloud的官方文档中也有对应的说明,原文如下: With VCS based backends (git, svn) fi...

这里推荐一个不错的Spring Cloud系列讲座,讲师简介如下: 小马哥,阿里巴巴技术专家,从事十余年Java EE 开发,国内微服务技术讲师。目前主要负责微服务技术推广、架构设计、基础设施、迁移等。重点关注云计算、微服务以及软件架构等领域。获得过 SUN Java(SCJP、SCWCD、SCBCD)以及 Oracle OCA 等的认证。 系列套餐 打包购买更实惠! Java 微服务实践 - Spring Boot Java 微服务实践 - Spring Cloud Java 微服务实践 - Spring Boot / Spring Cloud 讲座大纲 Java 微服务实践 - Spring Cloud 系列(一)云原生应用 Java 微服务实践 - Spring Cloud 系列(二)配置客户端 Java 微服务实践 - Spring Cloud 系列(三)配置服务器...

路径匹配不论是使用传统路由的配置方式还是服务路由的配置方式,我们都需要为每个路由规则定义匹配表达式,也就是上面所说的path参数。在Zuul中,路由匹配的路径表达式采用了Ant风格定义。 Ant风格的路径表达式使用起来非常简单,它一共有下面这三种通配符: 通配符 说明 ? 匹配任意的单个字符 * 匹配任意数量的字符 ** 匹配任意数量的字符,支持多级目录 我们可以通过下表的示例来进一步理解这三个通配符的含义并参考着来使用: URL路径 说明 /user-service/? 它可以匹配/user-service/之后拼接一个任务字符的路径,比如:/user-service/a、/user-service/b、/user-service/c /user-service/* 它可以匹配/user-service/之后拼接任意字符的路径,比如:/...

上一篇我们介绍了如何使用Ribbon的earger-load配置加速Spring Cloud中对服务接口的第一次调用。可是这样只是解决了内部服务间的调用,另外一个问题依然经常困扰我们,那就是网关到内部服务的访问。由于Spring Cloud Zuul的路由转发也是通过Ribbon实现负载均衡的,所以它也会存在第一次调时比较慢的情况。那么这个时候我们要如何设置呢? Zuul中的Eager Load配置在Spring Cloud Zuul中也提供了一个配置参数来实现earger-load,具体如下: zuul.ribbon.eager-load.enabled=true 但是,可能你尝试一下之后会发现,并没有起效?为什么呢?这是由于Spring Cloud Zuul中实现eager-load的时候同Ribbon中一样,都需要指定具体哪些服务需要饥饿加载。那么在Spring Cloud...

我们在使用Spring Cloud的Ribbon或Feign来实现服务调用的时候,如果我们的机器或网络环境等原因不是很好的话,有时候会发现这样一个问题:我们服务消费方调用服务提供方接口的时候,第一次请求经常会超时,而之后的调用就没有问题了。下面我们就来说说造成这个问题的原因,以及如何解决的方法。 问题原因造成第一次服务调用出现失败的原因主要是Ribbon进行客户端负载均衡的Client并不是在服务启动的时候就初始化好的,而是在调用的时候才会去创建相应的Client,所以第一次调用的耗时不仅仅包含发送HTTP请求的时间,还包含了创建RibbonClient的时间,这样一来如果创建时间速度较慢,同时设置的超时时间又比较短的话,很容易就会出现上面所描述的显现。 从日志中我们也能知道这一点细节,在第一次发起调用的时候我们可以从日志中看到如下信息: 2017-09-25 08:29:54,...

在前两篇文章:服务网关(基础)、服务网关(路由配置)中,我们了解了Spring Cloud Zuul作为网关所具备的最基本功能:路由。本文我们将具体介绍一下Spring Cloud Zuul的另一项核心功能:过滤器。 过滤器的作用通过上面所述的两篇我们,我们已经能够实现请求的路由功能,所以我们的微服务应用提供的接口就可以通过统一的API网关入口被客户端访问到了。但是,每个客户端用户请求微服务应用提供的接口时,它们的访问权限往往都需要有一定的限制,系统并不会将所有的微服务接口都对它们开放。然而,目前的服务路由并没有限制权限这样的功能,所有请求都会被毫无保留地转发到具体的应用并返回结果,为了实现对客户端请求的安全校验和权限控制,最简单和粗暴的方法就是为每个微服务应用都实现一套用于校验签名和鉴别权限的过滤器或拦截器。不过,这样的做法并不可取,它会增加日后的系统维护难度,因为同一个系统中的各...

在上一篇《Spring Cloud构建微服务架构:服务网关(基础)》一文中,我们通过使用Spring Cloud Zuul构建了一个基础的API网关服务,同时也演示了Spring Cloud Zuul基于服务的自动路由功能。在本文中,我们将进一步详细地介绍关于Spring Cloud Zuul的路由功能,以帮助读者可以更好的理解和使用它,以完成更复杂的路由配置。 传统路由配置所谓的传统路由配置方式就是在不依赖于服务发现机制的情况下,通过在配置文件中具体指定每个路由表达式与服务实例的映射关系来实现API网关对外部请求的路由。 没有Eureka和Consul的服务治理框架帮助的时候,我们需要根据服务实例的数量采用不同方式的配置来实现路由规则: 单实例配置:通过一组zuul.routes.<route>.path与zuul.routes.<route>.url参数...

通过之前几篇Spring Cloud中几个核心组件的介绍,我们已经可以构建一个简略的(不够完善)微服务架构了。比如下图所示: 我们使用Spring Cloud Netflix中的Eureka实现了服务注册中心以及服务注册与发现;而服务间通过Ribbon或Feign实现服务的消费以及均衡负载;通过Spring Cloud Config实现了应用多环境的外部化配置以及版本管理。为了使得服务集群更为健壮,使用Hystrix的融断机制来避免在微服务架构中个别服务出现异常时引起的故障蔓延。 在该架构中,我们的服务集群包含:内部服务Service A和Service B,他们都会注册与订阅服务至Eureka Server,而Open Service是一个对外的服务,通过均衡负载公开至服务调用方。本文我们把焦点聚集在对外服务这块,这样的实现是否合理,或者是否有更好的实现方式呢? 先来说说这样架构...