溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

如何進(jìn)行第二代網(wǎng)關(guān)GateWay的搭建

發(fā)布時(shí)間:2021-11-11 09:55:56 來源:億速云 閱讀:158 作者:柒染 欄目:編程語言

如何進(jìn)行第二代網(wǎng)關(guān)GateWay的搭建,很多新手對(duì)此不是很清楚,為了幫助大家解決這個(gè)難題,下面小編將為大家詳細(xì)講解,有這方面需求的人可以來學(xué)習(xí)下,希望你能有所收獲。

Spring Cloud第二代網(wǎng)關(guān)GateWay是由純Netty開發(fā),底層為Reactor,WebFlux構(gòu)建,不依賴任何Servlet容器,它不同于Zuul,使用的是異步IO,性能較Zuul提升1.6倍。搭建過程如下(本次搭建的為子項(xiàng)目,主項(xiàng)目可以參考Nacos搭建流程 )

pom

<dependency>   <groupId>org.springframework.cloud</groupId>   <artifactId>spring-cloud-starter-gateway</artifactId></dependency><dependency>   <groupId>com.alibaba.cloud</groupId>   <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency>

配置文件

server:  port: 8040spring:  application:    name: gateway  cloud:    nacos:      discovery:        server-addr: 127.0.0.1:8848gateway:      discovery:        locator:          enabled: true

以上的意思不僅是把自己給注冊(cè)到nacos,并且獲取nacos的所有注冊(cè)服務(wù)。

啟動(dòng)網(wǎng)關(guān)項(xiàng)目,現(xiàn)在就可以進(jìn)行網(wǎng)絡(luò)路由了。訪問格式為 ip:端口/服務(wù)注冊(cè)名/restfulapi-url

比方說我們現(xiàn)在有兩個(gè)微服務(wù)項(xiàng)目,一個(gè)為user(端口8082),一個(gè)為nacos(端口8081).

如何進(jìn)行第二代網(wǎng)關(guān)GateWay的搭建

如何進(jìn)行第二代網(wǎng)關(guān)GateWay的搭建

如何進(jìn)行第二代網(wǎng)關(guān)GateWay的搭建

如何進(jìn)行第二代網(wǎng)關(guān)GateWay的搭建

三大核心概念

  • Route(路由) Spring Cloud Gateway的基礎(chǔ)元素,可簡單理解成一條轉(zhuǎn)發(fā)的規(guī)則。包含:ID,目標(biāo)的URL,Predicate集合以及Filter集合。

  • Predicate(謂詞) 即java.util.function.Predicate,Spring Cloud Gateway使用Predicate實(shí)現(xiàn)路由的匹配條件。這是一個(gè)可以進(jìn)行條件判斷的函數(shù)式接口,具體可以參考本人博客Java函數(shù)式編程整理

  • Filter(過濾器) 修改請(qǐng)求以及響應(yīng)。

由于我們使用了nacos來進(jìn)行服務(wù)發(fā)現(xiàn),所以我們使用了之前的配置文件,但如果不使用服務(wù)發(fā)現(xiàn),只做常規(guī)的轉(zhuǎn)發(fā)如下

spring:
  cloud:gateway:  routes:        - id: some_route          uri: http://www.baidu.com          predicates:            - Path=/user/1          filtes:            - AddRequestHeader=X-Request-Foo, Bar

這段配置的意思是說,當(dāng)我們請(qǐng)求/user/1的url的時(shí)候,會(huì)添加AddRequestHeader=X-Request-Foo, Bar過濾器做一些處理,然后路由到http://www.baidu.com。

路由謂詞配置工廠

路由謂詞配置工廠由一整套謂詞來進(jìn)行配置轉(zhuǎn)發(fā)的不同情況。

謂詞工廠備注
After此謂詞匹配當(dāng)前日期時(shí)間之后發(fā)生的請(qǐng)求。
Before此謂詞匹配在當(dāng)前日期時(shí)間之前發(fā)生的請(qǐng)求。
Between此謂詞匹配datetime1之后和datetime2之前發(fā)生的請(qǐng)求。 datetime2參數(shù)必須在datetime1之后。
CookieCookie Route Predicate Factory有兩個(gè)參數(shù),cookie名稱和正則表達(dá)式。此謂詞匹配具有給定名稱且值與正則表達(dá)式匹配的cookie。
HeaderHeader Route Predicate Factory有兩個(gè)參數(shù),標(biāo)題名稱和正則表達(dá)式。與具有給定名稱且值與正則表達(dá)式匹配的標(biāo)頭匹配。
HostHost Route Predicate Factory采用一個(gè)參數(shù):主機(jī)名模式。該模式是一種Ant樣式模式“.”作為分隔符。此謂詞匹配與模式匹配的Host標(biāo)頭。
MethodMethod Route Predicate Factory采用一個(gè)參數(shù):要匹配的HTTP方法。
Path匹配請(qǐng)求的path
QueryQuery Route Predicate Factory有兩個(gè)參數(shù):一個(gè)必需的參數(shù)和一個(gè)可選的正則表達(dá)式。
RemoteAddrRemoteAddr Route Predicate Factory采用CIDR符號(hào)(IPv4或IPv6)字符串的列表(最小值為1),例如, 192.168.0.1/16(其中192.168.0.1是IP地址,16是子網(wǎng)掩碼)。

路由到指定URL

  • 通配

現(xiàn)在我們?nèi)サ鬾acos的配置,不由nacos來發(fā)現(xiàn)

spring:  application:    name: gateway  cloud:    gateway:      routes:      - id: gateuri: http://127.0.0.1:8082predicates:        #由/user來匹配跳轉(zhuǎn)        - Path=/user/**filters:        #跳轉(zhuǎn)后省略第一個(gè)通配        - StripPrefix=1

此時(shí)訪問

如何進(jìn)行第二代網(wǎng)關(guān)GateWay的搭建

將跳轉(zhuǎn)到

如何進(jìn)行第二代網(wǎng)關(guān)GateWay的搭建

  • 謂詞After

spring:  application:    name: gateway  cloud:    gateway:      routes:      - id: gateuri: http://127.0.0.1:8082predicates:        #由/user來匹配跳轉(zhuǎn)        - Path=/user/**#在2019-12-14日20:26后允許該轉(zhuǎn)發(fā)        - After=2019-12-14T20:26:15.667+08:00[Asia/Shanghai]filters:        #跳轉(zhuǎn)后省略第一個(gè)通配        - StripPrefix=1

這里表示在該時(shí)間后允許轉(zhuǎn)發(fā),如果我們將該時(shí)間設(shè)置為

spring:  application:    name: gateway  cloud:    gateway:      routes:      - id: gateuri: http://127.0.0.1:8082predicates:        #由/user來匹配跳轉(zhuǎn)        - Path=/user/**#在2019-12-15日20:26后允許該轉(zhuǎn)發(fā)        - After=2019-12-15T20:26:15.667+08:00[Asia/Shanghai]filters:        #跳轉(zhuǎn)后省略第一個(gè)通配        - StripPrefix=1

