当前位置: 代码迷 >> 综合 >> Zuul(1)--->Zuul的基本使用
  详细解决方案

Zuul(1)--->Zuul的基本使用

热度:104   发布时间:2023-10-24 14:38:31.0

1、spring-cloud-starter-netflix-zuul的基本使用

  1.1、 依赖y引入:

<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>

  1.2、激活方式

@EnableZuulProxy

@SpringBootApplication
@EnableZuulProxy
@EnableDiscoveryClient
public class ZuulService {public static void main(String[] args) {SpringApplication.run(ZuulService.class, args);}
}

  1.3、配置路由:

  Ⅰ、简化版配置方式:

zuul.routes.user-service=/userapi/**

配置说明:user-service:spring.application.name

/userapi/** :表示访问zuul服务的时候只要url中包含userapi的全部转发到user-service服务。

  Ⅱ:复杂版本配置方式:

             zuul:routes:route1:path: /userapi/**serviceId: user-serviceroute2:path: /orderapi/**serviceId: user-serviceroute3:path: /xxx/**url: http://localhost:8080/xxx-service        //xxx-service为application的name

 

2、zuul自定义filter

 2.1、 zuul是基于servlet的api网关,他允许我们自定义filter,但是这个filter 并非是Servlet 范畴的Filter,而是zuul范畴的Filter,自定义zuul范畴的Filter只要实现zuul提供的抽象类ZuulFilter即可:

案例如下:校验请求头中token:

public class TokenVerifyFilter extends ZuulFilter {@Overridepublic String filterType() {return "pre";}
?@Overridepublic int filterOrder() {return 0;}
?@Overridepublic boolean shouldFilter() {return true;}
?@Overridepublic Object run() throws ZuulException {RequestContext currentContext = RequestContext.getCurrentContext();HttpServletRequest request = currentContext.getRequest();String token = request.getHeader("token");
?if (!StringUtils.isNotEmpty(token)){
?/*通过context.setSendZuulResponse(false)可以终止请求的转发,但是只在pre类型的过滤器中设置才可以,原因是route 类型的filter 第一位就是RibbonRoutingFilter,这个filter就是用于向目标服务发起请求的,而在这个RibbonRoutingFilter的shouldFilter()里面,判断了只有currentContext的sendZuulResponse中为true才会执行RibbonRoutingFilter的run()方法去发起目标服务调用。*/
?currentContext.setSendZuulResponse(false);currentContext.setResponseStatusCode(401);currentContext.setResponseBody("unAuthrized");}return "TokenVerifyFilter";}
}

  2.2、注册自定zuulFilter:

@Bean
public TokenVerifyFilter tokenVerifyFilter(){return new TokenVerifyFilter();
}

  2.3、 zuul中提供了默认的zuulFilter列表,关系如下:

         

 

3、在zuul api网关层进行服务容/降级

zuul提供了在api网关层进行服务容错/降级处理,我们只需要实现一个FallbackProvider接口,并注册自己的容错/降级实现即可:

案例如下:如果服务调用异常那就在响应body中写入"fallback"字符串。

/*** zuul 服务容错*/
@Component
public class TestFallBbackProvider implements FallbackProvider {
?@Overridepublic String getRoute() {return "user-service";  //只对服务user-service进行Zuul网关的容错}
?@Overridepublic ClientHttpResponse fallbackResponse(String route, Throwable cause) {if (cause instanceof HystrixTimeoutException) {return response(HttpStatus.GATEWAY_TIMEOUT);} else {return response(HttpStatus.INTERNAL_SERVER_ERROR);}}
?private ClientHttpResponse response(final HttpStatus status) {return new ClientHttpResponse() {@Overridepublic HttpStatus getStatusCode() throws IOException {return status;}
?@Overridepublic int getRawStatusCode() throws IOException {return status.value();}
?@Overridepublic String getStatusText() throws IOException {return status.getReasonPhrase();}
?@Overridepublic void close() {}
?@Overridepublic InputStream getBody() throws IOException {return new ByteArrayInputStream("fallback".getBytes());}
?@Overridepublic HttpHeaders getHeaders() {HttpHeaders headers = new HttpHeaders();headers.setContentType(MediaType.APPLICATION_JSON);return headers;}};}
}

 

 

4、zuul限流

  4.1、我们可以在zuul层进行限流处理,需要引入限流依赖,依赖如下:

<dependency><groupId>com.marcosbarbero.cloud</groupId><artifactId>spring-cloud-zuul-ratelimit</artifactId><version>1.3.4.RELEASE</version>
</dependency>

