SpringCloud-Zuul(二):自定義Filter及內部路由源碼解析

原創地址,jsbintask的博客(食用效果最佳),轉載請註明出處!java

前言

上一篇介紹了SpringCloud使用Zuul的調用流程,明白了Zuul的工做原理關鍵在於ZuulServlet和它的內置Filter,因此在實際工做中,編寫業務邏輯的關鍵就在於自定義filter。spring

用法

實現ZuulFilter

實現一個自定義Filter很簡單,繼承自ZuulFilter便可:api

@Component
public class Filter 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 context = RequestContext.getCurrentContext().getRequest();
        HttpServletRequest request = context.getRequest();
        HttpServletResponse response = context.getResponse();
        System.out.println("Filter.run");
        return null;
    }
}
複製代碼
  1. filterType方法返回filter類型
  2. filterOrder返回同類型filter執行順序
  3. shouldFilter返回請求是否應該執行run方法。
  4. run表示業務邏輯執行過程。
  5. 處理邏輯過程當中若是須要用到HttpServletRequest和HttpServletResponse能夠用RequestContext.getCurrentContext()拿出。

Filter類型

Zuul的Filter一共分爲四個種類,Pre,Route,Post,Error,每種Filter的執行時機不一樣,因此他們在業務邏輯功能上有所不一樣,如圖: app

Zuul

  1. Pre類型的Filter老是先執行,它能夠作限流,權限控制等。
  2. Route類型的Filter爲Zuul內部轉發請求到真正的服務的Filter,通常咱們不須要實現這種類型.
  3. Post爲請求轉發完成後的後續動做,能夠進行日誌等的一些添加。
  4. Error爲上述Filter出錯後執行的動做,能夠進行錯誤處理等。 關於它們的執行順序,如圖:
    Zuul

源碼解析

zuul內部已經定義了各類類型的filter,如預處理,路由轉發,錯誤處理等。咱們能夠經過源碼來研究Zuul是如何幫咱們轉發請求的: 負載均衡

Zuul

  1. RibbonRoutingFilter
  2. SimpleHostRoutingFilter
  3. SendForwardFilter 上面三個Filter只會執行一個,控制它們執行過程的爲PreDecorationFilter:
    Zuul
    當整合的是微服務時,則配置的爲服務名,如:
zuul:
 prefix: /api
 routes:
 espay-auth:
 path: /test/**
 service-id: service-name
複製代碼

這個時候將調用RibbonRoutingFilter做負載均衡轉發請求:ide

protected ClientHttpResponse forward(RibbonCommandContext context) throws Exception {
    Map<String, Object> info = this.helper.debug(context.getMethod(),
            context.getUri(), context.getHeaders(), context.getParams(),
            context.getRequestEntity());

    RibbonCommand command = this.ribbonCommandFactory.create(context);
    try {
        ClientHttpResponse response = command.execute();
        this.helper.appendDebug(info, response.getRawStatusCode(), response.getHeaders());
        return response;
    }
    catch (HystrixRuntimeException ex) {
        return handleException(info, ex);
    }
}
複製代碼

而當咱們配置的直接爲某個地址:微服務

zuul:
 routes:
 espay-auth:
 path: /auth/**
 url: http://baidu.com
複製代碼

則會調用SimpleHostRoutingFilter進行轉發,它內部直接使用HttpClient進行轉發: post

Zuul
而當請求出錯時,則會交由 SendErrorFilter處理,它會設置標誌位 SEND_ERROR_FILTER_RAN爲true,而後從新發送請求到 PreDecorationFilter。這個時候的流程爲:
Zuul
SendForwardFilter:
Zuul
這樣一次完整的路由,轉發,錯誤處理就分析完畢。

總結

  1. Zuul內部使用自定義filter處理業務邏輯。
  2. Zuul內部有四種不一樣類型的Filter。
  3. Zuul內部轉發請求有兩種,爲服務下邊的RibbonRoutingFilter,普通http轉發的SimpleHostRoutingFilter.

關注我,這裏只有乾貨!this

相關文章: SpringCloud-Zuul(一):技術選型及請求流程源碼走讀url

相關文章
相關標籤/搜索