則轉(zhuǎn)發(fā)失敗,返回404

如何進(jìn)行第二代網(wǎng)關(guān)GateWay的搭建

我們可以通過以下方法來獲取這里的時(shí)間設(shè)置

public class TimeTest {public static void main(String[] args) {
        System.out.println(ZonedDateTime.now());    }
}

運(yùn)行結(jié)果

2019-12-14T20:43:34.755+08:00[Asia/Shanghai]

  • 謂詞Before

現(xiàn)在我們將上面的15號(hào)改為Before

spring:  application:    name: gateway  cloud:    gateway:      routes:      - id: gateuri: http://127.0.0.1:8082predicates:        #由/user來匹配跳轉(zhuǎn)        - Path=/user/**#在2019-12-15日20:26前允許該轉(zhuǎn)發(fā)        - Before=2019-12-15T20:26:15.667+08:00[Asia/Shanghai]filters:        #跳轉(zhuǎn)后省略第一個(gè)通配        - StripPrefix=1

此時(shí)就可以正常轉(zhuǎn)發(fā),而改成14號(hào)則會(huì)失敗。

  • 謂詞Between

spring:  application:    name: gateway  cloud:    gateway:      routes:      - id: gateuri: http://127.0.0.1:8082predicates:        #由/user來匹配跳轉(zhuǎn)        - Path=/user/**#在2019-12-14日20:26到2019-12-15日20:26之間允許該轉(zhuǎn)發(fā)        - Between=2019-12-14T20:26:15.667+08:00[Asia/Shanghai],2019-12-15T20:26:15.667+08:00[Asia/Shanghai]filters:        #跳轉(zhuǎn)后省略第一個(gè)通配        - StripPrefix=1
  • 謂詞Cookie

我們?cè)趗ser模塊增加一個(gè)帶cookie的Controller

@Slf4j@RestControllerpublic class CookieController {@GetMapping("/welcome")public Boolean handle(HttpServletRequest request,                               HttpServletResponse response) throws Exception {
        Cookie cookie = new Cookie("test","value");        cookie.setMaxAge(Integer.MAX_VALUE);        response.addCookie(cookie);        log.info("welcome");        return true;    }
}

此時(shí)我們?cè)L問該Controller為

如何進(jìn)行第二代網(wǎng)關(guān)GateWay的搭建

此時(shí)網(wǎng)關(guān)這邊配置為

spring:  application:    name: gateway  cloud:    gateway:      routes:      - id: gateuri: http://127.0.0.1:8082predicates:        #由/user來匹配跳轉(zhuǎn)        - Path=/user/**#只有帶上Cookie名為test,并且值符合正則value的cookie時(shí),才允許被轉(zhuǎn)發(fā)        - Cookie=test,valuefilters:        #跳轉(zhuǎn)后省略第一個(gè)通配        - StripPrefix=1

如何進(jìn)行第二代網(wǎng)關(guān)GateWay的搭建

  • 謂詞Header

現(xiàn)在我們給user模塊添加一個(gè)Controller的方法

@GetMapping("/header")public String header(@RequestHeader("item") String item) {return item;}

我們通過postman給該方法的訪問添加請(qǐng)求頭

如何進(jìn)行第二代網(wǎng)關(guān)GateWay的搭建

在網(wǎng)關(guān)中的配置為

spring:  application:    name: gateway  cloud:    gateway:      routes:      - id: gateuri: http://127.0.0.1:8082predicates:        #由/user來匹配跳轉(zhuǎn)        - Path=/user/**#只有帶上請(qǐng)求頭名為item,并且值符合正則123.p,才會(huì)轉(zhuǎn)發(fā)        - Header=item,123.pfilters:        #跳轉(zhuǎn)后省略第一個(gè)通配        - StripPrefix=1

如何進(jìn)行第二代網(wǎng)關(guān)GateWay的搭建

這里正則.可以匹配一個(gè)單字符

如果我們?cè)谡?qǐng)求頭item中設(shè)置錯(cuò)誤的字符則無法轉(zhuǎn)發(fā)

如何進(jìn)行第二代網(wǎng)關(guān)GateWay的搭建

  • 謂詞Host

要配置Host,我們需要給服務(wù)器的hosts文件添加一個(gè)域名映射,當(dāng)然在互聯(lián)網(wǎng)上需要一個(gè)域名來做DNS解析。

我這里給自己的域名添加為local.register.com

訪問user的find方法

如何進(jìn)行第二代網(wǎng)關(guān)GateWay的搭建

給網(wǎng)關(guān)添加配置

spring:  application:    name: gateway  cloud:    gateway:      routes:      - id: gateuri: http://127.0.0.1:8082predicates:        #由/user來匹配跳轉(zhuǎn)        - Path=/user/**#只有帶上請(qǐng)求頭Host,且值匹配**.register.com:8040才能通過轉(zhuǎn)發(fā)        - Host=**.register.com:8040filters:        #跳轉(zhuǎn)后省略第一個(gè)通配        - StripPrefix=1

此時(shí)我們通過網(wǎng)關(guān)訪問如下

如何進(jìn)行第二代網(wǎng)關(guān)GateWay的搭建

  • 謂詞Method

spring:  application:    name: gateway  cloud:    gateway:      routes:      - id: gateuri: http://127.0.0.1:8082predicates:        #由/user來匹配跳轉(zhuǎn)        - Path=/user/**#只有當(dāng)HTTP請(qǐng)求方法是GET時(shí)才能轉(zhuǎn)發(fā)        - Method=GETfilters:        #跳轉(zhuǎn)后省略第一個(gè)通配        - StripPrefix=1
  • 謂詞Query

現(xiàn)在我們給user模塊增加一個(gè)Controller方法

@GetMapping("/query")public String query(@RequestParam("name") String name) {return name;}

訪問如下

如何進(jìn)行第二代網(wǎng)關(guān)GateWay的搭建

網(wǎng)關(guān)配置如下

spring:  application:    name: gateway  cloud:    gateway:      routes:      - id: gateuri: http://127.0.0.1:8082predicates:        #由/user來匹配跳轉(zhuǎn)        - Path=/user/**#只有當(dāng)請(qǐng)求帶上參數(shù)名稱為name時(shí)才能通過轉(zhuǎn)發(fā)        - Query=namefilters:        #跳轉(zhuǎn)后省略第一個(gè)通配        - StripPrefix=1

如何進(jìn)行第二代網(wǎng)關(guān)GateWay的搭建

如果不帶上該參數(shù)則無法轉(zhuǎn)發(fā),如

如何進(jìn)行第二代網(wǎng)關(guān)GateWay的搭建

  • 謂詞RemoteAddr

spring:  application:    name: gateway  cloud:    gateway:      routes:      - id: gateuri: http://127.0.0.1:8082predicates:        #由/user來匹配跳轉(zhuǎn)        - Path=/user/**#只有當(dāng)請(qǐng)求為192.168.20.1/24網(wǎng)段(IP地址從192.168.20.1到192.168.20.254)才會(huì)轉(zhuǎn)發(fā)        - RemoteAddr=192.168.20.1/24filters:        #跳轉(zhuǎn)后省略第一個(gè)通配        - StripPrefix=1

