Spring Cloud Zuul微服务总结及其项目入门实例
应公司要求项目采用新技术Spring Cloud,团队中每个人负责一小块,我负责的部分是Zuul部分。
运行环境
jdk7+IntelliJ IDEA+maven
项目技术
Spring Cloud
一、定义(Zuul是什么?)
传统访问服务,HTTP请求
API Gateway作为轻量级网关(模式)
在微服务架构中,后端服务往往不直接开放给调用端,而是通过一个API网关根据请求的url,路由到相应的服务。当添加API网关后,在第三方调用端和服务提供方之间就创建了一面墙,这面墙直接与调用方通信进行权限控制,后将请求均衡分发给后台服务端。
1、简化客户端调用复杂度
实现相关的认证逻辑从而简化内部服务之间相互调用的复杂度。
2、对返回数据的处理(裁剪与聚合)
不同的客户端对于显示时对于数据的需求是不一致的
手机端
Web端
低延迟的网络环境
高延迟的网络环境
API Gateway对通用性的响应数据进行裁剪以适应不同客户端的使用需求,还可以将多个API调用逻辑进行聚合,从而减少客户端的请求数,优化客户端用户体验。
3、多渠道支持
针对不同的渠道和客户端提供不同的API Gateway(手机端、web端,电脑端)
4、遗留系统的微服务化改造
原有的系统存在或多或少的问题,比如技术债务,代码质量,可维护性,可扩展性等等。API Gateway的模式同样适用于这一类遗留系统的改造,通过微服务化的改造逐步实现对原有系统中的问题的修复,从而提升对于原有业务响应力的提升。通过引入抽象层,逐步使用新的实现替换旧的实现。
在Spring Cloud体系中, Spring Cloud Zuul就是提供负载均衡、反向代理、权限认证的一个API gateway。是对API gateway模式的一种实现。
Spring Cloud Zuul路由是微服务架构的的一部分,提供动态路由,监控,弹性,安全等的边缘服务。Zuul是Netflix出品的一个基于JVM路由和服务端的负载均衡器。
1、添加依赖,引入spring-cloud-starter-zuul包
三、Zuul过滤器运行机制
Filter是Zuul的核心,用来实现对外服务的控制。Filter的生命周期有4个,分别是“PRE”、“ROUTING”、“POST”、“ERROR”,整个生命周期可以用下图来表示。
HTTP请求的一个生命周期
用户或者外部应用发送请求到Zuul,Zuul提供了四类过滤器,四类过滤器是指的四个阶段,不是具体的过滤器,每个阶段都包含若干个过滤器。
1、首先“pre”过滤器,这种过滤器在请求被路由之前调用。我们可利用这种过滤器实现身份验证、在集群中选择请求的微服务、记录调试信息、对参数进行一些设置等。对请求进行一个预处理。
2、然后“routing”过滤器进行处理,这种过滤器将请求路由到微服务。这种过滤器用于构建发送给微服务的请求,并使用Apache HttpClient或Netfilx Ribbon请求微服务。这个阶段的过滤器会对请求进行一个转发,获取响应,调取语言服务。真正进行转发的是routing过滤器。
3、若出现异常调用error过滤器。在其他阶段发生错误时执行该过滤器。 除了默认的过滤器类型,Zuul还允许我们创建自定义的过滤器类型。例如,我们可以定制一种STATIC类型的过滤器,直接在Zuul中生成响应,而不将请求转发到后端的微服务。
4、这种过滤器在路由到微服务以后执行。这种过滤器可用来为响应添加标准的HTTP Header、收集统计信息和指标、将响应从微服务发送给客户端等。
四、自定义Filter
实现自定义Filter,需要继承ZuulFilter的类,并覆盖其中的4个方法。
将TokenFilter加入到请求拦截队列,在启动类中添加以下代码:
当我们的后端服务出现异常的时候,我们不希望将异常抛出给最外层,期望服务可以自动进行一降级。Zuul给我们提供了这样的支持。当某个服务出现异常时,直接返回我们预设的信息。
我们通过自定义的fallback方法,并且将其指定给某个route来实现该route访问出问题的熔断处理。主要继承ZuulFallbackProvider接口来实现,ZuulFallbackProvider默认有两个方法,一个用来指明熔断拦截哪个服务,一个定制返回内容。
实现类通过实现getRoute方法,告诉Zuul它是负责哪个route定义的熔断。而fallbackResponse方法则是告诉 Zuul 断路出现时,它会提供一个什么返回值来处理请求。
后来Spring又扩展了此类,丰富了返回方式,在返回的内容中添加了异常信息,因此最新版本建议直接继承类FallbackProvider 。
我们以上面的spring-cloud-producer服务为例,定制它的熔断返回内容。
当服务出现异常时,打印相关异常信息,并返回”The service is unavailable.”。
启动项目spring-cloud-producer-2,这时候服务中心会有两个spring-cloud-producer项目,我们重启Zuul项目。再手动关闭spring-cloud-producer-2项目(注意:这里先要启动服务中心Eurka,spring-cloud-producer,再启动spring-cloud-producer-2),多次访问地址:http://localhost:8888/spring-cloud-producer/hello?name=neo&token=xx,会交替返回:
根据返回结果可以看出:spring-cloud-producer-2项目已经启用了熔断,返回:The service is unavailable.
Zuul 目前只支持服务级别的熔断,不支持具体到某个URL进行熔断。
六、路由重试
有时候因为网络或者其它原因,服务可能会暂时的不可用,这个时候我们希望可以再次对服务进行重试,Zuul也帮我们实现了此功能,需要结合Spring Retry 一起来实现。下面我们以上面的项目为例做演示。
添加Spring Retry依赖
首先在spring-cloud-zuul项目中添加Spring Retry依赖。
开启Zuul Retry
再配置文件中配置启用Zuul Retry
这样我们就开启了Zuul的重试功能。
测试
我们对spring-cloud-producer-2进行改造,在hello方法中添加定时,并且在请求的一开始打印参数。
重启 spring-cloud-producer-2和spring-cloud-zuul项目。
访问地址:http://localhost:8888/spring-cloud-producer/hello?name=neo&token=aa,当页面返回:The service is unavailable.时查看项目spring-cloud-producer-2后台日志如下:
说明进行了三次的请求,也就是进行了两次的重试。这样也就验证了我们的配置信息,完成了Zuul的重试功能。
是否原创(转载必填原文地址)
否,原文代码地址https://github.com/ityouknow/spring-cloud-examples
注意事项
开启重试在某些情况下是有问题的,比如当压力过大,一个实例停止响应时,路由将流量转到另一个实例,很有可能导致最终所有的实例全被压垮。说到底,断路器的其中一个作用就是防止故障或者压力扩散。用了retry,断路器就只有在该服务的所有实例都无法运作的情况下才能起作用。这种时候,断路器的形式更像是提供一种友好的错误信息,或者假装服务正常运行的假象给使用者。
不用retry,仅使用负载均衡和熔断,就必须考虑到是否能够接受单个服务实例关闭和eureka刷新服务列表之间带来的短时间的熔断。如果可以接受,就无需使用retry。
七、Zuul高可用
不同的客户端使用不同的负载将请求分发到后端的Zuul,Zuul在通过Eureka调用后端服务,最后对外输出。因此为了保证Zuul的高可用性,前端可以同时启动多个Zuul实例进行负载,在Zuul的前端使用Nginx或者F5进行负载转发以达到高可用性。
猜你喜欢
- SpringCloud入门项目实例
- SpringCloud微服务的项目架构搭建及Springboot应用实例
- 基于Spring Boot、Spring Cloud、Spring Oauth2 和 Spring Cloud Netflix 等框架构建的微服务项目
- SpringCloud入门项目简单实例,包括eureka集群和服务注册者
- springcloud微服务架构项目搭建实例,基于maven多模块搭建
- springcloud alibaba+springboot开发个人博客微服务版本的demo实例,通过接口测试服务发现,监控,降级
- spring cloud简单的框架搭建实例
- 微服务spring cloud入门demo实例
- Spring Cloud微服务架构服务注册与消费实例
- spring cloud简单的demo例子,适合初学者
- Spring Cloud微服务架构项目搭建实例,微服务组件介绍,基于maven多模块搭建
- java web开发简单文件上传后端服务项目
- /
- /spring-cloud-zuul
- /spring-cloud-zuul/.idea
- /spring-cloud-zuul/.idea/.name
- /spring-cloud-zuul/.idea/compiler.xml
- /spring-cloud-zuul/.idea/encodings.xml
- /spring-cloud-zuul/.idea/libraries
- /spring-cloud-zuul/.idea/libraries/Maven__antlr_antlr_2_7_7.xml
- /spring-cloud-zuul/.idea/libraries/Maven__aopalliance_aopalliance_1_0.xml
- /spring-cloud-zuul/.idea/libraries/Maven__ch_qos_logback_logback_classic_1_1_11.xml
- /spring-cloud-zuul/.idea/libraries/Maven__ch_qos_logback_logback_core_1_1_11.xml
- /spring-cloud-zuul/spring-cloud-eureka
- /spring-cloud-zuul/spring-cloud-eureka/src
- /spring-cloud-zuul/spring-cloud-eureka/src/main
- /spring-cloud-zuul/spring-cloud-eureka/src/main/java
- /spring-cloud-zuul/spring-cloud-eureka/src/main/java/com
- /spring-cloud-zuul/spring-cloud-eureka/src/main/java/com/neo
- /spring-cloud-zuul/spring-cloud-eureka/src/main/java/com
- /spring-cloud-zuul/spring-cloud-eureka/src/main/java
- /spring-cloud-zuul/spring-cloud-eureka/src/test
- /spring-cloud-zuul/spring-cloud-eureka/src/test/java
- /spring-cloud-zuul/spring-cloud-eureka/src/test/java/com
- /spring-cloud-zuul/spring-cloud-eureka/src/test/java/com/neo
- /spring-cloud-zuul/spring-cloud-eureka/src/test/java/com
- /spring-cloud-zuul/spring-cloud-eureka/src/test/java
- /spring-cloud-zuul/spring-cloud-eureka/src/main
- /spring-cloud-zuul/spring-cloud-eureka/src
- /spring-cloud-zuul/spring-cloud-producer
- /spring-cloud-zuul/spring-cloud-producer/src
- /spring-cloud-zuul/spring-cloud-producer/src/main
- /spring-cloud-zuul/spring-cloud-producer/src/main/java
- /spring-cloud-zuul/spring-cloud-producer/src/main/java/com
- /spring-cloud-zuul/spring-cloud-producer/src/main/java/com/neo
/spring-cloud-zuul/spring-cloud-producer/src/main/java/com/neo/ProducerApplication.java
- /spring-cloud-zuul/spring-cloud-producer/src/main/java/com/neo/controller
- /spring-cloud-zuul/spring-cloud-producer/src/main/java/com/neo
- /spring-cloud-zuul/spring-cloud-producer/src/main/java/com
- /spring-cloud-zuul/spring-cloud-producer/src/main/java
- /spring-cloud-zuul/spring-cloud-producer/src/test
- /spring-cloud-zuul/spring-cloud-producer/src/test/java
- /spring-cloud-zuul/spring-cloud-producer/src/test/java/com
- /spring-cloud-zuul/spring-cloud-producer/src/test/java/com/neo
- /spring-cloud-zuul/spring-cloud-producer/src/test/java/com
- /spring-cloud-zuul/spring-cloud-producer/src/test/java
- /spring-cloud-zuul/spring-cloud-producer/src/main
- /spring-cloud-zuul/spring-cloud-producer/src
- /spring-cloud-zuul/.idea
- /spring-cloud-zuul
- 原 SpringCloud入门项目实例
- 原证 SpringCloud入门项目简单实例,包括eureka集群和服务注册者
- 原 SpringCloud微服务的项目架构搭建及Springboot应用实例
- 原证 springcloud微服务架构项目搭建实例,基于maven多模块搭建
- 原证 springcloud alibaba+springboot开发个人博客微服务版本的demo实例,通过接口测试服务发现,监控,降级
- 原 spring cloud简单的demo例子,适合初学者
- spring cloud简单的框架搭建实例
- 原 基于Spring Boot、Spring Cloud、Spring Oauth2 和 Spring Cloud Netflix 等框架构建的微服务项目
- 微服务spring cloud入门demo实例
- 原 spring cloud集成swagger2和配置数据源
- 原 Spring Cloud学习(一)之构建微服务架构:服务注册与发现(Eureka、Consul)博客源码
- 原 spring cloud之服务消费(基础)LoadBalancerClient使用