日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網(wǎng)為廣大站長(zhǎng)提供免費(fèi)收錄網(wǎng)站服務(wù),提交前請(qǐng)做好本站友鏈:【 網(wǎng)站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(wù)(50元/站),

點(diǎn)擊這里在線咨詢客服
新站提交
  • 網(wǎng)站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會(huì)員:747

文章已收錄到我的Github精選,歡迎Star:https://github.com/yehongzhi/learningSummary

介紹服務(wù)網(wǎng)關(guān)

要認(rèn)識(shí)一樣?xùn)|西,最好的方法是從為什么需要他開始說起。

按照現(xiàn)在主流使用微服務(wù)架構(gòu)的特點(diǎn),假設(shè)現(xiàn)在有A、B、C三個(gè)服務(wù),假如這三個(gè)服務(wù)都需要做一些請(qǐng)求過濾和權(quán)限校驗(yàn),請(qǐng)問怎么實(shí)現(xiàn)?

  • 每個(gè)服務(wù)自己實(shí)現(xiàn)一遍。
  • 寫在一個(gè)公共的服務(wù),然后讓A、B、C服務(wù)引入公共服務(wù)的Maven依賴。
  • 使用服務(wù)網(wǎng)關(guān),所有客戶端請(qǐng)求服務(wù)網(wǎng)關(guān)進(jìn)行請(qǐng)求過濾和權(quán)限校驗(yàn),然后再路由轉(zhuǎn)發(fā)到A、B、C服務(wù)。

第一種方式顯然是逆天的,這里不做討論。第二種方法稍微聰明點(diǎn),但是如果公共服務(wù)的邏輯發(fā)生改變,那么所有依賴公共服務(wù)的服務(wù)都需要重新打包部署才能生效。

所以顯而易見,使用服務(wù)網(wǎng)關(guān)則解決了以上的問題,其他服務(wù)不需要加入什么依賴,只需要在網(wǎng)關(guān)配置一些參數(shù),然后就能路由轉(zhuǎn)發(fā)到對(duì)應(yīng)的后端服務(wù),如果需要請(qǐng)求過濾和權(quán)限檢驗(yàn)的話,都可以在網(wǎng)關(guān)層實(shí)現(xiàn),如果需要更新權(quán)限校驗(yàn)的邏輯,只需要網(wǎng)關(guān)層修改就可以,其他后端服務(wù)不需要修改。

接下來再介紹一下服務(wù)網(wǎng)關(guān)的功能,主要有:

  • 路由轉(zhuǎn)發(fā)
  • API監(jiān)控
  • 權(quán)限控制
  • 限流

所以服務(wù)網(wǎng)關(guān)很重要!那么接下來我們就以目前比較主流的GateWay進(jìn)行學(xué)習(xí)吧。

GateWay入門

首先第一步需要?jiǎng)?chuàng)建一個(gè)作為網(wǎng)關(guān)的項(xiàng)目,這里使用的SpringBoot版本是2.0.1,引入依賴:

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

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>Finchley.SR1</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

我們需要使用網(wǎng)關(guān)轉(zhuǎn)發(fā)請(qǐng)求,那么首先需要有個(gè)后端服務(wù),這里我簡(jiǎn)單地創(chuàng)建了一個(gè)user項(xiàng)目。然后啟動(dòng)user項(xiàng)目,寫個(gè)獲取所有用戶信息的接口:

服務(wù)網(wǎng)關(guān)Gateway怎么玩?

 

那么我們現(xiàn)在配置網(wǎng)關(guān)的Application.yml實(shí)現(xiàn)請(qǐng)求轉(zhuǎn)發(fā)。

server:
  port: 9201
spring:
  application:
    name: api-gateway
  cloud:
    gateway:
      routes:
        - id: user_getList #路由的ID
          uri: http://localhost:8080/user/getList #最終目標(biāo)的請(qǐng)求地址
          predicates: #斷言
            - Path=/user/getList #路徑相匹配的進(jìn)行路由

也就是說我請(qǐng)求http://localhost:9201/user/getList后,9201端口是網(wǎng)關(guān)服務(wù),會(huì)匹配/user/getList的路由,最終轉(zhuǎn)發(fā)到目標(biāo)地址http://localhost:8080/user/getList。

服務(wù)網(wǎng)關(guān)Gateway怎么玩?

 

這就算是gateway網(wǎng)關(guān)的簡(jiǎn)單使用了。

繼續(xù)深入