例如

如何進(jìn)行第二代網(wǎng)關(guān)GateWay的搭建

但是使用127.0.0.1卻無法訪問

如何進(jìn)行第二代網(wǎng)關(guān)GateWay的搭建

現(xiàn)在我們恢復(fù)nacos的服務(wù)發(fā)現(xiàn)

spring:  application:    name: gateway  cloud:    nacos:      discovery:        server-addr: 127.0.0.1:8848gateway:      routes:      - id: gateuri: lb://userpredicates:        #由/user-center來匹配跳轉(zhuǎn)        - Path=/user-center/**filters:        #跳轉(zhuǎn)后省略第一個(gè)通配        - StripPrefix=1

為了跟不做任何配置相區(qū)別,我們這里謂詞Path寫了user-center

如何進(jìn)行第二代網(wǎng)關(guān)GateWay的搭建

自定義路由謂詞工廠

假設(shè)現(xiàn)在我們的一個(gè)API只有在上午9點(diǎn)到下午5點(diǎn)允許轉(zhuǎn)發(fā)

配置的文件如下

spring:  application:    name: gateway  cloud:    nacos:      discovery:        server-addr: 127.0.0.1:8848gateway:      routes:      - id: gateuri: lb://userpredicates:        #由/user-center來匹配跳轉(zhuǎn)        - Path=/user-center/**
        - TimeBetween=上午9:00,下午5:00filters:        #跳轉(zhuǎn)后省略第一個(gè)通配        - StripPrefix=1

由于這個(gè)TimeBetween并不是gateway默認(rèn)的謂詞工廠,所以我們需要自己來實(shí)現(xiàn)一個(gè)謂詞工廠,我們先定義一個(gè)時(shí)間的配置類

@Datapublic class TimeBetweenConfig {private LocalTime start;    private LocalTime end;}

然后自定義一個(gè)謂詞工廠類,該工廠類名稱必須以自定義謂詞開頭(這里是TimeBetween),以RoutePredicateFactory結(jié)尾,并繼承AbstractRoutePredicateFactory抽象類

@Componentpublic class TimeBetweenRoutePredicateFactory extends AbstractRoutePredicateFactory<TimeBetweenConfig>{public TimeBetweenRoutePredicateFactory() {super(TimeBetweenConfig.class);    }@Override    public Predicate<ServerWebExchange> apply(TimeBetweenConfig config) {
        LocalTime start = config.getStart();        LocalTime end = config.getEnd();        return exchange -> {
            LocalTime now = LocalTime.now();            return now.isAfter(start) && now.isBefore(end);        };    }@Override    public List<String> shortcutFieldOrder() {return Arrays.asList("start","end");    }
}

內(nèi)置過濾器工廠

1 AddRequestHeader GatewayFilter Factory
2 AddRequestParameter GatewayFilter Factory
3 AddResponseHeader GatewayFilter Factory
4 DedupeResponseHeader GatewayFilter Factory
5 Hystrix GatewayFilter Factory
6 FallbackHeaders GatewayFilter Factory

7 PrefixPath GatewayFilter Factory

8 PreserveHostHeader GatewayFilter Factory
9 RequestRateLimiter GatewayFilter Factory
10 RedirectTo GatewayFilter Factory
11 RemoveHopByHopHeadersFilter GatewayFilter Factory
12 RemoveRequestHeader GatewayFilter Factory
13 RemoveResponseHeader GatewayFilter Factory
14 RewritePath GatewayFilter Factory
15 RewriteResponseHeader GatewayFilter Factory
16 SaveSession GatewayFilter Factory
17 SecureHeaders GatewayFilter Factory
18 SetPath GatewayFilter Factory
19 SetResponseHeader GatewayFilter Factory
20 SetStatus GatewayFilter Factory
21 StripPrefix GatewayFilter Factory
22 Retry GatewayFilter Factory
23 RequestSize GatewayFilter Factory
24 Modify Request Body GatewayFilter Factory
25 Modify Response Body GatewayFilter Factory
26 Default Filters

  • AddRequestHeader

spring:  application:    name: gateway  cloud:    nacos:      discovery:        server-addr: 192.168.10.172:8848gateway:      routes:      - id: gateuri: lb://userpredicates:        #由/user-center來匹配跳轉(zhuǎn)        - Path=/user-center/**filters:        #跳轉(zhuǎn)后省略第一個(gè)通配        - StripPrefix=1#增加一個(gè)名稱為X-Request-Foo,值為Bar的請(qǐng)求頭        - AddRequestHeader=X-Request-Foo,Bar

這里需要注意的是新增的這個(gè)請(qǐng)求頭是轉(zhuǎn)發(fā)以后添加進(jìn)去的,所以我們請(qǐng)求網(wǎng)關(guān)的時(shí)候在瀏覽器中是找不到的,我們可以使用command+N(Windows中idea為Ctrl+N)來查找NettyRoutingFilter類,并且在filter方法中設(shè)置斷點(diǎn),由以下圖中可以看到它是被添加進(jìn)去了。

如何進(jìn)行第二代網(wǎng)關(guān)GateWay的搭建

  • AddRequestParameter

由于在user模塊中有這么一個(gè)方法

@GetMapping("/query")public String query(@RequestParam("name") String name) {return name;}

所以我們?cè)诰W(wǎng)關(guān)配置時(shí)

spring:  application:    name: gateway  cloud:    nacos:      discovery:        server-addr: 127.0.0.1:8848gateway:      routes:      - id: gateuri: lb://userpredicates:        #由/user-center來匹配跳轉(zhuǎn)        - Path=/user-center/**filters:        #跳轉(zhuǎn)后省略第一個(gè)通配        - StripPrefix=1#增加一個(gè)名稱為name,值為locky的請(qǐng)求參數(shù)        - AddRequestParameter=name,locky

所以我們?cè)诰W(wǎng)關(guān)中請(qǐng)求就可以不寫參數(shù),直接訪問

如何進(jìn)行第二代網(wǎng)關(guān)GateWay的搭建

  • AddResponseHeader

spring:  application:    name: gateway  cloud:    nacos:      discovery:        server-addr: 127.0.0.1:8848gateway:      routes:      - id: gateuri: lb://userpredicates:        #由/user-center來匹配跳轉(zhuǎn)        - Path=/user-center/**filters:        #跳轉(zhuǎn)后省略第一個(gè)通配        - StripPrefix=1#增加一個(gè)名稱為X-Response-Foo,值為Bar的響應(yīng)頭        - AddResponseHeader=X-Response-Foo, Bar

如何進(jìn)行第二代網(wǎng)關(guān)GateWay的搭建

  • DedupeResponseHeader

Spring Cloud Greenwich SR2提供的新特性,低于這個(gè)版本無法使用。
它的主要作用是去重,例如

