使用Spring Cloud Gateway 替換 zuul, 並代理註冊在 Nacos 中的微服務
Spring Cloud Gateway是Spring Cloud官方推出的第二代閘道器框架,取代Zuul閘道器.閘道器常見的功能有路由轉發、許可權校驗、限流控制等作用.
Nacos 是阿里開源的一款 配製和註冊中心,目前已經適配了spring cloud(ofollow,noindex">Spring Cloud Alibaba ), 與 dubbo 的適配也在進行中.
之前使用 zuul 的時候, 發現預設情況下 RequestHeaders 中的 Authorization 引數被zuul過濾了, 導致被代理的服務拿不到token,需要經過配製才能傳遞到服務中. 經過測試,Spring Cloud Gateway 在預設情況下沒有此問題.
閱讀本篇,需要你提前瞭解並做好:
- spring boot 和 spring cloud 相信因為標題進來的你已經瞭解並應用了
- 下載安裝並啟動 Nacos,nacos 快速入門
- 將服務註冊中心替換為 Nacos, 可以參考Nacos與Spring Cloud快速入門
- spring boot 使用 2.0.x, 不要使用 2.1.x, 因為 Nacos 的相關庫還沒有適配 2.1.x ,會有問題(比如服務註冊不上)
- spring cloud 使用 Finchley.SR1 或者Finchley.SR2
pom 引入:
~~~ <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-gateway</artifactId> </dependency> <!-- nacos 的服務註冊與發現 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <!-- hystrix 熔斷器 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-hystrix</artifactId> </dependency> ~~~
application.yml
server: port: 80 spring: application: name: gateway-server cloud: nacos: discovery: serverAddr: 127.0.0.1:8848
啟動器和簡單路由+Hystrix熔斷降級
import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.cloud.gateway.route.RouteLocator; import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder; import org.springframework.context.annotation.Bean; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import reactor.core.publisher.Mono; @SpringBootApplication @EnableDiscoveryClient// 啟用服務註冊和發現 @RestController// 提供一個簡單的降級頁面 public class GatewayServerApplication { public static void main(String[] args) { SpringApplication.run(GatewayServerApplication.class); } /** * @Title: fallback * @Description: 一個簡單的降級頁面 * @return */ @RequestMapping("/fallback") public Mono<String> fallback() { // Mono是一個Reactive stream,對外輸出一個“fallback”字串。 return Mono.just("fallback"); } @Bean public RouteLocator customRouteLocator(RouteLocatorBuilder builder) { return builder.routes() // 配製一個路由,把 http://閘道器地址:閘道器埠/demo/ 下的請求路由到 demo-service 微服務中 .route(p -> p .path("/demo/**") .filters(f -> f .hystrix(config -> config// 對path()指定的請求使用熔斷器 .setName("mycmd")// 熔斷器的名字 .setFallbackUri("forward:/fallback")))// 熔斷到 /fallback, 就是上面配製的那個 .uri("lb://demo-service"))// 將請求路由到指定目標, lb開頭是註冊中心中的服務, http/https 開頭你懂的 .build(); } }
到這裡就結束了,可以愉快的啟動閘道器並測試了
【注意】:
這裡說一下 Spring Cloud Gateway 與 zuul 的代理的地址有點不一樣
zuul 中, 例如我們配製的是 把 /demo/** 路由到http://服務/, 則閘道器的請求地址: http://閘道器/demo/xx/abc.do 實際請求的服務地址為: http://服務/xx/abc.do , zuul自動把 /demo 去掉了.而 Spring Cloud Gateway 不是這樣:在Spring Cloud Gateway中,上面的實際請求的服務地址為: http://服務/demo/xx/abc.do ,Spring Cloud Gateway不會把 /demo 去掉,與請求的地址一樣