Spring Cloud Gateway 实战之二:更多路由配置方式,阿里面试 java 准备
application:
name: gateway-by-loadbalance
cloud:
nacos:
注册中心的配置
discovery:
server-addr: 127.0.0.1:8848
gateway:
routes:
id: path_route_lb
uri: lb://provider-hello
predicates:
Path=/lbtest/**
单元测试类:
package com.bolingcavalry.gateway;
import com.bolingcavalry.common.Constants;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.reactive.AutoConfigureWebTestClient;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.MediaType;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.test.web.reactive.server.WebTestClient;
import static org.junit.jupiter.api.Assertions.assertTrue;
@SpringBootTest
@ExtendWith(SpringExtension.class)
@AutoConfigureWebTestClient
public class HelloTest {
@Autowired
private WebTestClient webClient;
@Test
void testLoadBalance() {
webClient.get()
.uri("/lbtest/str")
.accept(MediaType.APPLICATION_JSON)
.exchange()
// 验证状态
.expectStatus().isOk()
// 验证结果,注意结果是字符串格式
.expectBody(String.class).consumeWith(result -> assertTrue(result.getResponseBody().contains(Constants.LB_PREFIX)));
}
}
运行单元测试,通过,可见上述配置可以通过前缀 lb:准确找到服务:
[](
)支持在 nacos 上配置
将所有配置信息写在 application.yml 中有个问题:不能远程配置,这在应用数量较多的场景就不方便了,好在 nacos 提供了远程配置的能力,应用启动后可以从 nacos 取得自己的配置信息,咱们来试试
新增名为 gateway-nacos-config 的子工程,其 pom.xml 中的依赖情况如下,请注意里面的中文注释,每指明了每一个依赖的作用:
<dependencies>
<dependency>
<groupId>com.bolingcavalry</groupId>
<artifactId>common</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
<!-
-nacos:配置中心-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
</dependencies>
本地的配置文件 bootstrap.yml,非常简单,就是 nacos 的地址和远程配置信息:
spring:
application:
name: gateway-nacos-config
cloud:
nacos:
config:
server-addr: 127.0.0.1:8848
file-extension: yml
group: DEFAULT_GROUP
接下来再 nacos 增加一个配置文件,操作如下图红框:
增加一个配置,要注意的地方如下(配置信息的文本稍后给出,便于复制):
上图中完整的配置信息如下:
server:
port: 8083
spring:
cloud:
gateway:
routes:
id: path_route_addr
predicates:
Path=/hello/**
id: path_route_lb
uri: lb://provider-hello
predicates:
Path=/lbtest/**
测试类中的两个测试方法如下所示,和前面没有任何区别:
@Test
void testHelloPredicates() {
webClient.get()
.uri("/hello/str")
.accept(MediaType.APPLICATION_JSON)
.exchange()
// 验证状态
.expectStatus().isOk()
// 验证结果,注意结果是字符串格式
.expectBody(String.class).consumeWith(result -> assertTrue(result.getResponseBody().contains(Constants.HELLO_PREFIX)));
}
@Test
void testLoadBalance() {
webClient.get()
.uri("/lbtest/str")
.accept(MediaType.APPLICATION_JSON)
.exchange()
// 验证状态
.expectStatus().isOk()
// 验证结果,注意结果是字符串格式
.expectBody(String.class).consumeWith(result -> assertTrue(result.getResponseBody().contains(Constants.LB_PREFIX)));
}
运行单元测试类,测试通过,证明从 nacos 获取配置文件成功:
[](
)写代码的方式配置
前面的几个例子,路由信息都是写在配置文件中的,其实还有一种方式:写代码配置路由,能自己写代码来配置,这灵活性就更强了
新增名为 gateway-by-code 的子工程,其 pom.xml 文件参照前面工程的即可
接下来的本例的重点,在配置类中增加一个 RouteLocator 类型的 bean,通过以下代码即可增加一个路由:
package com.bolingcavalry.gateway.cofig;
import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class RouteConfig {
@Bean
public RouteLocator customizeRoute(RouteLocatorBuilder builder) {
return builder
.routes()
.route(
// 第一个参数是路由的唯一身份
"path_route_lb",
// 第二个参数是个 lambda 实现,
// 设置了配套条件是按照请求路径匹配,以及转发地址,
// 注意 lb://表示这是个服务名,要从
r -> r.path("/lbtest/**").uri("lb://provider-hello")
)
.build();
}
}
上述代码只配置了一个路由,还有一个在配置文件中,这样就能验证代码和配置文件能不能同时生效了:
server:
#服务端口
port: 8084
spring:
application:
name: gateway-by-code
cloud:
nacos:
discovery:
nacos 服务地址
server-addr: 127.0.0.1:8848
gateway:
评论