Zuul是Netflix开源的微服务网关,Spring Cloud对Zuul进行了整合和增强。在Spring Cloud体系中,Zuul担任着网关的角色,对发送到服务端的请求进行一些预处理,比如安全验证、动态路由、负载均衡等。
Zuul(1.x) 基于Servlet,使用阻塞 API,它不支持任何长连接,如 WebSocket。
Netflix使用Zuul进行以下操作:认证、洞察、压力测试、金丝雀测试、动态路由、服务迁移、负载脱落、安全、静态响应处理、主动/主动流量管理等。
Zuul的主要功能是路由转发和过滤器。
路由:
负责将外部请求转发到具体的微服务实例上,是实现外部访问统一入口的基础。
过滤器:
负责对请求的拦截与过滤,是实现请求校验、权限控制、服务聚合、监控、压力测试、请求限流等功能的基础。
是Zuul实现API网关功能最为核心的部件,每一个进入Zuul的HTTP请求都会经过一系列的过滤器处理链得到请求响应并返回给客户端。
zuul默认和Ribbon结合实现了负载均衡的功能。
Hystrix和Ribbon支持
Zuul中包含了Hystrix和Ribbon的依赖,所以Zuul拥有线程隔离和断路器的自我保护功能,以及对服务调用的客户端负载均衡。传统路由也就是使用path与url映射关系来配置路由规则的时候,对于路由转发的请求不会使用HystrixCommand来包装,所以没有线程隔离和断路器的保护,并且也不会有负载均衡的能力。
Zuul中默认实现的Filter:
pre:
ServletDetectionFilter 用来检测当前请求是通过Spring的DispatcherServlet处理运行,还是通过ZuulServlet来处理运行的。
Servlet30WrapperFilter 将原始的HttpServletRequest包装成Servlet30RequestWrapper对象。
FormBodyWrapperFilter 将符合要求的请求体包装成FormBodyRequestWrapper对象。该过滤器仅对两种类请求生效,第一类是Content-Type为application/x-www-form-urlencoded的请求,第二类是Content-Type为multipart/form-data并且是由Spring的DispatcherServlet处理的请求。
PreDecorationFilter 处理请求上下文供后续使用。
route:
RibbonRoutingFilter 该过滤器只对请求上下文中存在serviceId参数的请求进行处理,即只对通过serviceId配置路由规则的请求生效。它通过使用Ribbon和Hystrix来向服务实例发起请求,并将服务实例的请求结果返回。
SimpleHostRoutingFilter 该过滤器只对请求上下文中存在routeHost参数的请求进行处理,即只对通过url配置路由规则的请求生效。该请求是直接通过httpclient包实现的,而没有使用Hystrix命令进行包装,所以这类请求并没有线程隔离和断路器的保护。
SendForwardFilter 该过滤器只对请求上下文中存在forward.to参数的请求进行处理,即用来处理路由规则中的forward本地跳转配置。
post:
SendErrorFilter 该过滤器仅在请求上下文中包含error.status_code参数并且还没有被该过滤器处理过的时候执行。
SendResponseFilter 该过滤器会检查请求上下文中是否包含请求响应相关的头信息、响应数据流或是响应体,只有在包含它们其中一个的时候就会执行处理逻辑。
创建Zuul服务网关工程:
pom.xml文件的关键配置:
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.7.RELEASE</version> <relativePath/> </parent> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-zuul</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-dependencies</artifactId> <version>Finchley.RELEASE</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>
application.properties文件的配置:
spring.application.name=service-zuul server.port=3001 eureka.instance.hostname=${spring.cloud.client.ip-address} eureka.instance.instance-id=${spring.cloud.client.ip-address}:${server.port} eureka.instance.prefer-ip-address=true #注册中心地址 eureka.client.service-url.defaultZone=http://root:123456@${eureka.instance.hostname}:7001/eureka/ #服务路由规则配置 zuul.routes.a.path=/api-a/** zuul.routes.a.serviceId=service-consumer-1 #zuul.routes.a.url=http://localhost:9002/ zuul.routes.b.path=/api-b/** zuul.routes.b.serviceId=service-consumer-2 #zuul.routes.service-consumer-2=/api-b/**
规则配置详解:
格式: zuul.routes.<路由名>.属性名 ,路由名可随意定义
对于面向服务的路由配置有一种更简单的方式:zuul.routes.<服务名>=<映射地址>
path: 定义一个用来匹配客户端请求的路径表达式
serviceId: 指定请求表达式映射具体的服务名。服务路由配置时使用该属性
当同一服务名下有多个服务实例时,默认是采用轮询的负载均衡策略,通过在启动类配置负载均衡Bean类可以更改默认策略。
url: 指定请求表达式映射具体的实例地址。传统路由配置时使用该属性
假如网关根地址是http://localhost:3001,微服务根地址是http://localhost:9002,那么请求地址http://localhost:3001/api-b/addUser会路由到http://localhost:9002/addUser微服务地址。
启动类:
@SpringBootApplication @EnableEurekaClient @EnableZuulProxy //开启zuul功能 public class Main { public static void main(String[] args) { SpringApplication.run(Main.class, args); } } /** * 更改zull服务路由的负载均衡策略 */ @Bean public IRule feignRule(){ return new RandomRule(); //随机 }
忽略指定路径
设置不希望被API网关进行路由的URL表达式
zuul.ignored-patterns=/**/hello/** #忽略所有包含/hello/的路径
忽略服务路由的默认配置
Zuul注册到Eureka服务中心后,它会为Eureka中的每个服务都创建一个默认的路由规则,默认规则的path会使用serviceId配置的服务名作为请求前缀,如http://localhost:9002/service-consumer-2/addUser
可以使用zuul.ignored-services参数来设置一个不自动创建该服务的默认路由,多个服务名之间用逗号分隔。如
zuul.ignored-services=service-consumer-1,service-consumer-2
忽略所有服务
zuul.ignored-services=*
路由前缀
默认情况下,路径表达式的前缀会被移除掉。可以使用zuul.strip-prefix=false来关闭移除前缀的动作,也可以通过zuul.routes.<路由名>.strip-prefix=false来指定服务关闭移除前缀的动作
本地跳转
zuul.routes.<路由名>.url=forward:/<要跳转到的端点>
禁用过滤器
zuul.<过滤器名>.<过滤器类型>.disable=true
自定义过滤器
Zuul服务网关的很多基础功能都可以通过自定义过滤器来实现。自定义过滤器需要继承ZuulFilter类。
@Component public class DefaultZuulFilter extends ZuulFilter { /** * 过滤器类型,它决定过滤器在请求的哪个生命周期中执行。 * pre:路由之前 * route:路由之时 * post: 路由之后 * error:处理请求发生错误时调用 */ @Override public String filterType() { return FilterConstants.PRE_TYPE; } /** * filter执行顺序 * 数字越大,优先级越低 */ @Override public int filterOrder() { return 0; } /** * 判断该过滤器是否需要被执行。 */ @Override public boolean shouldFilter() { return true; } /** * 过滤器的具体逻辑:可以查询数据库判断是否有访问权限 */ @Override public Object run() { RequestContext requestContext = RequestContext.getCurrentContext(); HttpServletRequest request = requestContext.getRequest(); Object token = request.getParameter("token"); if(token == null) { requestContext.setSendZuulResponse(false); //过滤该请求,不对其进行路由 requestContext.setResponseStatusCode(401); //返回的错误码 try { requestContext.getResponse().getWriter().write("token is empty"); }catch (Exception ex){ ex.printStackTrace(); } return null; } return null; } }
路由熔断处理
默认情况下,当Zuul调用后端服务出现异常时,异常会抛出给最外层。 为了避免这种情况的发生,可以通过自定义Fallback类来处理。自定义Fallback类需要实现FallbackProvider接口类。
Consumer1FallbackProvider类:
/** * 回退类:Zuul路由熔断时调用 * Zuul目前只支持服务级别的熔断,不支持具体到某个URL进行熔断。 */ @Component public class Consumer1FallbackProvider implements FallbackProvider{ // private String serviceName = "service-consumer-1"; //为指定微服务提供回退 private String serviceName = "*"; //为所有微服务提供回退 /** * 表明是为哪个微服务提供回退 */ @Override public String getRoute() { return serviceName; } /** * 回退的响应对象 */ @Override public ClientHttpResponse fallbackResponse(String route, Throwable cause) { return new DefaultClientHttpResponse(route); } }
DefaultClientHttpResponse类:
public class DefaultClientHttpResponse implements ClientHttpResponse { private String route; public DefaultClientHttpResponse(String route){ this.route = route; } /** * 响应体 */ @Override public InputStream getBody() throws IOException { String result = ""; try { JSONObject object = new JSONObject(); object.put("code", "999"); object.put("message", route + " 不可用!"); result = object.toString(); } catch (JSONException e) { e.printStackTrace(); } return new ByteArrayInputStream(result.getBytes()); } @Override public HttpHeaders getHeaders() { HttpHeaders headers = new HttpHeaders(); headers.setContentType(MediaType.APPLICATION_JSON_UTF8); return headers; } @Override public HttpStatus getStatusCode() throws IOException { //fallback时的状态码 return HttpStatus.OK; } @Override public int getRawStatusCode() throws IOException { //数字类型的状态码 return this.getStatusCode().value(); } @Override public String getStatusText() throws IOException { //状态文本 return this.getStatusCode().getReasonPhrase(); } @Override public void close() { } }
相关推荐
SpringCloud Zuul是基于Spring Cloud框架的一个核心组件,它扮演着API网关的角色,负责路由转发、过滤器处理以及安全控制等任务。Zuul的主要功能包括动态路由、过滤器机制、安全控制、负载均衡、健康检查等。下面将...
SpringCloud Zuul Gateway 服务网关是Spring Cloud生态系统中的一个重要组件,它主要负责微服务架构中的路由转发和过滤器功能。Zuul是Netflix开源的一个边缘服务,而Gateway则是Spring Cloud针对Zuul进行的升级版,...
在本篇学习笔记中,我们将深入探讨Spring Cloud框架中的一个重要组件——Spring Cloud Zuul,它作为微服务架构中的路由网关和负载均衡器。Spring Cloud是基于Java的微服务工具集,它为开发者提供了在分布式系统(如...
在本篇学习笔记中,我们将深入探讨Spring Cloud框架中的一个重要组件——Spring Cloud Zuul,它是一个强大的路由网关。Zuul的主要职责是为微服务架构提供统一的入口,进行请求过滤、路由转发等操作,使得后端服务对...
首先,Spring Cloud Zuul是Spring Cloud生态中的一个边缘服务工具,它作为一个API网关,负责处理所有客户端的请求。作为前端和后端服务之间的桥梁,Zuul可以实现动态路由、过滤、安全控制、负载均衡等功能,简化了...
SpringCloud Zuul是Spring Cloud生态系统中的一个边缘服务和API网关组件。它的主要功能是作为微服务架构中的统一入口,负责路由转发、过滤器处理、负载均衡以及安全控制等任务。Zuul允许开发者在微服务架构中实现...
**Spring Cloud Zuul** 是一个基于 Spring Framework 和 Netflix Zuul 的边缘服务工具,它作为微服务架构中的边缘服务器,提供动态路由、流量控制、安全、监控等功能。Zuul 主要是作为 API 网关,它负责处理所有来自...
springcloud zuul 网关开发实践,模拟了在Spring Cloud微服务系统中,客户端的请求首先经过负载均衡(zuul、Ngnix),再到达服务网关(zuul集群),然后再到具体的服的实现过程。
接下来,Zuul是Spring Cloud的边缘服务,也是一个API网关。`demo-zuul-master.zip`中的代码展示了如何设置和使用Zuul。Zuul可以处理所有来自客户端的请求,执行如认证、路由、过滤等操作。它将请求转发到合适的...
Spring Cloud Zuul:API网关服务详解 Spring Cloud Zuul 是 Spring Cloud Netflix 子项目的核心组件之一,可以作为微服务架构中的 API 网关使用,支持动态路由与过滤功能。API 网关为微服务架构中的服务提供了统一...
Spring Cloud Zuul网关 Spring Cloud Zuul网关是微服务架构中的一种网关解决方案,主要用于解决微服务之间的调用和路由问题。在本章节中,我们将了解Zuul网关的基本概念和使用方法,以及如何将其应用于微服务架构...
SpringCloud Zuul网关功能实现解析 SpringCloud Zuul网关功能实现解析是基于 SpringCloud 生态系统的微服务架构中的一种网关解决方案。 Zuul 是 Netflix 公司开源的一个基于 Java 的 API Gateway 项目,旨在提供一...
在"Spring Cloud Zuul动态路由demo"中,我们将看到如何创建Config Server项目,配置Eureka,然后编写Zuul服务,实现动态路由配置的加载和变更。同时,你还可以学习如何编写自定义过滤器,以及如何测试动态路由功能...
Spring Cloud 使用 Zuul 实现 API 网关服务问题 在本文中,我们将主要介绍如何使用 Spring Cloud 的 Zuul 组件来实现 API 网关服务问题。 Zuul 是一个基于 Netflix Zuul 的 API 网关组件,它可以解决路由规则和服务...
Zuul是Spring Cloud生态中的一个关键组件,它扮演着边缘服务的角色,负责微服务间的路由转发和过滤器功能。本文将深入探讨Spring Cloud Zuul在微服务架构中的应用和重要性。 1. **Zuul简介** Zuul是Netflix开源的...
Spring Cloud Zuul是Spring Cloud生态系统中的一个边缘服务和API网关组件。它作为一个过滤器路由,为微服务架构提供统一的入口,同时处理预处理、安全、限流等功能。这篇博客文章“Spring Cloud Zuul使用”可能详细...
SpringCloud-2.0-service-zuul-80 代表了Zuul服务网关,它是所有微服务请求的统一入口。Zuul的主要职责有: 1. 路由转发:根据请求路径将请求转发到对应的服务提供者,实现服务间的解耦。 2. 访问过滤:Zuul提供了...
Spring Cloud Zuul是基于Spring Boot实现的微服务网关,它提供路由转发、过滤器等功能,使得客户端可以方便地访问到后端微服务。在这个示例中,Zuul与Consul结合,使得Zuul能够动态地发现注册在Consul中的服务,实现...
Spring Cloud Zuul 是一个基于 Java 的边缘服务,它可以作为 API 网关,对微服务架构中的所有请求进行路由。Zuul 提供了过滤器机制(Zuul Filters),类似于 Spring 的面向切面编程(AOP),可以实现预处理、路由、...