之前已經介紹了
Gateway
的十種路由斷言工廠,因為部落客之前看的官方文檔是舊版本(相較于部落客使用的架構版本
2.2.6.RELEASE
),該文檔隻介紹了十種路由斷言工廠。
- Spring Cloud Alibaba:Gateway網關 & 路由斷言工廠
部落客重新看了
2.2.9.RELEASE
版本的官方文檔,新增了
Weight
路由斷言工廠,更新還是很快的,想閱讀官方文檔可以如下圖所示擷取相關版本的
Gateway
文檔。
接下來部落客給大家示範一下它的使用方式,基于配置檔案和基于
Java DSL
這兩種方式,然後使用
Postman
對網關進行批量請求,看效果是否符合預期。
搭建工程
一個父
module
和兩個子
module
(
server module
提供服務,
gateway module
實作網關)。
父
module
的
pom.xml
:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.kaven</groupId>
<artifactId>alibaba</artifactId>
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>
<description>Spring Cloud Alibaba</description>
<modules>
<module>gateway</module>
<module>server</module>
</modules>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<spring-cloud-version>Hoxton.SR9</spring-cloud-version>
<spring-cloud-alibaba-version>2.2.6.RELEASE</spring-cloud-alibaba-version>
</properties>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.2.RELEASE</version>
</parent>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud-version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${spring-cloud-alibaba-version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
</project>
server module
pom.xml
:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>com.kaven</groupId>
<artifactId>alibaba</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>server</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
</project>
application.yml
:
server:
port: 8085
接口定義:
package com.kaven.alibaba.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.concurrent.atomic.AtomicInteger;
@RestController
public class MessageController {
private static final AtomicInteger MESSAGE_COUNT = new AtomicInteger(0);
private static final AtomicInteger NEW_MESSAGE_COUNT = new AtomicInteger(0);
@GetMapping("/message")
public Integer getMessage() {
int count = MESSAGE_COUNT.incrementAndGet();
System.out.println("message: " + count);
return count;
}
@GetMapping("/new/message")
public Integer getMessageNew() {
int count = NEW_MESSAGE_COUNT.incrementAndGet();
System.out.println("new message: " + count);
return count;
}
}
啟動類:
package com.kaven.alibaba;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class);
}
}
gateway module
pom.xml
:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<groupId>com.kaven</groupId>
<artifactId>alibaba</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>gateway</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
</dependencies>
</project>
啟動類:
package com.kaven.alibaba;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class);
}
}
基于配置檔案
gateway module
的
application.yml
:
server:
port: 8086
spring:
cloud:
gateway:
routes:
- id: server
uri: http://localhost:8085
predicates:
- Path=/message
- Weight=group1, 75
- id: new_server
uri: http://localhost:8085
predicates:
- Path=/message
- Weight=group1, 25
filters:
- PrefixPath=/new
Weight
路由斷言工廠接受兩個參數:
group
和
weight
(
int
類型),權重是按組計算的(
group
參數需要相同)。如果請求網關的
/message
路徑,會有
75%
的機率被路由到
http://localhost:8085/message
,
25%
的機率被路由到
http://localhost:8085/new/message
(
PrefixPath
是一種路由過濾器,它會将指定的路徑以字首的形式加在請求路徑上,是以請求
/message
路徑,會被路由到
/new/message
路徑)。
- Spring Cloud Alibaba:Gateway之路由過濾器工廠(一)
可見,這種配置可用于有新版本的服務,但不确定新版本服務是否存在問題,就可以将小部分流量導入新版本服務中,進行線上測試,用較小的代價試錯,即使出現了嚴重的錯誤,系統總體的損失也是可承受的,大家可以去了解一下金絲雀釋出。
啟動兩個應用,使用
Postman
對網關發送批量請求,可以根據如下圖所示進行操作。
運作
Collection
。
輸入運作
Collection
的配置(請求次數與請求間歇)。
服務端的輸出如下圖所示:
服務端的兩個接口分别被請求了
757
次和
243
次,還是符合預期的。
基于Java DSL
修改
gateway module
的
application.yml
(删除網關的路由配置):
server:
port: 8086
在
gateway module
中增加兩個
bean
,即以
Java DSL
的形式定義兩個路由的處理流程。
@Bean
public RouteLocator routes1(RouteLocatorBuilder builder) {
String uri = "http://127.0.0.1:8085";
return builder.routes()
.route("server", r -> r.path("/message")
.and().weight("group1", 75)
.uri(uri))
.build();
}
@Bean
public RouteLocator routes2(RouteLocatorBuilder builder) {
String uri = "http://127.0.0.1:8085";
return builder.routes()
.route("new_server", r -> r.path("/message")
.and().weight("group1", 25)
.filters(f -> f.prefixPath("/new"))
.uri(uri))
.build();
}
上面代碼的配置和之前的配置檔案是一樣的,重新啟動兩個應用,再用
Postman
給網關發送批量請求。