1. 程式人生 > 實用技巧 >[微服務-sc-06] SpringCloud-Zuul

[微服務-sc-06] SpringCloud-Zuul

Zuul

Zuul的主要功能是路由轉發和過濾器。路由功能是微服務的一部分,比如/api/user轉發到到user服務,/api/shop轉發到到shop服務。zuul預設和Ribbon結合實現了負載均衡的功能。
Spring Cloud Zuul 是基於 Netflix Zuul 的微服務路由和過濾器的解決方案,也用於實現 API 閘道器。其中,路由功能負責將外部請求轉發到具體的微服務例項上,是實現外部訪問統一入門的基礎。而過濾功能是負責對請求的處理過程進行干預,是實現請求校驗、服務聚合等功能的基礎。
Spring Cloud Zuul 和 Eureka 進行整合時,Zuul 將自身註冊到 Eureka 服務中,同時從 Eureka 中獲取其他微服務資訊,以便請求可以準確的通過 Zuul 轉發到具體微服務上。

使用

1 依賴

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

2 開啟功能

@EnableZuulProxy
@EnableEurekaClient
@SpringBootApplication
public class ServiceZuulApplication {

    public static void main(String[] args) {
        SpringApplication.run(ServiceZuulApplication.class, args);
    }
}

3 配置檔案

server:
    port: 9600

spring:
    application:
        name: gateway

eureka:
    instance:
        instance-id: gateway-9600
        prefer-ip-address: true 
    client:
        service-url:
            defaultZone: http://localhost:9000/eureka/  # 註冊中心訪問地址

此時可以通過閘道器來進行服務訪問。

路由功能

zuul:
  sensitive-headers: # 全域性忽略敏感頭,即允許接收 cookie 等請求頭資訊   
  routes:
    extlight: # 任意名字,保證唯一即可
      path: /extlight/** # 自定義,真正用到的請求地址
      service-id: ORDER  # 路由到的目標服務名稱

服務過濾

@Component
public class MyFilter extends ZuulFilter{

    private static Logger log = LoggerFactory.getLogger(MyFilter.class);
    @Override
    public String filterType() {
        return "pre";
    }

    @Override
    public int filterOrder() {
        return 0;
    }

    @Override
    public boolean shouldFilter() {
        return true;
    }

    @Override
    public Object run() {
        RequestContext ctx = RequestContext.getCurrentContext();
        HttpServletRequest request = ctx.getRequest();
        log.info(String.format("%s >>> %s", request.getMethod(), request.getRequestURL().toString()));
        Object accessToken = request.getParameter("token");
        if(accessToken == null) {
            log.warn("token is empty");
            ctx.setSendZuulResponse(false);
            ctx.setResponseStatusCode(401);
            try {
                ctx.getResponse().getWriter().write("token is empty");
            }catch (Exception e){}

            return null;
        }
        log.info("ok");
        return null;
    }
}

filterType:返回一個字串代表過濾器的型別,在zuul中定義了四種不同生命週期的過濾器型別,具體如下:
pre: 這種過濾器在請求被路由之前呼叫。我們可利用這種過濾器實現身份驗證、在叢集中選擇請求的微服務、記錄除錯資訊等。
routing:這種過濾器將請求路由到微服務。這種過濾器用於構建傳送給微服務的請求,並使用 Apache HttpClient 或 Netfilx Ribbon 請求微服務。
post:這種過濾器在路由到微服務以後執行。這種過濾器可用來為響應新增標準的 HTTP Header、收集統計資訊和指標、將響應從微服務傳送給客戶端等。
error:在其他階段發生錯誤時執行該過濾器。
filterOrder:過濾的順序
shouldFilter:這裡可以寫邏輯判斷,是否要過濾,本文true,永遠過濾。
run:過濾器的具體邏輯。可用很複雜,包括查sql,nosql去判斷該請求到底有沒有許可權訪問。