天天看點

Gateway-源碼分析

工作原理

Gateway-源碼分析

用戶端向 Spring Cloud Gateway 送出請求。 如果網關處理程式映射确定請求與路由比對,則将其發送到網關 Web 處理程式。 此處理程式通過特定于請求的過濾器鍊運作請求。 過濾器用虛線劃分的原因是過濾器可以在發送代理請求之前和之後運作邏輯。 執行所有“預”過濾器邏輯。 然後發出代理請求。 發出代理請求後,将運作“釋出”過濾器邏輯。

配置類分析

jar包中加載的配置類,會注入到IOC容器中。

Gateway-源碼分析

1、GatewayClassPathWarningAutoConfiguration 檢查是否有正确的配置webflux

檢查是否有

org.springframework.web.servlet.DispatcherServlet

類,也就是是否引入了springweb的依賴。

Gateway-源碼分析

2、GatewayAutoConfiguration 核心配置類

配置了很多bean,加載了gateway 需要注入的類。

Gateway-源碼分析

配置了很多謂詞想的的bean

Gateway-源碼分析

3、GatewayLoadBalancerClientAutoConfiguration 網關需要使用的負載均衡

Gateway-源碼分析

該過濾器實作了負載均衡的功能,通過責任鍊的設計模式。

Gateway-源碼分析

4、GatewayRedisAutoConfiguration 網關整合Redis整合Lua實作限流

Gateway-源碼分析

5、GatewayDiscoveryClientAutoConfiguration 把網關服務注冊到注冊中心中去,服務注冊與發現功能

路由模式源碼分析

網關的請求入口在 DispatcherHandler類裡面的 handler 方法。

Gateway-源碼分析

查找handler方法中,子類會查找路由政策,循環查找路由政策,第一個比對的政策會傳回了。

Gateway-源碼分析

執行的handler

Gateway-源碼分析

webHandler去執行

Gateway-源碼分析

執行的是 filter 的 handler,gateway 預設有7個filter,分别實作了不同的功能:負載均衡、請求轉發等功能。各個filter通過責任鍊模式循環執行。

Gateway-源碼分析

解決前後端的跨域問題

微服務中跨域的問題,不屬于前端解決 jsonp ,隻能支援get請求。

核心點就是在我們後端。

解決跨域的問題

  1. HttpClient轉發
  2. 使用過濾器允許接口可以跨域 響應頭設定
  3. Jsonp 不支援我們的post 屬于前端解決
  4. Nginx解決跨域的問題保持我們域名和端口一緻性
  5. Nginx也是通過配置檔案解決跨域的問題
  6. 基于微服務網關解決跨域問題,需要保持域名和端口一緻性
  7. 使用網關代碼允許所有的服務可以跨域的問題
  8. 使用SpringBoot注解形式@CrossOrigin

gateway解決跨域問題:增加過濾器,給請求頭增加參數。

@Component
public class CrossOriginFilter implements GlobalFilter {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        ServerHttpResponse response = exchange.getResponse();
        HttpHeaders headers = response.getHeaders();
        headers.add(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN, "*");
        headers.add(HttpHeaders.ACCESS_CONTROL_ALLOW_METHODS, "POST, GET, PUT, OPTIONS, DELETE, PATCH");
        headers.add(HttpHeaders.ACCESS_CONTROL_ALLOW_CREDENTIALS, "true");
        headers.add(HttpHeaders.ACCESS_CONTROL_ALLOW_HEADERS, "*");
        headers.add(HttpHeaders.ACCESS_CONTROL_EXPOSE_HEADERS, "*");
        return chain.filter(exchange);

    }
}