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 刷新配置
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章