在上面入門的例子中,我們注意到有個(gè)predicates的配置,有點(diǎn)對(duì)其似懂非懂的感覺。中文翻譯過來叫做斷言,有點(diǎn)類似于JAVA8的Stream流里的Predicate函數(shù)的意思。如果斷言是真的,則匹配路由。

除此之外,gateway的另一個(gè)核心是Filter(過濾器),F(xiàn)ilter有全局和局部?jī)煞N。那么整個(gè)gateway的流程是怎么樣的呢?請(qǐng)看下圖:

服務(wù)網(wǎng)關(guān)Gateway怎么玩?

 

從圖中可以看出,gateway的兩大核心就是斷言(Predicate)和過濾(Filter),接下來我們重點(diǎn)講講這兩者的使用。

Route Predicate 的使用

Spring Cloud Gateway包括許多內(nèi)置的Route Predicate工廠,所以可以直接通過配置直接使用各種內(nèi)置的Predicate。

After Route Predicate

在指定的時(shí)間之后請(qǐng)求匹配該路由。

spring:
  cloud:
    gateway:
      routes:
        - id: user_getList
          uri: http://localhost:8080/user/getList
          predicates:
            - After=2021-10-30T01:00:00+08:00[Asia/Shanghai]

Before Route Predicate

在指定時(shí)間之前的請(qǐng)求會(huì)匹配該路由。

spring:
  cloud:
    gateway:
      routes:
        - id: user_getList
          uri: http://localhost:8080/user/getList
          predicates:
            - Before=2021-10-30T02:00:00+08:00[Asia/Shanghai]

Between Route Predicate

在指定時(shí)間區(qū)間內(nèi)的請(qǐng)求會(huì)匹配該路由。

spring:
  cloud:
    gateway:
      routes:
        - id: user_getList
          uri: http://localhost:8080/user/getList
          predicates:
           - Between=2021-10-30T01:00:00+08:00[Asia/Shanghai],2021-10-30T02:00:00+08:00[Asia/Shanghai]

Cookie Route Predicate

帶有指定Cookie的請(qǐng)求會(huì)匹配該路由。

spring:
  cloud:
    gateway:
      routes:
        - id: user_getList
          uri: http://localhost:8080/user/getList
          predicates:
           - Cookie=username,yehongzhi

使用POSTMAN發(fā)送帶有Cookie里username=yehongzhi的請(qǐng)求。

服務(wù)網(wǎng)關(guān)Gateway怎么玩?

 

Header Route Predicate

帶有指定請(qǐng)求頭的請(qǐng)求會(huì)匹配該路由。

spring:
  cloud:
    gateway:
      routes:
        - id: user_getList
          uri: http://localhost:8080/user/getList
          predicates:
         - Header=X-Id, d+

使用POSTMAN發(fā)送請(qǐng)求頭帶有X-Id的請(qǐng)求。

服務(wù)網(wǎng)關(guān)Gateway怎么玩?

 

Host Route Predicate

帶有指定Host的請(qǐng)求會(huì)匹配該路由。

spring:
  cloud:
    gateway:
      routes:
        - id: user_getList
          uri: http://localhost:8080/user/getList
          predicates:
            - Host=**.yehongzhi.com

使用POSTMAN發(fā)送請(qǐng)求頭帶有Host=www.yehongzhi.com的請(qǐng)求。

服務(wù)網(wǎng)關(guān)Gateway怎么玩?

 

Path Route Predicate

發(fā)送指定路徑的請(qǐng)求會(huì)匹配該路由。

spring:
  cloud:
    gateway:
      routes:
        - id: user_getList
          uri: http://localhost:8080/user/getList
          predicates:
            - Path=/user/getList

直接在瀏覽器輸入該地址http://localhost:9201/user/getList,即可訪問。

Method Route Predicate

發(fā)送指定方法的請(qǐng)求會(huì)匹配該路由。

spring:
  cloud:
    gateway:
      routes:
        - id: user_getList
          uri: http://localhost:8080/user/getList
          predicates:
            - Method=POST

用POSTMAN以POST方式發(fā)送請(qǐng)求。

服務(wù)網(wǎng)關(guān)Gateway怎么玩?

 

Query Route Predicate

帶指定查詢參數(shù)的請(qǐng)求可以匹配該路由。

spring:
  cloud:
    gateway:
      routes:
        - id: user_query_byName
          uri: http://localhost:8080/user/query/byName
          predicates:
            - Query=name

