springcloud中gateway的實際應用


之前我一直用的是Zuul網關,用過gateway以后感覺比Zuul功能還是強大很多。

Spring Cloud Gateway是基於Spring5.0,Spring Boot2.0和Project Reactor等技術開發的,用來為微服務架構提供一種簡單有效統一的API路由管理方式。

相比Zuul,GateWay不僅僅提供統一的路由方式,還提供了例如:安全,限流,監控/指標,重試機制,熔斷回調,過濾等功能,這些都是可配置的。

原理什么的就不多說了,可以看下官方文檔

首先添加Maven依賴

<!-- gateway -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!-- 熔斷器 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
        </dependency>
        <!-- 限流 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis-reactive</artifactId>
        </dependency>
        <!-- eureka-client -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <!--暴露各種指標-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <!-- zipkin-client -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-zipkin</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>

yml配置詳情如下:

#連接Eureka配置
eureka:
  client:
    serviceUrl:
      defaultZone: http://peer1:8761/eureka/,http://peer2:8762/eureka/
server:
  port: 8770
spring:
  main:
    banner-mode:
  application:
    name: dkjk-gateway-service #應用程序名
#  redis:
#    host: localhost
#    port: 6379
  cloud:
    gateway:
      routes:
      - id: my-service-one   #我們自定義的路由 ID,保持唯一
        #目標服務地址,也可以是http://localhost:8182  PS: 當所用協議為lb時,
        #gateway將使用 LoadBalancerClient把服務名通過eureka解析為實際的主機和端口,並進行負載均衡。
        uri: lb://Eureka中的服務名稱1  
#        order: 0
        #路由規則,Predicate 接受一個輸入參數,返回一個布爾值結果。
#該接口包含多種默認方法來將 Predicate 組合成其他復雜的邏輯(比如:與,或,非)。 predicates: # PS:以下規則可以組合使用 #接收一個匹配路徑的參數來判斷是否走路由。當訪問地址 http:
//localhost:8770/spring-cloud時
#會自動轉發到地址:
http://www.ityouknow.com/spring-cloud - Path=/em/** #可以通過是 POST、GET、PUT、DELETE 等不同的請求方式來進行路由。可以用postman測試,如果符合規則進行路由,否則不進行路由(報404) # - Method=GET #請求時間在 2019年11月04日6點6分6秒之前可以進行路由,在這時間之后停止路由(報404) # - Before=2019-11-04T06:06:06+08:00[Asia/Shanghai] #請求時間在 2019年11月04日16點31分00秒之前不可以進行路由(報404),在這時間之后可以進行路由 # - After=2019-11-05T16:31:00+08:00[Asia/Shanghai] #在這個時間段內可以匹配到此路由,超過這個時間段范圍則不會進行匹配(報404)。可以用在限時搶購的一些場景中。 # - Between=2019-11-04T06:06:06+08:00[Asia/Shanghai], 2019-11-06T06:06:06+08:00[Asia/Shanghai] #兩個參數:1.請求頭中屬性名稱2.正則表達式(也可以是固定值),可以用postman測試,如果符合規則進行路由,否則不進行路由(報404) # - Header=apikey, \d+ #兩個參數:1.Cookie name 值2.正則表達式(也可以是固定值),可以用postman測試,如果符合規則進行路由,否則不進行路由(報404) # - Cookie=apikey, \d+ #只要請求中包含apikey屬性的參數即可匹配路由。如果符合規則進行路由,否則不進行路由(報404) # - Query=apikey # - Host=**.ityouknow.com #通過設置某個 ip 區間號段的請求才會路由,即符合這個網段的可以訪問,例如:http://192.168.1.131:8770/ # - RemoteAddr=192.168.1.1/24 # 過濾規則 filters: #截取路徑的個數 - StripPrefix=1 #在URL路徑前面添加一部分的前綴,例如:配置 - Path=/** , 請求路徑為localhost:8770/idcard,
#會轉變為localhost:8770/identity/idcard # - PrefixPath=/identity - name: Hystrix args: name: fallbackcmd fallbackUri: forward:/fallback #如果服務調用異常會回調自定義的/fallback請求 - id: credit-service uri: lb://Eureka中的服務名稱2 predicates: - Path=/credit/** filters: - StripPrefix=1 - name: Hystrix args: name: fallbackcmd fallbackUri: forward:/fallback #如果服務調用異常會回調自定義的/fallback請求 - name: RequestRateLimiter #名稱必須是 RequestRateLimiter args: redis-rate-limiter.replenishRate: 2 #允許用戶每秒處理多少個請求 redis-rate-limiter.burstCapacity: 3 #令牌桶的容量,允許在一秒鍾內完成的最大請求數 key-resolver: "#{@userKeyResolver}" #使用 SpEL 按名稱引用 bean - name: Retry args: #重試次數,默認值是3次 retries: 3 series: - SERVER_ERROR #滿足的status statuses: - BAD_GATEWAY methods: - GET - POST exceptions: - java.io.IOException - java.util.concurrent.TimeoutException - java.lang.RuntimeException #是否與服務注冊於發現組件進行結合,通過 serviceId 轉發到具體的服務實例。
#默認為 false,設為 true 便開啟通過服務中心的自動根據 serviceId 創建路由的功能。 #這個不用配置也可以 # discovery: # locator: # enabled: true # hystrix 信號量隔離,30秒后自動超時 hystrix: command: default: execution: isolation: thread: timeoutInMilliseconds: 30000 logging: level: org.springframework.cloud.gateway: debug

 

以上配置啟動類中用到的注解

package com.dkjk.gateway;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;

@SpringBootApplication
@EnableEurekaClient
@EnableCircuitBreaker
public class DkjkGatewayServiceApplication {

    public static void main(String[] args) {
        SpringApplication.run(DkjkGatewayServiceApplication.class, args);
    }

}

限流配置代碼

package com.dkjk.gateway.config;

import org.springframework.cloud.gateway.filter.ratelimit.KeyResolver;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import reactor.core.publisher.Mono;

/**
 * @Description:
 * @Author: qjc
 * @Date: 2019/11/6
 */
@Configuration
public class Config {
    @Bean
    KeyResolver userKeyResolver() {
//        return exchange -> Mono.just(exchange.getRequest().getQueryParams().getFirst("user"));//根據請求參數中的 user 字段來限流
        return exchange -> Mono.just(exchange.getRequest().getRemoteAddress().getHostName());//根據請求 IP 地址來限流
    }
}

熔斷回調代碼:

package com.dkjk.gateway.controller;

import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @Description:
 * @Author: qjc
 * @Date: 2019/11/6
 */
@RestController
@Slf4j
public class FallbackController {

    @GetMapping("/fallback")
    public String fallback() {
        log.info("回調了");
        return "Hello World!\nfrom gateway";
    }

}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM