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

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-service
                      
                   route2:
                      path: /orderapi/**
                      serviceId: user-service
                      
                   route3:
                      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 {
    @Override
    public String filterType() {
        return "pre";
    }
​
    @Override
    public int filterOrder() {
        return 0;
    }
​
    @Override
    public boolean shouldFilter() {
        return true;
    }
​
    @Override
    public 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 {
​
    @Override
    public String getRoute() {
        return "user-service";  //只对服务user-service进行Zuul网关的容错
    }
​
    @Override
    public 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() {
            @Override
            public HttpStatus getStatusCode() throws IOException {
                return status;
            }
​
            @Override
            public int getRawStatusCode() throws IOException {
                return status.value();
            }
​
            @Override
            public String getStatusText() throws IOException {
                return status.getReasonPhrase();
            }
​
            @Override
            public void close() {
            }
​
            @Override
            public InputStream getBody() throws IOException {
                return new ByteArrayInputStream("fallback".getBytes());
            }
​
            @Override
            public 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

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值