1. 程式人生 > 其它 >聊聊Spring Cloud Gateway閘道器路由

聊聊Spring Cloud Gateway閘道器路由

簡介

Spring Cloud Gateway是Spring Cloud官方推出的第二代閘道器框架,取代Zuul閘道器。閘道器作為流量的,在微服務系統中有著非常作用。
閘道器常見的功能有

  • 協議轉換,路由轉發
  • 流量聚合,對流量進行監控,日誌輸出
  • 可以在閘道器層做許可權的判斷
  • 限流,作為整個系統的前端工程,對流量進行控制
  • 作為系統的前端邊界,外部流量只能通過閘道器才能訪問系統
  • 快取

如上圖所示,客戶端向Spring Cloud Gateway發出請求。 如果Gateway Handler Mapping確定請求與路由匹配(這個時候就用到predicate),則將其傳送到Gateway web handler處理。 Gateway web handler處理請求時會經過一系列的過濾器鏈。 過濾器鏈被虛線劃分的原因是過濾器鏈可以在傳送代理請求之前或之後執行過濾邏輯。 先執行所有“pre”過濾器邏輯,然後進行代理請求。 在發出代理請求之後,收到代理服務的響應之後執行“post”過濾器邏輯。這跟zuul的處理過程很類似。在執行所有“pre”過濾器邏輯時,往往進行了鑑權、限流、日誌輸出等功能,以及請求頭的更改、協議的轉換;轉發之後收到響應之後,會執行所有“post”過濾器的邏輯,在這裡可以響應資料進行了修改,比如響應頭、協議的轉換等。

增新一個專案 分別是服務提供方provider,消費方comsumer,註冊中心eureka,閘道器gateway

provider

@RequestMapping("/hello")
@RestController
public class HelloController {
    @GetMapping("")
    public String hello(@RequestParam String name) {
        return "Hello, " + name + "!";
    }
}

comsumer

使用Feign呼叫

@CommonsLog
@RequestMapping("/hello")
@RestController
public class HelloController {

    @Autowired
    HelloFeignService helloRemote;

    @GetMapping("/{name}")
    public String index(@PathVariable("name") String name)  {
        log.info("the name is " + name);
        return helloRemote.hello(name) + "\n" + new Date().toString();
    }
    
}

增加 Hystrix 斷路器

@FeignClient(name = "producer", fallback = HelloFeignProviderHystrix.class)
public interface HelloFeignService {

    /**
     * @param name
     * @return
     */
    @GetMapping("/hello/")
    String hello(@RequestParam(value = "name") String name);

}

gateway

Spring Cloud gateway內建了很多校驗條件謂語(predicate)來實現路由功能。
有兩種方式配置,一種是配置檔案application的方式,一種是程式碼配置

a.application配置:

spring:
  application:
    name: sc-gateway-server
  cloud:
    gateway:
      discovery:
        locator:
          # 是否可以通過其他服務的serviceId來轉發到具體的服務例項。預設為false
          # 為true,自動建立路由,路由訪問方式:http://Gateway_HOST:Gateway_PORT/大寫的serviceId/**,其中微服務應用名預設大寫訪問
          enabled: true
      routes:
        - id: host_route
          uri: http://httpbin.org:80/get
          predicates:
            - Host=**.csdn.** # 請求域名攜帶csdn的,則轉發
        - id: query_route
          uri: http://httpbin.org:80/get
          predicates:
            - Query=username, zzz* # 請求引數含有username,且值滿足zzz開頭的,則轉發(對值的匹配可以省略)
        - id: header_route
          uri: http://httpbin.org:80/get
          predicates:
            - Header=request, \d+ # 如果請求頭含有request,且為數字,則轉發

b.程式碼配置

gateway也提供了程式碼的方式配置,比如我們註釋掉上面的application配置,然後建一個配置類

@Configuration
public class GateWayConfig {

  @Bean
  public RouteLocator routeLocator(RouteLocatorBuilder builder) {
    return builder.routes()
            .route(r -> r.path("/fluent/**")
                    .uri("http://httpbin.org:80/get"))
            .build();

  }

}

在上面的程式碼中,我們使用了一個router,該router使用host去斷言請求是否進入該路由,當請求的host有“/fluent/**”,都會進入該router,重定向到了“http://httpbin.org:80/get”。

Spring Cloud Gateway內建了許多Predict,這些Predict的原始碼在org.springframework.cloud.gateway.handler.predicate包中。

列舉各種Predicate如下圖:

啟動專案

輸入URL 可以看到轉到了 comsumer 的地址返回了provider的內容

專案地址:https://github.com/codeyuyu/SpringCloudTc.git

作者:codeyuyu
連結:http://www.imooc.com/article/284048