Spring Cloud Gateway是Spring Cloud官方推出的第二代網(wǎng)關(guān)框架,取代Zuul網(wǎng)關(guān).網(wǎng)關(guān)常見的功能有路由轉(zhuǎn)發(fā)沽损、權(quán)限校驗纲岭、限流控制等作用.
Nacos 是阿里開源的一款 配制和注冊中心,目前已經(jīng)適配了spring cloud(Spring Cloud Alibaba), 與 dubbo 的適配也在進行中.
之前使用 zuul 的時候, 發(fā)現(xiàn)默認(rèn)情況下 RequestHeaders 中的 Authorization 參數(shù)被zuul過濾了, 導(dǎo)致被代理的服務(wù)拿不到token,需要經(jīng)過配制才能傳遞到服務(wù)中. 經(jīng)過測試,Spring Cloud Gateway 在默認(rèn)情況下沒有此問題.
閱讀本篇,需要你提前了解并做好:
- spring boot 和 spring cloud 相信因為標(biāo)題進來的你已經(jīng)了解并應(yīng)用了
- 下載安裝并啟動 Nacos, nacos 快速入門
- 將服務(wù)注冊中心替換為 Nacos, 可以參考 Nacos與Spring Cloud快速入門
- spring boot 使用 2.0.x, 不要使用 2.1.x, 因為 Nacos 的相關(guān)庫還沒有適配 2.1.x ,會有問題(比如服務(wù)注冊不上)
- spring cloud 使用 Finchley.SR1 或者 Finchley.SR2
pom 引入:
~~~
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<!-- nacos 的服務(wù)注冊與發(fā)現(xiàn) -->
<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 // 啟用服務(wù)注冊和發(fā)現(xiàn)
@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://網(wǎng)關(guān)地址:網(wǎng)關(guān)端口/demo/ 下的請求路由到 demo-service 微服務(wù)中
.route(p -> p
.path("/demo/**")
.filters(f -> f
.hystrix(config -> config // 對path()指定的請求使用熔斷器
.setName("mycmd") // 熔斷器的名字
.setFallbackUri("forward:/fallback"))) // 熔斷到 /fallback, 就是上面配制的那個
.uri("lb://demo-service")) // 將請求路由到指定目標(biāo), lb開頭是注冊中心中的服務(wù), http/https 開頭你懂的
.build();
}
}
到這里就結(jié)束了,可以愉快的啟動網(wǎng)關(guān)并測試了
【注意】:
這里說一下 Spring Cloud Gateway 與 zuul 的代理的地址有點不一樣
zuul 中, 例如我們配制的是 把 /demo/** 路由到 http://服務(wù)/, 則網(wǎng)關(guān)的請求地址: http://網(wǎng)關(guān)/demo/xx/abc.do 實際請求的服務(wù)地址為: http://服務(wù)/xx/abc.do, zuul自動把 /demo 去掉了.而 Spring Cloud Gateway 不是這樣:在Spring Cloud Gateway中,上面的實際請求的服務(wù)地址為: http://服務(wù)/demo/xx/abc.do ,Spring Cloud Gateway不會把 /demo 去掉,與請求的地址一樣