spring:  application:    name: gateway  cloud:    nacos:      discovery:        server-addr: 127.0.0.1:8848gateway:      routes:      - id: gateuri: lb://userpredicates:        #由/user-center來匹配跳轉(zhuǎn)        - Path=/user-center/**
        - Cookie=test,valuefilters:        #跳轉(zhuǎn)后省略第一個(gè)通配        - StripPrefix=1#在Http響應(yīng)報(bào)文頭中進(jìn)行去重,去重目標(biāo)為跨域請(qǐng)求        - DedupeResponseHeader=Access-Control-Allow-Credentials Access-Control-Allow-Origin
  • Hystrix

Hystrix是Spring Cloud第一代中的容錯(cuò)組件,不過已經(jīng)進(jìn)入維護(hù)模式。未來,Hystrix會(huì)被Spring Cloud移除掉,取而代之的是Alibaba Sentinel/Resilience4J。

此處不做具體設(shè)置了

  • FallbackHeaders

也是對(duì)Hystrix的支持,不做具體設(shè)置了

  • PrefixPath

為匹配的路由添加前綴,我們?cè)趗ser模塊的find添加一層訪問路徑

@GetMapping("/test/find")@SuppressWarnings("unchecked")public Result<User> findStr() {log.info("訪問成功");    return Result.success(new User(1,"張三",23));}

網(wǎng)關(guān)配置

spring:  application:    name: gateway  cloud:    nacos:      discovery:        server-addr: 127.0.0.1:8848gateway:      routes:      - id: gateuri: lb://userpredicates:        #由/user-center來匹配跳轉(zhuǎn)        - Path=/user-center/**filters:        #跳轉(zhuǎn)后省略第一個(gè)通配        - StripPrefix=1#跳轉(zhuǎn)后添加前綴/test        - PrefixPath=/test

如何進(jìn)行第二代網(wǎng)關(guān)GateWay的搭建

如何進(jìn)行第二代網(wǎng)關(guān)GateWay的搭建

一致。

  • PreserveHostHeader

如果不設(shè)置,那么名為 Host 的Header由Http Client控制;如果設(shè)置了,那么會(huì)設(shè)置一個(gè)請(qǐng)求屬性(preserveHostHeader=true),路由過濾器會(huì)檢查從而去判斷是否要發(fā)送原始的、名為Host的Header。這里主要是通過網(wǎng)關(guān)是否向代理服務(wù)器轉(zhuǎn)發(fā)請(qǐng)求頭中的Host屬性。

spring:  application:    name: gateway  cloud:    nacos:      discovery:        server-addr: 127.0.0.1:8848gateway:      routes:      - id: gateuri: lb://userpredicates:        #由/user-center來匹配跳轉(zhuǎn)        - Path=/user-center/**filters:        #跳轉(zhuǎn)后省略第一個(gè)通配        - StripPrefix=1#轉(zhuǎn)發(fā)客戶端的請(qǐng)求報(bào)文頭Host給后端代理服務(wù)器        - PreserveHostHeader
  • RequestRateLimiter

Gateway自帶的限流服務(wù),但后續(xù)我們會(huì)整合Gateway和Sentinel來進(jìn)行限流和熔斷。

  • RedirectTo

轉(zhuǎn)發(fā)到后端服務(wù)后再重定向到一個(gè)url.

spring:  application:    name: gateway  cloud:    nacos:      discovery:        server-addr: 127.0.0.1:8848gateway:      routes:      - id: gateuri: lb://userpredicates:        #由/user-center來匹配跳轉(zhuǎn)        - Path=/user-center/**filters:        #跳轉(zhuǎn)后省略第一個(gè)通配        - StripPrefix=1#轉(zhuǎn)發(fā)到Path,并且攜帶一個(gè)http://www.baidu.com到Location的響應(yīng)頭        - RedirectTo=302,http://www.baidu.com

如何進(jìn)行第二代網(wǎng)關(guān)GateWay的搭建

如何進(jìn)行第二代網(wǎng)關(guān)GateWay的搭建

從以上圖中可以看出,其實(shí)我們請(qǐng)求的是http://127.0.0.1:8040/user-center/find,但是被重定向到了百度。這里HTTP狀態(tài)碼應(yīng)該是HTTP狀態(tài)碼300序列,例如301.302,具體狀態(tài)碼可以參考HTTP協(xié)議整理

  • RemoveHopByHopHeadersFilter

移除轉(zhuǎn)發(fā)請(qǐng)求的Header,多個(gè)用","分隔。默認(rèn)情況下移除如下Header。

  1. Connection

  2. Keep-Alive

  3. Proxy-Authenticate

  4. Proxy-Authorization

  5. TE

  6. Trailer

  7. Transfer-Encoding

  8. Upgrade

spring:  application:    name: gateway  cloud:    nacos:      discovery:        server-addr: 127.0.0.1:8848gateway:      routes:      - id: gateuri: lb://userpredicates:        #由/user-center來匹配跳轉(zhuǎn)        - Path=/user-center/**filters:        #跳轉(zhuǎn)后省略第一個(gè)通配        - StripPrefix=1      filter:        #移除轉(zhuǎn)發(fā)請(qǐng)求        remove-hop-by-hop:          headers: Keep-Alive,Connection
  • RemoveRequestHeader

移除原始請(qǐng)求頭

spring:  application:    name: gateway  cloud:    nacos:      discovery:        server-addr: 127.0.0.1:8848gateway:      routes:      - id: gateuri: lb://userpredicates:        #由/user-center來匹配跳轉(zhuǎn)        - Path=/user-center/**filters:        #跳轉(zhuǎn)后省略第一個(gè)通配        - StripPrefix=1#移除原始請(qǐng)求頭X-Request-Foo        - RemoveRequestHeader=X-Request-Foo

由spring cloud zuul網(wǎng)關(guān)的作用 可知,在跨域轉(zhuǎn)發(fā)中,我們需要移除這些請(qǐng)求頭

spring:  application:    name: gateway  cloud:    nacos:      discovery:        server-addr: 127.0.0.1:8848gateway:      routes:      - id: gateuri: lb://userpredicates:        #由/user-center來匹配跳轉(zhuǎn)        - Path=/user-center/**filters:        #跳轉(zhuǎn)后省略第一個(gè)通配        - StripPrefix=1#移除原始跨域請(qǐng)求頭        - RemoveRequestHeader=Access-Control-Allow-Origin      filter:        #移除轉(zhuǎn)發(fā)請(qǐng)求        remove-hop-by-hop:          headers: Access-Control-Allow-Credentials,Access-Control-Allow-Origin,Vary,X-Frame-Options,token
  • RemoveResponseHeader

移除響應(yīng)頭

我們?cè)趗ser中添加一個(gè)Controller方法

@GetMapping("/addhead")public String addHeader(HttpServletRequest request, HttpServletResponse response) {
    response.addHeader("X-Response-Foo","Foo");    return "header";}

如何進(jìn)行第二代網(wǎng)關(guān)GateWay的搭建

