日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

Gateway服務網關

作者:crazy_xieyi 更新時間: 2023-07-10 編程語言

Spring Cloud Gateway為微服務架構提供一種簡單有效的統一的 API 路由管理方式。Gateway網關是所有微服務的統一入口。

網關的核心功能特性

請求路由和負載均衡:一切請求都必須先經過gateway,但網關不處理業務,而是根據某種規則,把請求轉發到某個微服務,這個過程叫做路由。當然路由的目標服務有多個時,還需要做負載均衡。

權限控制:網關作為微服務入口,需要校驗用戶是是否有請求資格,如果沒有則進行攔截。

限流:當請求流量過高時,在網關中按照微服務能夠接受的速度來放行請求,避免服務壓力過大。

在SpringCloud中網關的實現包括兩種:gateway和zuul

Zuul是基于Servlet的實現,屬于阻塞式編程。而SpringCloudGateway則是基于Spring5中提供的WebFlux,屬于響應式編程的實現,具備更好的性能。

gateway使用步驟:

  1. 創建gateway服務,引入依賴

<!--網關-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<!--nacos服務發現依賴-->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>

2)編寫啟動類

3)編寫基礎配置和路由規則

創建application.yml文件,內容如下:

server:
  port: 10010 # 網關端口
spring:
  application:
    name: gateway # 服務名稱
  cloud:
    nacos:
      server-addr: localhost:8848 # nacos地址
    gateway:
      routes: # 網關路由配置
        - id: user-service # 路由id,自定義,只要唯一即可
          # uri: http://127.0.0.1:8081 # 路由的目標地址 http就是固定地址
          uri: lb://userservice # 路由的目標地址 lb就是負載均衡,后面跟服務名稱
          predicates: # 路由斷言,也就是判斷請求是否符合路由規則的條件
            - Path=/user/** # 這個是按照路徑匹配,只要以/user/開頭就符合要求

Gateway在注冊中心拉取了服務列表,當請求來的時候將會路由判斷,將符合Path 規則的一切請求,都代理到 uri參數指定的地址。比如將 /user/**開頭的請求,代理到lb://userservice,lb是負載均衡,根據服務名拉取服務列表,實現負載均衡。

路由配置包括:

  1. 路由id:路由的唯一標示

  1. 路由目標(uri):路由的目標地址,http代表固定地址,lb代表根據服務名負載均衡

  1. 路由斷言(predicates):判斷路由的規則,

  1. 路由過濾器(filters):對請求或響應做處理

過濾器GatewayFilter

GatewayFilter是網關中提供的一種過濾器,可以對進入網關的請求和微服務返回的響應做處理。在官網中可以看到,Spring提供了31種不同的路由過濾器工廠。

只需要修改gateway服務的application.yml文件,添加路由過濾即可:

示例:

spring:
  cloud:
    gateway:
      routes:
      - id: user-service 
        uri: lb://userservice 
        predicates: 
        - Path=/user/** 
        filters: # 過濾器
        - AddRequestHeader=Truth, xieyi is crazy! # AddRequestHeader這種過濾器是添加請求頭

當前過濾器寫在userservice路由下,因此僅僅對訪問userservice的請求有效。

如果要對所有的路由都生效,則可以將過濾器工廠寫到default下。格式如下:

spring:
  cloud:
    gateway:
      routes:
      - id: user-service 
        uri: lb://userservice 
        predicates: 
        - Path=/user/**
      default-filters: # 默認過濾項
      - AddRequestHeader=Truth, xieyi is crazy!

GatewayFilter小結

過濾器的作用是什么?

① 對路由的請求或響應做加工處理,比如添加請求頭

② 配置在路由下的過濾器只對當前路由的請求生效

defaultFilters的作用是什么?

① 對所有路由都生效的過濾器

全局過濾器GlobalFilter

網關提供了31種,但每一種過濾器的作用都是固定的。如果希望攔截請求,做自己的業務邏輯則沒辦法實現,這個時候就需要GlobalFilter這種全局過濾器。

全局過濾器的作用也是處理一切進入網關的請求和微服務響應,與GatewayFilter的作用一樣。區別在于GatewayFilter通過配置定義,處理邏輯是固定的;而GlobalFilter的邏輯需要自己寫代碼實現。

定義方式是實現GlobalFilter接口:

public interface GlobalFilter {
    /**
     *  處理當前請求,有必要的話通過{@link GatewayFilterChain}將請求交給下一個過濾器處理
     * @param exchange 請求上下文,里面可以獲取Request、Response等信息
     * @param chain 用來把請求委托給下一個過濾器 
     * @return {@code Mono<Void>} 返回標示當前過濾器業務結束
     */
    Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain);
}

在filter中編寫自定義邏輯,可以實現下列功能:登錄狀態判斷、權限校驗、請求限流等。

示例:

@Order(-1)
@Component
public class AuthorizeFilter implements GlobalFilter {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        //1.獲取請求參數
        ServerHttpRequest request = exchange.getRequest();
        MultiValueMap<String, String> queryParams = request.getQueryParams();
        //2.獲取參數中的authorization參數
        String auth = queryParams.getFirst("authorization");
        //3.判斷參數值是否等于admin
        if ("admin".equals(auth)){
            //4.是,放行;
            return chain.filter(exchange);
        }
        //否,攔截
        //設置狀態碼
        exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
        return exchange.getResponse().setComplete();
    }
}

過濾器執行順序

請求進入網關會碰到三類過濾器:當前路由的過濾器、DefaultFilter、GlobalFilter

請求路由后,會將當前路由過濾器和DefaultFilter、GlobalFilter,合并到一個過濾器鏈(集合)中,排序后依次執行每個過濾器。

排序的規則:

1.每一個過濾器都必須指定一個int類型的order值,order值越小,優先級越高,執行順序越靠前

2.或者GlobalFilter通過實現Ordered接口,或者添加@Order注解來指定order值,由我們自己指定

3.路由過濾器和defaultFilter的order由Spring指定,默認是按照聲明順序從1遞增。當過濾器的order值一樣時,會按照 defaultFilter > 路由過濾器 > GlobalFilter的順序執行。

跨域問題

域名不同,或者域名相同,端口不同都是跨域,跨域就是瀏覽器禁止請求的發起者與服務端發生跨域ajax請求,請求被瀏覽器攔截的問題。

跨越問題可以通過CORS解決,詳情可以參考這篇文章https://www.ruanyifeng.com/blog/2016/04/cors.html

下面我們在gateway服務的application.yml文件中,添加下面的配置來解決跨域問題。

spring:
  cloud:
    gateway:
      # 。。。
      globalcors: # 全局的跨域處理
        add-to-simple-url-handler-mapping: true # 解決options請求被攔截問題
        corsConfigurations:
          '[/**]':
            allowedOrigins: # 允許哪些網站的跨域請求 
              - "http://localhost:8090"
            allowedMethods: # 允許的跨域ajax的請求方式
              - "GET"
              - "POST"
              - "DELETE"
              - "PUT"
              - "OPTIONS"
            allowedHeaders: "*" # 允許在請求中攜帶的頭信息 *表示任何
            allowCredentials: true # 是否允許攜帶cookie
            maxAge: 360000 # 這次跨域檢測的有效期

原文鏈接:https://blog.csdn.net/crazy_xieyi/article/details/128977409

  • 上一篇:沒有了
  • 下一篇:沒有了
欄目分類
最近更新