之前已经介绍了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:
server module4.0.0 com.kaven alibaba pom 1.0-SNAPSHOT Spring Cloud Alibaba gateway server 8 8 Hoxton.SR9 2.2.6.RELEASE org.springframework.boot spring-boot-starter-parent 2.3.2.RELEASE org.springframework.cloud spring-cloud-dependencies ${spring-cloud-version} pom import com.alibaba.cloud spring-cloud-alibaba-dependencies ${spring-cloud-alibaba-version} pom import
pom.xml:
com.kaven alibaba 1.0-SNAPSHOT 4.0.0 server 8 8 org.springframework.boot spring-boot-starter-web
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:
com.kaven alibaba 1.0-SNAPSHOT 4.0.0 gateway 8 8 org.springframework.cloud spring-cloud-starter-gateway
启动类:
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次,还是符合预期的。
修改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给网关发送批量请求。
服务端的两个接口还是分别被请求了757次和243次,符合预期。
Gateway网关的Weight路由断言工厂就介绍到这里,如果博主有说错的地方或者大家有不同的见解,欢迎大家评论补充。