網(wǎng)關(guān)配置

spring:  application:    name: gateway  cloud:    nacos:      discovery:        server-addr: 127.0.0.1:8848gateway:      routes:      - id: gateuri: lb://userpredicates:        #由/user-center來匹配跳轉(zhuǎn)        - Path=/user-center/**filters:        #跳轉(zhuǎn)后省略第一個(gè)通配        - StripPrefix=1#移除響應(yīng)頭X-Response-Foo        - RemoveResponseHeader=X-Response-Foo

如何進(jìn)行第二代網(wǎng)關(guān)GateWay的搭建

通過網(wǎng)關(guān)轉(zhuǎn)發(fā),我們可以看到無此X-Response-Foo的響應(yīng)頭。

  • RewritePath

重寫請(qǐng)求路徑

spring:  application:    name: gateway  cloud:    nacos:      discovery:        server-addr: 127.0.0.1:8848gateway:      routes:      - id: gateuri: lb://userpredicates:        #由/user-center來匹配跳轉(zhuǎn)        - Path=/user-center/**filters:        #配置成原始路徑正則, 重寫后的路徑的正則        - RewritePath=/user-center/(?<segment>.*), /$\{segment}

以上配置會(huì)將/user-center/find變成/find再轉(zhuǎn)發(fā)

直接訪問user

如何進(jìn)行第二代網(wǎng)關(guān)GateWay的搭建

網(wǎng)關(guān)請(qǐng)求的

如何進(jìn)行第二代網(wǎng)關(guān)GateWay的搭建

  • RewriteResponseHeader

重寫響應(yīng)頭部分內(nèi)容,根據(jù)正則來修改

之前在user中有一個(gè)Controller方法

@GetMapping("/addhead")public String addHeader(HttpServletRequest request, HttpServletResponse response) {
    response.addHeader("X-Response-Foo","Foo");    return "header";}
spring:  application:    name: gateway  cloud:    nacos:      discovery:        server-addr: 127.0.0.1:8848gateway:      routes:      - id: gateuri: lb://userpredicates:        #由/user-center來匹配跳轉(zhuǎn)        - Path=/user-center/**filters:        #跳轉(zhuǎn)后省略第一個(gè)通配        - StripPrefix=1#重寫響應(yīng)頭X-Response-Foo的值Foo為dee,內(nèi)容可根據(jù)正則匹配        - RewriteResponseHeader=X-Response-Foo,Foo,dee

訪問user的/addhead,X-Response-Foo響應(yīng)頭的值為Foo.

如何進(jìn)行第二代網(wǎng)關(guān)GateWay的搭建

通過網(wǎng)關(guān)訪問/addhead,X-Response-Foo響應(yīng)頭的值為dee

如何進(jìn)行第二代網(wǎng)關(guān)GateWay的搭建

  • SaveSession

在轉(zhuǎn)發(fā)到后端微服務(wù)請(qǐng)求之前,強(qiáng)制執(zhí)行 WebSession::save 操作。用在那種像 Spring Session 延遲數(shù)據(jù)存儲(chǔ)(數(shù)據(jù)不是立刻持久化)的,并希望在請(qǐng)求轉(zhuǎn)發(fā)前確保session狀態(tài)保存情況。

現(xiàn)在我們對(duì)user進(jìn)行共享Session的配置,添加依賴

<dependency>   <groupId>org.springframework.boot</groupId>   <artifactId>spring-boot-starter-data-redis</artifactId></dependency><dependency>   <groupId>org.springframework.session</groupId>   <artifactId>spring-session-data-redis</artifactId></dependency><dependency>   <groupId>redis.clients</groupId>   <artifactId>jedis</artifactId>   <version>2.9.0</version></dependency>

添加配置

spring:
  redis:
    host: 127.0.0.1
    port: 6379
    password: xxxxx
    timeout: 10000
    lettuce:
      pool:
        min-idle: 0
        max-idle: 8
        max-active: 8
        max-wait: -1

在SpringBoot開啟共享Session

@EnableRedisHttpSession@SpringBootApplicationpublic class UserApplication {   public static void main(String[] args) {
      SpringApplication.run(UserApplication.class, args);   }

}

在user中添加如下Controller

@RestControllerpublic class SessionController {@GetMapping("/first")public Map<String,Object> firstResp(HttpServletRequest request, HttpServletResponse response) {
        Map<String,Object> map = new HashMap<>();        request.getSession().setAttribute("request Url",request.getRequestURL());        map.put("request Url",request.getRequestURL());        return map;    }@GetMapping("/sessions")public Object sessions(HttpServletRequest request,HttpServletResponse response) {
        Map<String,Object> map = new HashMap<>();        map.put("SessionId",request.getSession().getId());        map.put("message",request.getSession().getAttribute("request Url"));        return map;    }
}

我們啟動(dòng)兩個(gè)user實(shí)例,一個(gè)端口號(hào)為8082,一個(gè)為8083,訪問如下

如何進(jìn)行第二代網(wǎng)關(guān)GateWay的搭建

如何進(jìn)行第二代網(wǎng)關(guān)GateWay的搭建

如何進(jìn)行第二代網(wǎng)關(guān)GateWay的搭建

如何進(jìn)行第二代網(wǎng)關(guān)GateWay的搭建

我們可以看到除了存入Session的RequestURL不同以外,他們的SessionId是相同的,說明這里是一個(gè)共享的Session。

我們不對(duì)網(wǎng)關(guān)配置做修改,則我們通過網(wǎng)關(guān)訪問

如何進(jìn)行第二代網(wǎng)關(guān)GateWay的搭建

如何進(jìn)行第二代網(wǎng)關(guān)GateWay的搭建

在訪問first的時(shí)候,它會(huì)負(fù)載均衡這兩個(gè)實(shí)例,但我們可以看到他在Session中存儲(chǔ)的是內(nèi)網(wǎng)的IP,而不是127.0.0.1。

如何進(jìn)行第二代網(wǎng)關(guān)GateWay的搭建

在網(wǎng)關(guān)做如下配置

spring:  application:    name: gateway  cloud:    nacos:      discovery:        server-addr: 127.0.0.1:8848gateway:      routes:      - id: gateuri: lb://userpredicates:        #由/user-center來匹配跳轉(zhuǎn)        - Path=/user-center/**filters:        #跳轉(zhuǎn)后省略第一個(gè)通配        - StripPrefix=1#請(qǐng)求轉(zhuǎn)發(fā)前保存Session        - SaveSession

目前未測(cè)出有什么太大的作用。反而會(huì)破壞Session的數(shù)據(jù)。所以不建議增加該設(shè)置。

  • SecureHeaders

添加一系列起安全作用的響應(yīng)頭。