  4.2、统一配置所有服务的限流规则:

zuul.ratelimit.enabled=true    : 开启zuul限流
#配置60秒内最多有两次请求
zuul.ratelimit.default-policy.limit=2
zuul.ratelimit.default-policy.refresh-interval=60
#针对url限流
zuul.ratelimit.default-policy.type=url
?
##针对IP进行限流,不影响其他IP,还可以设置为URL   IP限流就是当前IP不管请求什么接口都会进行限流
##                                         URL限流则表示只是针对某个URL进行调用者限流,同一个调用者多个URL间限流是隔离开的。
##zuul.ratelimit.default-policy.type=origin  表示IP限流
##zuul.ratelimit.default-policy.type=url     表示URL限流

4.3、正对单个服务进行限流:

zuul.ratelimit.enabled=true    : 开启zuul限流
#可以对单个服务进行限流,配置的方式如下
zuul.ratelimit.policies.user-service.limit=2
zuul.ratelimit.policies.user-service.refresh-interval=60
zuul.ratelimit.policies.user-service.type=url

 

5、zuul超时/重试控制:

默认zuul会结合ribbon、erueka、hystrix、openfeign来使用,因此控制超时时长也是需要调优一下:

# 当请求通过zuul网关路由到服务,并等待服务返回响应,这个过程中zuul也有超时控制。zuul的底层使用的是Hystrix+ribbon来实现请求路由。
# zuul中的Hystrix内部使用线程池隔离机制提供请求路由实现,其默认的超时时长为1000毫秒。ribbon底层默认超时时长为5000毫秒。
# 如果Hystrix超时,直接返回超时异常。如果ribbon超时,同时Hystrix未超时,ribbon会自动进行服务集群轮询重试,直到Hystrix超时为止。
# 如果Hystrix超时时长小于ribbon超时时长,ribbon不会进行服务集群轮询重试。因此我们会把hystrix的超时时间设置 > ribbon 超时时间。
zuul.retryable=true
# hystrix 线程池隔离,默认超时时间1000ms
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=80000
# ribbon 连接超时时间
ribbon.ConnectTimeout=5000
# ribbon请求处理的超时时间: 默认5000ms
ribbon.ReadTimeout=5000
# 重试次数:MaxAutoRetries表示访问服务集群下原节点(同路径访问),MaxAutoRetriesNextServer表示访问服务集群下其余节点(换台服务器)
ribbon.MaxAutoRetries=1
ribbon.MaxAutoRetriesNextServer=1
# ribbon 开启重试
ribbon.OkToRetryOnAllOperations=true

除此之外还要结合openfeign的超时时间来进行控制:

#设置feign的请求超时时间为2秒
feign.client.config.default.read-timeout=5000

需要引入的依赖:

<dependency><groupId>org.springframework.retry</groupId><artifactId>spring-retry</artifactId>
</dependency>

 

6、zuul动态路由:

zuul 结合spring-cloud-config 来进行路由的动态配置,当我们新加一个服务的时候,我们只需要修改spring-cloud-config-server上的zuul服务的配置,然后想办法属性路由配置即可,最简单的刷新方式就是开启zuul服务是actuator,暴露refresh端点,然后调用:localhost:6060/actuator/refresh即可刷新路由,整个过程不用重启zuul服务!!!!!!!!!!!!

步骤:

  1、将config-server 注册到eureka 上。

  2、zuul服务整合spring-cloud-config-client :

整合的配置:bootstrap.properties中:

spring.application.name=zuul-server
server.port=6060
?
#配置zuul服务的配置文件名称
spring.cloud.config.name=zuul
?
#开启配置服务从服务注册/发现的方式寻找
spring.cloud.config.discovery.enabled=true
?
#配置配置服务的 服务名称
spring.cloud.config.discovery.service-id=config-server
?
#配置eureka 地址
eureka.client.service-url.defaultZone=http://localhost:9090/eureka
?
#以web暴露所有的actuator 端点
management.endpoints.web.exposure.include=*

  3、修改config-server 上的zuul配置,例如添加路由。

  4、不重启zuul服务刷新zuul配置,使用actuator/refresh 端点来进行手动刷新,此处可改造,改造的方式很多,可自行解决,例如定时任务也可以啊。

 

7、zuul的原理:

核心类:ZuulServlet : 标准的Setvlet规范。

各种实现的ZuulFilter