在瀏覽器輸入http://localhost:9201/user/query/byName?name=tom地址,發(fā)送請(qǐng)求。

服務(wù)網(wǎng)關(guān)Gateway怎么玩?

 

Weight Route Predicate

使用權(quán)重來路由相應(yīng)請(qǐng)求,以下配置表示有80%的請(qǐng)求會(huì)被路由到localhost:8080,20%的請(qǐng)求會(huì)被路由到localhost:8081。

spring:
  cloud:
    gateway:
      routes:
        - id: user_1
          uri: http://localhost:8080
          predicates:
            - Weight=group1, 8
        - id: user_2
          uri: http://localhost:8081
          predicates:
            - Weight=group1, 2

RemoteAddr Route Predicate

從指定的遠(yuǎn)程地址發(fā)起的請(qǐng)求可以匹配該路由。

spring:
  cloud:
    gateway:
      routes:
        - id: user_1
          uri: http://localhost:8080/user/getList
          predicates:
            - RemoteAddr=192.168.1.4

使用瀏覽器請(qǐng)求。

服務(wù)網(wǎng)關(guān)Gateway怎么玩?

 

組合使用

spring:
  cloud:
    gateway:
      routes:
        - id: user_1
          uri: http://localhost:8080/user/getList
          predicates:
            - RemoteAddr=192.168.1.4
            - Method=POST
            - Cookie=username,yehongzhi
            - Path=/user/getList

使用POSTMAN發(fā)起請(qǐng)求,使用POST方式,uri是/user/getList,帶有Cookie,RemoteAddr。

服務(wù)網(wǎng)關(guān)Gateway怎么玩?

 

自定義Predicate

如果我們需要自定義Predicate,怎么玩呢?其實(shí)很簡(jiǎn)單,看源碼,有樣學(xué)樣,需要繼承AbstractRoutePredicateFactory類。

下面舉個(gè)例子,需求是token值為abc的則匹配路由,怎么寫呢,請(qǐng)看代碼:

@Component
public class TokenRoutePredicateFactory extends AbstractRoutePredicateFactory<TokenRoutePredicateFactory.Config> {

    public static final String TOKEN_KEY = "tokenValue";

    public TokenRoutePredicateFactory() {
        //當(dāng)前類的Config類,會(huì)利用反射創(chuàng)建Config并賦值,在apply傳回來
        super(TokenRoutePredicateFactory.Config.class);
    }

    @Override
    public List<String> shortcutFieldOrder() {
        //"tokenValue"跟Config的接收字段一致
        return Arrays.asList(TOKEN_KEY);
    }

    @Override
    public Predicate<ServerWebExchange> apply(Config config) {
        //這里獲取的config對(duì)象就是下面自定義的Config對(duì)象
        return new Predicate<ServerWebExchange>() {
            @Override
            public boolean test(ServerWebExchange exchange) {
                MultiValueMap<String, String> params = exchange.getRequest().getQueryParams();
                //獲取請(qǐng)求參數(shù)
                String value = params.getFirst("token");
                //請(qǐng)求參數(shù)和配置文件定義的token進(jìn)行對(duì)比,相等則返回true
                return config.getTokenValue() != null && config.getTokenValue().equals(value);
            }
        };
    }
 //用來接收配置文件定義的值
    public static class Config {

        private String tokenValue;

        public String getTokenValue() {
            return tokenValue;
        }

        public void setTokenValue(String tokenValue) {
            this.tokenValue = tokenValue;
        }
    }
}

這里需要注意的一點(diǎn)是類名必須是RoutePredicateFactory結(jié)尾,前面的則作為配置名。比如TokenRoutePredicateFactory的配置名則為Token,這是一個(gè)約定的配置。

接著在配置文件中加上該配置:

spring:
  cloud:
    gateway:
      routes:
        - id: user_1
          uri: http://localhost:8080/user/getList
          predicates:
            - Token=abc ##使用TokenRoutePredicateFactory進(jìn)行斷言

然后用POSTMAN發(fā)送請(qǐng)求,帶上token參數(shù),參數(shù)值為abc。

服務(wù)網(wǎng)關(guān)Gateway怎么玩?

 

如果token的值不正確的話,會(huì)報(bào)404。

服務(wù)網(wǎng)關(guān)Gateway怎么玩?

 

整合注冊(cè)中心