默認(rèn)會(huì)添加如下Header(包括值):

  1. X-Xss-Protection:1; mode=block 防XSS攻擊設(shè)置,0: 表示關(guān)閉瀏覽器的XSS防護(hù)機(jī)制;1:刪除檢測(cè)到的惡意代碼, 如果響應(yīng)報(bào)文中沒有看到X-XSS-Protection 字段,那么瀏覽器就認(rèn)為X-XSS-Protection配置為1,這是瀏覽器的默認(rèn)設(shè)置.1; mode=block:如果檢測(cè)到惡意代碼,在不渲染惡意代碼.

  2. Strict-Transport-Security:max-age=631138519 一個(gè)網(wǎng)站接受一個(gè)HTTP的請(qǐng)求,然后跳轉(zhuǎn)到HTTPS,用戶可能在開始跳轉(zhuǎn)前,通過沒有加密的方式和服務(wù)器對(duì)話,比如,用戶輸入http://foo.com或者直接foo.com。這樣存在中間人攻擊潛在威脅,跳轉(zhuǎn)過程可能被惡意網(wǎng)站利用來直接接觸用戶信息,而不是原來的加密信息。網(wǎng)站通過HTTP Strict Transport Security通知瀏覽器,這個(gè)網(wǎng)站禁止使用HTTP方式加載,瀏覽器應(yīng)該自動(dòng)把所有嘗試使用HTTP的請(qǐng)求自動(dòng)替換為HTTPS請(qǐng)求。

  3. X-Frame-Options:DENY 點(diǎn)擊劫持(ClickJacking)是一種視覺上的欺騙手段。攻擊者使用一個(gè)透明的iframe,覆蓋在一個(gè)網(wǎng)頁上,然后誘使用戶在網(wǎng)頁上進(jìn)行操作,此時(shí)用戶將在不知情的情況下點(diǎn)擊透明的iframe頁面。通過調(diào)整iframe頁面的位置,可以誘使用戶恰好點(diǎn)擊在iframe頁面的一些功能性按鈕上。
    HTTP響應(yīng)頭信息中的X-Frame-Options,可以指示瀏覽器是否應(yīng)該加載一個(gè)iframe中的頁面。如果服務(wù)器響應(yīng)頭信息中沒有X-Frame-Options,則該網(wǎng)站存在ClickJacking攻擊風(fēng)險(xiǎn)。網(wǎng)站可以通過設(shè)置X-Frame-Options阻止站點(diǎn)內(nèi)的頁面被其他頁面嵌入從而防止點(diǎn)擊劫持。
    解決方案:
    修改web服務(wù)器配置,添加X-Frame-Options響應(yīng)頭。賦值有如下三種:
    1、DENY:不能被嵌入到任何iframe或者frame中。
    2、SAMEORIGIN:頁面只能被本站頁面嵌入到iframe或者frame中
    3、ALLOW-FROM uri:只能被嵌入到指定域名的框架中

  4. X-Content-Type-Options:nosniff

    如果服務(wù)器發(fā)送響應(yīng)頭 "X-Content-Type-Options: nosniff",則 script 和 styleSheet 元素會(huì)拒絕包含錯(cuò)誤的 MIME 類型的響應(yīng)。這是一種安全功能,有助于防止基于 MIME 類型混淆的攻擊。

     

    簡單理解為:通過設(shè)置"X-Content-Type-Options: nosniff"響應(yīng)標(biāo)頭,對(duì) script 和 styleSheet 在執(zhí)行是通過MIME 類型來過濾掉不安全的文件

    服務(wù)器發(fā)送含有 "X-Content-Type-Options: nosniff" 標(biāo)頭的響應(yīng)時(shí),此更改會(huì)影響瀏覽器的行為。

  5. Referrer-Policy:no-referrer

    referrer是HTTP請(qǐng)求header的報(bào)文頭,用于指明當(dāng)前流量的來源參考頁面。通過這個(gè)信息,我們可以知道訪客是怎么來到當(dāng)前頁面的。這對(duì)于Web Analytics非常重要,可以用于分析不同渠道流量分布、用戶搜索的關(guān)鍵詞等。
    但是,這個(gè)字段同時(shí)會(huì)造成用戶敏感信息泄漏(如:帶有敏感信息的重置密碼URL,若被Web Analytics收集,則存在密碼被重置的危險(xiǎn))。

    Referrer Policy States

    新的Referrer規(guī)定了五種策略:

  • No Referrer:任何情況下都不發(fā)送Referrer信息

  • No Referrer When Downgrade:僅當(dāng)協(xié)議降級(jí)(如HTTPS頁面引入HTTP資源)時(shí)不發(fā)送Referrer信息。是大部分瀏覽器默認(rèn)策略。

  • Origin Only:發(fā)送只包含host部分的referrer.

  • Origin When Cross-origin:僅在發(fā)生跨域訪問時(shí)發(fā)送只包含host的Referer,同域下還是完整的。與Origin Only的區(qū)別是多判斷了是否Cross-origin。協(xié)議、域名和端口都一致,瀏覽器才認(rèn)為是同域。

  • Unsafe URL:全部都發(fā)送Referrer信息。最寬松最不安全的策略。

  1. Content-Security-Policy:default-src 'self' https:; font-src 'self' https: data:; img-src 'self' https: data:; object-src 'none'; script-src https:; style-src 'self' https: 'unsafe-inline' 內(nèi)容安全策略(CSP),其核心思想十分簡單:網(wǎng)站通過發(fā)送一個(gè) CSP 頭部,來告訴瀏覽器什么是被授權(quán)執(zhí)行的與什么是需要被禁止的。其被譽(yù)為專門為解決XSS攻擊而生的神器。具體參考https://blog.csdn.net/u014465934/article/details/84199171

  2. X-Download-Options:noopen

    用于放置直接打開用戶下載文件。

    X-Download-Options: noopen


  • noopen 用于指定IE 8以上版本的用戶不打開文件而直接保存文件。在下載對(duì)話框中不顯示“打開”選項(xiàng)。

  1. X-Permitted-Cross-Domain-Policies:none

    用于指定當(dāng)不能將"crossdomain.xml"文件(當(dāng)需要從別的域名中的某個(gè)文件中讀取 Flash 內(nèi)容時(shí)用于進(jìn)行必要設(shè)置的策略文件)放置在網(wǎng)站根目錄等場合時(shí)采取的替代策略。

    X-Permitted-Cross-Domain-Policies: master-only


  • master-only 只允許使用主策略文件(/crossdomain.xml)

如果你想修改這些Header的值,可使用如下配置:

spring:  application:    name: gateway  cloud:    nacos:      discovery:        server-addr: 127.0.0.1:8848gateway:      routes:      - id: gateuri: lb://userpredicates:        #由/user-center來匹配跳轉(zhuǎn)        - Path=/user-center/**filters:        #跳轉(zhuǎn)后省略第一個(gè)通配        - StripPrefix=1      filter:        secure-headers:          xss-protection-header: 1;mode=block

上面的header對(duì)應(yīng)的后綴:

  1. xss-protection-header

  2. strict-transport-security

  3. frame-options

  4. content-type-options

  5. referrer-policy

  6. content-security-policy

  7. download-options

  8. permitted-cross-domain-policies

