本節我們先創建一個 Gateway 項目,然後實現了一個最簡單的轉發功能,並進行 Eureka 路由的整合。
創建 Gateway 項目
創建一個 Spring Boot 的 Maven 項目,增加 Spring Cloud Gateway 的依賴,代碼如下所示。
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.6.RELEASE</version>
<relativePath />
</parent>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Finchley.SR2</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
</dependencies>
啓動類就按 Spring Boot 的方式即可,無須添加額外的註解。代碼如下所示。
@SpringBootApplication
public class App {
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
}
路由轉發示例
下面來實現一個最簡單的轉發功能——基於 Path 的匹配轉發功能。
Gateway 的路由配置對 yml 文件支持比較好,我們在 resources 下建一個 application.yml 的文件,內容如下:
server:
port: 2001
spring:
cloud:
gateway:
routes:
- id: path_route
uri: http://c.biancheng.net
predicates:
- Path=/spring_cloud
當你訪問 http://localhost:2001/spring_cloud 的時候就會轉發到 http://c.biancheng.net/spring_cloud。
如果我們要支持多級 Path,配置方式跟 Zuul 中一樣,在後面加上兩個*
號即可,比如:
- id: path_route2
uri: http://c.biancheng.net
predicates:
- Path=/spring_cloud/**
這樣一來,上面的配置就可以支持多級 Path,比如訪問 http://localhost:2001/spring_cloud/view/1 的時候就會轉發到 http://c.biancheng.net/spring_cloud/view/1。
整合 Eureka 路由
添加 Eureka Client 的依賴,代碼如下所示。
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
配置基於 Eureka 的路由:
- id: user-service
uri: lb://user-service
predicates:
- Path=/user-service/**
uri 以lb://
開頭(lb 代表從註冊中心獲取服務),後面接的就是你需要轉發到的服務名稱,這個服務名稱必須跟 Eureka 中的對應,否則會找不到服務,錯誤代碼如下:
org.springframework.cloud.gateway.support.NotFoundException: Unable to find instance for user-service1
整合 Eureka 的默認路由
Zuul 默認會爲所有服務都進行轉發操作,我們只需要在訪問路徑上指定要訪問的服務即可,通過這種方式就不用爲每個服務都去配置轉發規則,當新加了服務的時候,不用去配置路由規則和重啓網關。
在 Spring Cloud Gateway 中當然也有這樣的功能,通過配置即可開啓,配置如下:
spring:
cloud:
gateway:
discovery:
locator:
enabled: true
開啓之後我們就可以通過地址去訪問服務了,格式如下:
http://網關地址/服務名稱(大寫)/**
http://localhost:2001/USER-SERVICE/user/get?id=1
這個大寫的名稱還是有很大的影響,如果我們從 Zuul 升級到 Spring Cloud Gateway 的話意味着請求地址有改變,或者重新配置每個服務的路由地址,通過源碼筆者發現可以做到兼容處理,再增加一個配置即可:
spring:
cloud:
gateway:
discovery:
locator:
lowerCaseServiceId: true
配置完成之後我們就可以通過小寫的服務名稱進行訪問了,如下所示:
http://網關地址/服務名稱(小寫)/**
http://localhost:2001/user-service/user/get?id=1
注意:開啓小寫服務名稱後大寫的服務名稱就不能使用,兩者只能選其一。
配置源碼在 org.springframework.cloud.gateway.discovery.DiscoveryLocatorProperties 類中,代碼所示。
@ConfigurationProperties("spring.cloud.gateway.discovery.locator")
public class DiscoveryLocatorProperties {
/**
* 服務名稱小寫配置, 默認爲false
*
*/
private boolean lowerCaseServiceId = false;
}