為什么要整合注冊(cè)中心呢?因?yàn)槊總€(gè)服務(wù)一般背后都不只一臺(tái)機(jī)器,而且一般使用服務(wù)名進(jìn)行配置,而不是配置服務(wù)的IP地址,并且要實(shí)現(xiàn)負(fù)載均衡調(diào)用。

這里我就使用Nacos作為注冊(cè)中心。

引入Maven依賴:

<dependency><!-- SpringCloud nacos服務(wù)發(fā)現(xiàn)的依賴 -->
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>Finchley.SR1</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-alibaba-dependencies</artifactId>
            <version>0.2.2.RELEASE</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

啟動(dòng)類加上注解,開啟注冊(cè)中心。

@SpringBootApplication
@EnableDiscoveryClient
public class GatewayApplication {
    public static void main(String[] args) {
        SpringApplication.run(GatewayApplication.class, args);
    }
}

在application.yml加上配置:

spring:
  application:
    name: api-gateway
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848
        service: ${spring.application.name}
    gateway:
      routes:
        - id: consumer
          uri: lb://consumer #使用lb協(xié)議,consumer是服務(wù)名,不再使用IP地址配置
          order: 1
          predicates:
            - Path=/consumer/** #匹配/consumer/**的請(qǐng)求路徑
server:
  port: 9201

創(chuàng)建一個(gè)consumer也注冊(cè)到nacos,并提供一個(gè)接口:

@RestController
public class ConsumerController {

    @Value("${server.port}")
    private String port;
    
    @RequestMapping("consumer/getDetail/{id}")
    public String getDetail(@PathVariable("id") String id) {
        return "端口號(hào):" + port + ",獲取ID為:" + id + "的商品詳情";
    }
}

啟動(dòng)consumer和gateway兩個(gè)項(xiàng)目,然后打開nacos控制臺(tái),可以看到兩個(gè)服務(wù)。

服務(wù)網(wǎng)關(guān)Gateway怎么玩?

 

連續(xù)請(qǐng)求地址http://localhost:9201/consumer/getDetail/1,可以看到實(shí)現(xiàn)了負(fù)載均衡調(diào)用服務(wù)。

服務(wù)網(wǎng)關(guān)Gateway怎么玩?

 


服務(wù)網(wǎng)關(guān)Gateway怎么玩?

 

可能有人會(huì)覺得每個(gè)服務(wù)都要配一個(gè)路由,很麻煩。有個(gè)很簡(jiǎn)單的配置可以解決這個(gè)問題:

spring:
    gateway:
      discovery:
        locator:
          enabled: true

然后啟動(dòng)服務(wù),再試一次,請(qǐng)求地址需要加上服務(wù)名,依然沒有問題!

服務(wù)網(wǎng)關(guān)Gateway怎么玩?

 

寫在最后

這篇文章主要介紹GateWay的路由轉(zhuǎn)發(fā)功能,并且整合了注冊(cè)中心。權(quán)限控制可以用過濾器實(shí)現(xiàn),由于篇幅有點(diǎn)長(zhǎng),過濾器放到下一篇文章了,感謝大家的閱讀。

覺得有用就點(diǎn)個(gè)贊吧,你的點(diǎn)贊是我創(chuàng)作的最大動(dòng)力~

我是一個(gè)努力讓大家記住的程序員。我們下期再見!!!

分享到:
標(biāo)簽:Gateway
用戶無頭像

網(wǎng)友整理

注冊(cè)時(shí)間:

網(wǎng)站:5 個(gè)   小程序:0 個(gè)  文章:12 篇

  • 51998

    網(wǎng)站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會(huì)員

趕快注冊(cè)賬號(hào),推廣您的網(wǎng)站吧!
最新入駐小程序

數(shù)獨(dú)大挑戰(zhàn)2018-06-03

數(shù)獨(dú)一種數(shù)學(xué)游戲,玩家需要根據(jù)9

答題星2018-06-03

您可以通過答題星輕松地創(chuàng)建試卷

全階人生考試2018-06-03

各種考試題,題庫(kù),初中,高中,大學(xué)四六

運(yùn)動(dòng)步數(shù)有氧達(dá)人2018-06-03

記錄運(yùn)動(dòng)步數(shù),積累氧氣值。還可偷

每日養(yǎng)生app2018-06-03

每日養(yǎng)生,天天健康

體育訓(xùn)練成績(jī)?cè)u(píng)定2018-06-03

通用課目體育訓(xùn)練成績(jī)?cè)u(píng)定