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

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

點擊這里在線咨詢客服
新站提交
  • 網站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

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

介紹服務網關

要認識一樣東西,最好的方法是從為什么需要他開始說起。

按照現在主流使用微服務架構的特點,假設現在有A、B、C三個服務,假如這三個服務都需要做一些請求過濾和權限校驗,請問怎么實現?

  • 每個服務自己實現一遍。
  • 寫在一個公共的服務,然后讓A、B、C服務引入公共服務的Maven依賴。
  • 使用服務網關,所有客戶端請求服務網關進行請求過濾和權限校驗,然后再路由轉發到A、B、C服務。

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

所以顯而易見,使用服務網關則解決了以上的問題,其他服務不需要加入什么依賴,只需要在網關配置一些參數,然后就能路由轉發到對應的后端服務,如果需要請求過濾和權限檢驗的話,都可以在網關層實現,如果需要更新權限校驗的邏輯,只需要網關層修改就可以,其他后端服務不需要修改。

接下來再介紹一下服務網關的功能,主要有:

  • 路由轉發
  • API監控
  • 權限控制
  • 限流

所以服務網關很重要!那么接下來我們就以目前比較主流的GateWay進行學習吧。

GateWay入門

首先第一步需要創建一個作為網關的項目,這里使用的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>

我們需要使用網關轉發請求,那么首先需要有個后端服務,這里我簡單地創建了一個user項目。然后啟動user項目,寫個獲取所有用戶信息的接口:

服務網關Gateway怎么玩?

 

那么我們現在配置網關的Application.yml實現請求轉發。

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

也就是說我請求http://localhost:9201/user/getList后,9201端口是網關服務,會匹配/user/getList的路由,最終轉發到目標地址http://localhost:8080/user/getList。

服務網關Gateway怎么玩?

 

這就算是gateway網關的簡單使用了。

繼續深入

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

除此之外,gateway的另一個核心是Filter(過濾器),Filter有全局和局部兩種。那么整個gateway的流程是怎么樣的呢?請看下圖:

服務網關Gateway怎么玩?

 

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

Route Predicate 的使用

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

After Route Predicate

在指定的時間之后請求匹配該路由。

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

在指定時間之前的請求會匹配該路由。

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

在指定時間區間內的請求會匹配該路由。

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的請求會匹配該路由。

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

使用POSTMAN發送帶有Cookie里username=yehongzhi的請求。

服務網關Gateway怎么玩?

 

Header Route Predicate

帶有指定請求頭的請求會匹配該路由。

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

使用POSTMAN發送請求頭帶有X-Id的請求。

服務網關Gateway怎么玩?

 

Host Route Predicate

帶有指定Host的請求會匹配該路由。

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

使用POSTMAN發送請求頭帶有Host=www.yehongzhi.com的請求。

服務網關Gateway怎么玩?

 

Path Route Predicate

發送指定路徑的請求會匹配該路由。

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

發送指定方法的請求會匹配該路由。

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

用POSTMAN以POST方式發送請求。

服務網關Gateway怎么玩?

 

Query Route Predicate

帶指定查詢參數的請求可以匹配該路由。

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地址,發送請求。

服務網關Gateway怎么玩?

 

Weight Route Predicate

使用權重來路由相應請求,以下配置表示有80%的請求會被路由到localhost:8080,20%的請求會被路由到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

從指定的遠程地址發起的請求可以匹配該路由。

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

使用瀏覽器請求。

服務網關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發起請求,使用POST方式,uri是/user/getList,帶有Cookie,RemoteAddr。

服務網關Gateway怎么玩?

 

自定義Predicate

如果我們需要自定義Predicate,怎么玩呢?其實很簡單,看源碼,有樣學樣,需要繼承AbstractRoutePredicateFactory類。

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

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

    public static final String TOKEN_KEY = "tokenValue";

    public TokenRoutePredicateFactory() {
        //當前類的Config類,會利用反射創建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對象就是下面自定義的Config對象
        return new Predicate<ServerWebExchange>() {
            @Override
            public boolean test(ServerWebExchange exchange) {
                MultiValueMap<String, String> params = exchange.getRequest().getQueryParams();
                //獲取請求參數
                String value = params.getFirst("token");
                //請求參數和配置文件定義的token進行對比,相等則返回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;
        }
    }
}

這里需要注意的一點是類名必須是RoutePredicateFactory結尾,前面的則作為配置名。比如TokenRoutePredicateFactory的配置名則為Token,這是一個約定的配置。

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

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

然后用POSTMAN發送請求,帶上token參數,參數值為abc。

服務網關Gateway怎么玩?

 

如果token的值不正確的話,會報404。

服務網關Gateway怎么玩?

 

整合注冊中心

為什么要整合注冊中心呢?因為每個服務一般背后都不只一臺機器,而且一般使用服務名進行配置,而不是配置服務的IP地址,并且要實現負載均衡調用。

這里我就使用Nacos作為注冊中心。

引入Maven依賴:

<dependency><!-- SpringCloud nacos服務發現的依賴 -->
    <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>

啟動類加上注解,開啟注冊中心。

@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協議,consumer是服務名,不再使用IP地址配置
          order: 1
          predicates:
            - Path=/consumer/** #匹配/consumer/**的請求路徑
server:
  port: 9201

創建一個consumer也注冊到nacos,并提供一個接口:

@RestController
public class ConsumerController {

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

啟動consumer和gateway兩個項目,然后打開nacos控制臺,可以看到兩個服務。

服務網關Gateway怎么玩?

 

連續請求地址http://localhost:9201/consumer/getDetail/1,可以看到實現了負載均衡調用服務。

服務網關Gateway怎么玩?

 


服務網關Gateway怎么玩?

 

可能有人會覺得每個服務都要配一個路由,很麻煩。有個很簡單的配置可以解決這個問題:

spring:
    gateway:
      discovery:
        locator:
          enabled: true

然后啟動服務,再試一次,請求地址需要加上服務名,依然沒有問題!

服務網關Gateway怎么玩?

 

寫在最后

這篇文章主要介紹GateWay的路由轉發功能,并且整合了注冊中心。權限控制可以用過濾器實現,由于篇幅有點長,過濾器放到下一篇文章了,感謝大家的閱讀。

覺得有用就點個贊吧,你的點贊是我創作的最大動力~

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

分享到:
標簽:Gateway
用戶無頭像

網友整理

注冊時間:

網站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網站吧!
最新入駐小程序

數獨大挑戰2018-06-03

數獨一種數學游戲,玩家需要根據9

答題星2018-06-03

您可以通過答題星輕松地創建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數有氧達人2018-06-03

記錄運動步數,積累氧氣值。還可偷

每日養生app2018-06-03

每日養生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定