如果想禁用某些Header,可使用如下配置:spring.cloud.gateway.filter.secure-headers.disable ,多個(gè)用 , 分隔。例如:

spring:  application:    name: gateway  cloud:    nacos:      discovery:        server-addr: 127.0.0.1:8848gateway:      routes:      - id: gateuri: lb://userpredicates:        #由/user-center來匹配跳轉(zhuǎn)        - Path=/user-center/**filters:        #跳轉(zhuǎn)后省略第一個(gè)通配        - StripPrefix=1      filter:        secure-headers:          disable: frame-options,download-options
  • SetPath

spring:  application:    name: gateway  cloud:    nacos:      discovery:        server-addr: 127.0.0.1:8848gateway:      routes:      - id: gateuri: lb://userpredicates:        #由/user-center來匹配跳轉(zhuǎn)        - Path=/user-center/{segment}filters:        #使用/{segment}來代替/user-center/{segment}后轉(zhuǎn)發(fā)        - SetPath=/{segment}

如何進(jìn)行第二代網(wǎng)關(guān)GateWay的搭建

用意跟之前差不多。

  • SetResponseHeader

在User項(xiàng)目中有這樣一個(gè)Controller方法

@GetMapping("/addhead")public String addHeader(HttpServletRequest request, HttpServletResponse response) {
    response.addHeader("X-Response-Foo","Foo");    return "header";}
spring:  application:    name: gateway  cloud:    nacos:      discovery:        server-addr: 127.0.0.1:8848gateway:      routes:      - id: gateuri: lb://userpredicates:        #由/user-center來匹配跳轉(zhuǎn)        - Path=/user-center/**filters:        #跳轉(zhuǎn)后省略第一個(gè)通配        - StripPrefix=1#將響應(yīng)頭X-Response-Foo的值更改為dee        - SetResponseHeader=X-Response-Foo,dee

如何進(jìn)行第二代網(wǎng)關(guān)GateWay的搭建

  • SetStatus

修改響應(yīng)的狀態(tài)碼,值可以是數(shù)字,也可以是字符串。但一定要是Spring HttpStatus 枚舉類中的值。

spring:  application:    name: gateway  cloud:    nacos:      discovery:        server-addr: 127.0.0.1:8848gateway:      routes:      - id: gateuri: lb://userpredicates:        #由/user-center來匹配跳轉(zhuǎn)        - Path=/user-center/**filters:        #跳轉(zhuǎn)后省略第一個(gè)通配        - StripPrefix=1#修改返回狀態(tài)碼為401        - SetStatus=401

如何進(jìn)行第二代網(wǎng)關(guān)GateWay的搭建

這里是可以正常返回結(jié)果的,只不過狀態(tài)碼被修改為401

  • StripPrefix

數(shù)字表示要截?cái)嗟穆窂降臄?shù)量。

  • Retry

針對(duì)不同的響應(yīng)做重試,可配置如下參數(shù):

  1. retries: 重試次數(shù)

  2. statuses: 需要重試的狀態(tài)碼,取值在 org.springframework.http.HttpStatus 中

  3. methods: 需要重試的請(qǐng)求方法,取值在 org.springframework.http.HttpMethod 中

  4. series: HTTP狀態(tài)碼系列,取值在 org.springframework.http.HttpStatus.Series 中

spring:  application:    name: gateway  cloud:    nacos:      discovery:        server-addr: 127.0.0.1:8848gateway:      routes:      - id: gateuri: lb://userpredicates:        #由/user-center來匹配跳轉(zhuǎn)        - Path=/user-center/**filters:        #跳轉(zhuǎn)后省略第一個(gè)通配        - StripPrefix=1#如果方法未找到,重試3次        - name: Retry          args:            retries: 3statuses: NOT_FOUND
  • RequestSize

為后端服務(wù)設(shè)置收到的最大請(qǐng)求包大小。如果請(qǐng)求大小超過設(shè)置的值,則返回 413 Payload Too Large 。默認(rèn)值是5M
不過這里我設(shè)置了1字節(jié),好像不起作用。

spring:  application:    name: gateway  cloud:    nacos:      discovery:        server-addr: 127.0.0.1:8848gateway:      routes:      - id: gateuri: lb://userpredicates:        #由/user-center來匹配跳轉(zhuǎn)        - Path=/user-center/**filters:        #跳轉(zhuǎn)后省略第一個(gè)通配        - StripPrefix=1#如果請(qǐng)求包超過1字節(jié),返回413        - name: RequestSize          args:            maxSize: 1

經(jīng)測(cè)試無效

  • Modify Request Body

可用于在Gateway將請(qǐng)求發(fā)送給后端微服務(wù)之前,修改請(qǐng)求體內(nèi)容。該過濾器工廠目前處于BETA狀態(tài),不建議使用。

  • Modify Response Body

可用于修改響應(yīng)體內(nèi)容。該過濾器工廠目前處于BETA狀態(tài),不建議使用。

  • Default

如果你想為所有路由添加過濾器,可使用該屬性。

spring:  application:    name: gateway  cloud:    nacos:      discovery:        server-addr: 127.0.0.1:8848gateway:      routes:      - id: gateuri: lb://userpredicates:        #由/user-center來匹配跳轉(zhuǎn)        - Path=/user-center/**      #該配置對(duì)所有的routes.id均有效      default-filters:      #跳轉(zhuǎn)后省略第一個(gè)通配      - StripPrefix=1

自定義過濾器工廠

  • 過濾器生命周期

  1. pre: Gateway轉(zhuǎn)發(fā)請(qǐng)求之前

  2. post: Gateway轉(zhuǎn)發(fā)請(qǐng)求之后

  • 自定義過濾器工廠的方式

  1. 繼承: AbstractGatewayFilterFactory

  2. 繼承: AbstractNameValueGatewayFilterFactory

  • 核心API

  1. exchange.getRequest().mutate().xxx //修改request

  2. exchange.mutate().xxx //修改exchange

  3. chain.filter(exchange) //傳遞給下一個(gè)過濾器處理

  4. exchange.getResponse //拿到響應(yīng)

  • 編寫一個(gè)過濾器工廠

現(xiàn)在我們來寫一個(gè)打印日志的過濾器工廠,該自定義過濾器工廠必須以GatewayFilterFactory結(jié)尾

