Spring Cloud (随笔)- Zuul

Spring Cloud - Zuul


请求路由,负载均衡,校验过滤

启用

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


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

请求路由

无注册中心 (配置URL)
  • 单例配置
zuul:
  routes:
    <route>:
      path: /user/**
      url: http://127.0.0.1:8080
      #stripPrefix: false  # 是否过滤 path 
  • 多例配置
zuul:
  routes:
    user:
      path: /user/**
      serviceId: spcd-user
      #stripPrefix: false

ribbon:
  eureka:
    enabled: false # 不使用服务发现机制获取service

spcd-user:
  ribbon:
    NIWSServerListClassName: com.netflix.loadbalancer.ConfigurationBasedServerList
    listOfServers: http://127.0.0.1:8741,http://127.0.0.1:8742 # 多实例
    ConnectTimeout: 500
    ReadTimeout: 10000
    MaxTotalHttpConnections: 500
    MaxConnectionsPerHost: 100
  • 本地跳转
zuul:
  routes:
    <route>:
      path: /user/*
      url: forward:/local  # zuul服务本身接口 /local/*
注册中心

使用 serviceId 为注册中心的 注册服务名即可

zuul:
  ignoredServices: '*' # 禁止自动创建路由
  routes:
    user:
      path: /user/**
      serviceId: spcd-user
      stripPrefix: false

默认情况下 ,Eureka上的所有服务,Zuul会自动创建路由, 规则如下

zuul.routes.<服务名>.path=/<服务名>/**
zuul.routes.<服务名>.serviceId=<服务名>

zuul.ignoredServices 可指定服务忽略自动创建路由规则 ,=* 则全部忽略,需为服务手动配置路由规则

Cookies and Sensitive Headers

Zuul默认过滤敏感头信息,不传递给下游服务,可配置如下修改

zuul:
  routes:
    users:
      path: /myusers/**
      sensitiveHeaders: Cookie,Set-Cookie,Authorization # 默认,头信息过滤,不传递给下游
      #sensitiveHeaders: # 不过滤,全部传递给下游
      url: https://downstream
超时 + 重试

zuul 中已集成 Hystrix 和 Ribbon ,即当 hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds > ribbon.ReadTimeout 即会发生重试,禁止重试命令如下

zuul.retryable=false
zuul.routes.<route>.retryable=false

超时设置

  • 配置Eureka时,使用Ribbon超时
ribbon.ReadTimeout
ribbon.SocketTimeout
  • 配置URL时,使用zuul配置超时
zuul.host.connect-timeout-millis
zuul.host.socket-timeout-millis

ZuulFilter

ZuulFilter

	public int filterOrder() ; // 过滤器执行顺序, 小优先

	public String filterType();

	public boolean shouldFilter(); // 是否执行
	
    public Object run(); // 执行逻辑

filterType 定义四种生命周期的过滤类型

  • pre: 在请求被路由前调用

    • ServletDetectionFilter 标记处理servlet类型 -3

    • Servlet30WrapperFilter 将HttpServletRequest 包装为 Servlet30RequestWrapper 对象

    • FromBodyWrapperFilter 包装 Content-Type: application/x-www-from-urlencoded ,multipart/form-data(ServletDetectionFilter) 的请求

      还有 DebugFilter 和 PreDecorationFilter 为默认实现的 pre 的ZuulFilter

  • routing: 在请求在路由时调用

    • RibbonRoutingFilter 对配置serviceId 的请求进行路由 (Ribbon)
    • SimpleHostRoutingFilter 对配置url的请求进行路由
    • SendForwardFilter 对forward.to 本地路由跳转
  • post: 在请求路由返回响应后,或发生error后 调用

    • LocationRewriteFilter 重写位置头为zuul url
    • SendResponseFilter 响应客户端 oreder 1000
    • SendErrorFilter 错误信息 forward 到 zuul的/error接口产生错误响应
  • error: 处理请求时发生错误时被调用

Disable Zuul Filters
zuul.<SimpleClassName>.<filterType>.disable=true
zuul.SendResponseFilter.post.disable=true # org.springframework.cloud.netflix.zuul.filters.post.SendResponseFilter禁用
生命周期图

在这里插入图片描述

Fallback

class MyFallbackProvider implements FallbackProvider {

    @Override
    public String getRoute() {
        return "*";  // 可指定 route
    }

    @Override
    public ClientHttpResponse fallbackResponse(final Throwable cause) {
        if (cause instanceof HystrixTimeoutException) {
            return response(HttpStatus.GATEWAY_TIMEOUT);
        } else {
            return fallbackResponse();
        }
    }

    @Override
    public ClientHttpResponse fallbackResponse() {
        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;
            }
        };
    }
}

动态路由

1、通过与 spring cloud config 配合使用,zuul作为 config client 端,需引入

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

2、使用bootstrap.yml 指定config server 中的配置文件 zuul-dev.yml

eureka:
  client:
    service-url:
      defaultZone: http://127.0.0.1:8761/eureka/

spring:
  application:
    name: zuul
  cloud:
    config:
      discovery:
        enabled: true
        service-id: spcd-config
      profile: dev
      label: master
      #uri: http://127.0.0.1:8711
      username: user
      password: 123456789

3、在zuul-dev.yml 开启 endpoints端点接口

# actuator
management:
  endpoints:
    web:
      exposure:
        include: "*"
        exclude: env  #必须去除 env

启动后 通过 http://127.0.0.1:8721/actuator/refresh 刷新配置
在这里插入图片描述

发布了73 篇原创文章 · 获赞 78 · 访问量 9万+

猜你喜欢

转载自blog.csdn.net/SHIYUN123zw/article/details/103548260