1. 程式人生 > 其它 >微服務【SpringCloud】--Gateway入門

微服務【SpringCloud】--Gateway入門

技術標籤:2020實習SpringCloud過濾器gateway網路

文章目錄



Spring Cloud Gateway入門

(1)閘道器是什麼?

閘道器(Gateway) 就是一個網路連線到另一個網路的“關口”。就是網路關卡。
從一個房間走到另一個房間,必然要經過一扇門。同樣,從一個網路向另一個網路傳送資訊,也必須經過一道“關口”

(2)SpringCloud的閘道器是什麼?

Spring Cloud Gateway的核心就是一系列的過濾器,可以將客戶端的請求轉發到不同的微服務。主要作用:過濾和路由。

Spring Cloud Gateway入門

(1)GateWay如何使用

  • 依賴
    -配置路由資訊
    id 路由id,可以任意
    uri 代理的服務地址
    predicates 路由斷言: 可以匹配對映路徑
  • 啟用
    -啟動

pom.xml

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

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

application.properties

spring.application.name=demo04_gateway_1001
server.port=1001
eureka.client.service-url.defaultZone=http://127.0.0.1:10086/eureka
# route
spring.cloud.gateway.routes[0].id=demo04_gateway_1001
#spring.cloud.gateway.routes[0].uri.=http://127.0.0.1:8001
spring.cloud.gateway.routes[0].uri=lb://demo01-provider-user
spring.cloud.gateway.routes[0].predicates[0]=Path=/**
#spring.cloud.gateway.routes[0].predicates[0]=Path=/users/*
spring.cloud.gateway.routes[0].filters[0]=PrefixPath=/users

main

@SpringBootApplication
@EnableDiscoveryClient
public class Demo04Gateway1001Application 

面向服務的路由 uri

(1)面向服務的路由是什麼?

配置路由資訊時,使用服務的名稱來代替 ip+port的配置方式
只需要在配置檔案中指定路由路徑類似: lb://user-service

(2)代理的服務地址;lb表示從eureka中獲取具體服務

(3)注意事項

lb 之後編寫的服務名必須要在eureka中註冊才能使用

(4)分析

路由配置中uri所用的協議為lb時(以uri: lb://user-service為例),gateway將使用 LoadBalancerClient把user-service通過eureka解析為實際的主機和埠,並進行ribbon負載均衡。

路由字首處理 filter

(1)路由的字首

請求地址與微服務的服務地址如果不一致的時候,可以通過配置路徑過濾器實現路徑字首的新增和去除。
提供服務的地址:http://127.0.0.1:8001/user/8

  • 新增字首:對請求地址新增字首路徑之後再作為代理的服務地址;
    http://127.0.0.1:101/8 --> http://127.0.0.1:8001/user/8 新增字首路徑/user
spring.cloud.gateway.routes[0].predicates[0]=Path=/**
spring.cloud.gateway.routes[0].filters[0]=PrefixPath=/users
  • 去除字首:將請求地址中路徑去除一些字首路徑之後再作為代理的服務地址;
    http://127.0.0.1:101/api/user/8 --> http://127.0.0.1:8001/user/8 去除字首路徑/api
spring.cloud.gateway.routes[0].predicates[0]=Path=/api/users/**
spring.cloud.gateway.routes[0].filters[0]=StripPrefix=1

過濾器簡介

(1)過濾器

符合條件的請求放行,否則不放行

(2)Gateway自帶過濾器有幾十個,常見自帶過濾器有

在配置檔案中指定要使用的過濾器名稱

(3)案例:新增響應頭過濾器

spring.cloud.gateway.default-filters[0]=AddResponseHeader=name,rose
spring.cloud.gateway.default-filters[1]=AddResponseHeader=age,34

過濾器分類

過濾器的分類 兩類

  • 區域性過濾器
    只對當前路由起作用
    spring.cloud.gateway.routes.filters
  • 全域性過濾器
    作用在所有的路由上
  • spring.cloud.gateway.default-filters + 實現GatewayFilterFactory介面的過濾器
  • 實現GlobalFilter介面,不需要配置

自定義全域性過濾器

判斷請求上的token值是否為空,不為空放行

  • (1)實現GlobalFilter
  • (2)實現Ordered介面
  • (3)符合條件,放行
  • (4)否則結束響應
//1:本類為全域性閘道器過濾器 /*
@Component
@Slf4j
public class MyGlobalFilter  implements GlobalFilter, Ordered {
    //exchange  =  req + resp
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        //攔截方法,攔截到請求後,自動執行
        log.info("filter 攔截方法,攔截到請求後,自動執行 ");
        //以後開發中,不會將 user物件存到session,只會在地址上帶上token
        //根據token是否有空可以判斷是否登入
        //http://localhost:8001/users/3?token=10001&pageSize=30
        String token = exchange.getRequest().getQueryParams().getFirst("token");
        if(token == null || "".equals(token)){
            //未登入 跳轉到登入頁
            log.info("----跳到登入頁面");
            exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
            exchange.getResponse().setComplete();
        }
        return chain.filter(exchange);//2 全部放行
    }

    @Override
    public int getOrder() {//3:系統呼叫該方法獲得過濾器的優先順序
        return 1; //數字越小,越優先
    }
}

自定義區域性過濾器

(1)使用場景:請求鑑權、異常處理、記錄呼叫時長等。
(2)步驟

  • 配置
    MyParam=name,address
  • 定義Config
  • MyParamGatewayFilterFactory繼承AbstractGatewayFilterFactory
  • 實現shortcutFieldOrder
  • 實現apply

application.properties

spring.cloud.gateway.routes[0].filters[0]=MyParam=name,address

MyParamGatewayFilterFactory

//1:本類為區域性過濾器類
@Component
@Slf4j
public class MyParamGatewayFilterFactory extends AbstractGatewayFilterFactory<MyParamGatewayFilterFactory.Config> {

    //5:將config交給父類的構造方法

    public MyParamGatewayFilterFactory() {
        super(Config.class);
    }

    @Override //4:過濾器
    public GatewayFilter apply(Config config) {
        GatewayFilter gatewayFilter = new GatewayFilter(){

            @Override
            public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
                //http://127.0.0.1:1001/users/3?token=333&name=jack&address=bj
                String name = exchange.getRequest().getQueryParams().getFirst(config.name);
                String address = exchange.getRequest().getQueryParams().getFirst(config.address);
                log.info("filter ....name"+name);
                log.info("filter ....address"+address);
                log.info("filter ....攔截了請求");
                return chain.filter(exchange);//全部放行
            }
        };
        return gatewayFilter;//返回一個自己定義的過濾器
    }

    //3:定義順序
    @Override
    public List<String> shortcutFieldOrder() {//定義變數的順序
        List<String> order = new ArrayList<>();
        order.add("name");
        order.add("address");
        return order;
    }

    //name,address
    //http://127.0.0.1:8001/users/1?name=jack&address=bj
    @Data //2:定義config
    public static class Config{
        private String name;
        private String address;
    }
}