@Slf4j@Componentpublic class PreLogGatewayFilterFactory extends AbstractNameValueGatewayFilterFactory {@Override    public GatewayFilter apply(NameValueConfig config) {return (((exchange, chain) -> {log.info("請(qǐng)求進(jìn)來了...{},{}",config.getName(),config.getValue());            //獲取請(qǐng)求            ServerHttpRequest modifiedRequest = exchange.getRequest()
                    .mutate()
                    .build();            //獲取exchange            ServerWebExchange modifiedExchange = exchange.mutate()
                    .request(modifiedRequest)
                    .build();            //傳遞給下一個(gè)過濾器            return chain.filter(modifiedExchange);        }));    }
}

配置文件

spring:  application:    name: gateway  cloud:    nacos:      discovery:        server-addr: 127.0.0.1:8848gateway:      routes:      - id: gateuri: lb://userpredicates:        #由/user-center來匹配跳轉(zhuǎn)        - Path=/user-center/**filters:        #跳轉(zhuǎn)后省略第一個(gè)通配        - StripPrefix=1#打印a,b日志        - PreLog=a,b

運(yùn)行后,我們通過網(wǎng)關(guān)訪問API后,打印日志如下

2019-12-20 14:09:48.066  INFO 2702 --- [ctor-http-nio-2] c.c.c.m.g.c.PreLogGatewayFilterFactory   : 請(qǐng)求進(jìn)來了...a,b

全局過濾器

1 Combined Global Filter and GatewayFilter Ordering
2 Forward Routing Filter
3 LoadBalancerClient Filter
4 Netty Routing Filter
5 Netty Write Response Filter
6 RouteToRequestUrl Filter
7 Websocket Routing Filter
8 Gateway Metrics Filter
9 Marking An Exchange As Routed

  • Global Filter and GatewayFilter Ordering

當(dāng)請(qǐng)求到來時(shí),Filtering Web Handler 處理器會(huì)添加所有 GlobalFilter 實(shí)例和匹配的 GatewayFilter 實(shí)例到過濾器鏈中。

過濾器鏈會(huì)使用 org.springframework.core.Ordered 注解所指定的順序,進(jìn)行排序。Spring Cloud Gateway區(qū)分了過濾器邏輯執(zhí)行的”pre”和”post”階段,所以優(yōu)先級(jí)高的過濾器將會(huì)在pre階段最先執(zhí)行,優(yōu)先級(jí)最低的過濾器則在post階段最后執(zhí)行。數(shù)值越小越靠前執(zhí)行。

@Slf4j@Configurationpublic class GlobleFilters {@Bean    @Order(-1)public GlobalFilter a() {return ((exchange, chain) -> {log.info("first pre filter");            return chain.filter(exchange).then(Mono.fromRunnable(
                    () -> log.info("third post filter")));        });    }@Bean    @Order(0)public GlobalFilter b() {return ((exchange, chain) -> {log.info("second pre filter");            return chain.filter(exchange).then(Mono.fromRunnable(
                    () -> log.info("second post filter")));        });    }@Bean    @Order(1)public GlobalFilter c() {return ((exchange, chain) -> {log.info("third pre filter");            return chain.filter(exchange).then(Mono.fromRunnable(
                    () -> log.info("first post filter")));        });    }
}

當(dāng)有網(wǎng)關(guān)轉(zhuǎn)發(fā)請(qǐng)求時(shí)

2019-12-20 15:03:34.263  INFO 3380 --- [ctor-http-nio-2] c.c.c.m.gateway.config.GlobleFilters     : first pre filter
2019-12-20 15:03:34.263  INFO 3380 --- [ctor-http-nio-2] c.c.c.m.gateway.config.GlobleFilters     : second pre filter
2019-12-20 15:03:34.263  INFO 3380 --- [ctor-http-nio-2] c.c.c.m.gateway.config.GlobleFilters     : third pre filter
2019-12-20 15:03:34.302  INFO 3380 --- [ctor-http-nio-7] c.c.c.m.gateway.config.GlobleFilters     : first post filter
2019-12-20 15:03:34.302  INFO 3380 --- [ctor-http-nio-7] c.c.c.m.gateway.config.GlobleFilters     : second post filter
2019-12-20 15:03:34.302  INFO 3380 --- [ctor-http-nio-7] c.c.c.m.gateway.config.GlobleFilters     : third post filter

  • Forward Routing Filter

整合Sentinel限流

Sentinel的版本必須在1.6及以上,我們這里為1.7

pom

<dependency>   <groupId>com.alibaba.csp</groupId>   <artifactId>sentinel-spring-cloud-gateway-adapter</artifactId></dependency>

添加配置類

@Configurationpublic class GatewayConfig {private final List<ViewResolver> viewResolvers;    private final ServerCodecConfigurer serverCodecConfigurer;    public GatewayConfig(ObjectProvider<List<ViewResolver>> viewResolverProvider,                         ServerCodecConfigurer serverCodecConfigurer) {this.viewResolvers = viewResolverProvider.getIfAvailable(Collections::emptyList);        this.serverCodecConfigurer = serverCodecConfigurer;    }@Bean    @Order(Ordered.HIGHEST_PRECEDENCE)public SentinelGatewayBlockExceptionHandler sentinelGatewayBlockExceptionHandler() {return new SentinelGatewayBlockExceptionHandler(viewResolvers,serverCodecConfigurer);    }@Bean    @Order(Ordered.HIGHEST_PRECEDENCE)public GlobalFilter sentinelGatewayFilter() {return new SentinelGatewayFilter();    }@PostConstruct    public void doInit() {
        initGatewayRules();    }/**     * 配置限流規(guī)則     */    private void initGatewayRules() {
        Set<GatewayFlowRule> rules = new HashSet<>();        rules.add(new GatewayFlowRule("gate")
                    .setCount(1) //限流閾值                    .setIntervalSec(1)); //統(tǒng)計(jì)時(shí)間窗口,單位是秒,默認(rèn)是1秒        GatewayRuleManager.loadRules(rules);    }
}

我們這里設(shè)置的為1秒鐘只能通過一個(gè)請(qǐng)求。

如何進(jìn)行第二代網(wǎng)關(guān)GateWay的搭建

如果我們?cè)?秒鐘內(nèi)請(qǐng)求兩次或以上,就會(huì)產(chǎn)生限流提示。

網(wǎng)關(guān)跨域設(shè)置

import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.web.cors.CorsConfiguration;import org.springframework.web.cors.reactive.CorsWebFilter;import org.springframework.web.cors.reactive.UrlBasedCorsConfigurationSource;import org.springframework.web.util.pattern.PathPatternParser;/** * 跨域配置 */@Configurationpublic class CrossDomainConfig {@Bean    public CorsWebFilter corsFilter() {
        CorsConfiguration config = new CorsConfiguration();        config.addAllowedMethod("*");        config.addAllowedOrigin("*");        config.addAllowedHeader("*");        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(new PathPatternParser());        source.registerCorsConfiguration("/**", config);        return new CorsWebFilter(source);    }
}

或配置文件配置

spring:  application:    name: gateway  cloud:    nacos:      discovery:        server-addr: xxx.xxx.xxx.xxx:8848gateway:      discovery:        locator:          enabled: true      # 跨域      globalcors:        corsConfigurations:          '[/**]':          allowedHeaders: "*"          allowedOrigins: "*"          allowedMethods:          - GET
            POST
            DELETE
            PUT
            OPTION

看完上述內(nèi)容是否對(duì)您有幫助呢?如果還想對(duì)相關(guān)知識(shí)有進(jìn)一步的了解或閱讀更多相關(guān)文章,請(qǐng)關(guān)注億速云行業(yè)資訊頻道,感謝您對(duì)億速云的支持。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI