1、动态路由的需求背景
由于 routes 配置项中的配置内容是固定的,不便于灵活处理多样化的路由信息,所以需要动态路由来实现路由的灵活配置。
2、配置信息
1、添加依赖
<!-- 添加 actuator 依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.79</version>
</dependency>
需要将之前引入的 redis-reactive 注释掉
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis-reactive</artifactId>
</dependency>
2、添加配置
# 匹配所有端点
management:
endpoints:
web:
exposure:
include: "*"
spring:
redis:
host: 192.168.106.137
port: 63789
3、添加自定义的RouteDefinitionRepository
通过 Redis 来存储路由信息:
import com.alibaba.fastjson.JSON;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.route.RouteDefinition;
import org.springframework.cloud.gateway.route.RouteDefinitionRepository;
import org.springframework.data.redis.core.RedisTemplate;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import java.util.ArrayList;
import java.util.List;
@Component
public class RedisRouteDefinitionRepository implements RouteDefinitionRepository {
private static final String GATEWAY_ROUTE = "gateway_dynamic_route";
@Autowired
private RedisTemplate redisTemplate;
@Override
public Flux<RouteDefinition> getRouteDefinitions() {
List<RouteDefinition> routeDefinitionList = new ArrayList<>();
redisTemplate.opsForHash().values(GATEWAY_ROUTE).stream().forEach(route -> {
routeDefinitionList.add(JSON.parseObject(route.toString(), RouteDefinition.class));
});
return Flux.fromIterable(routeDefinitionList);
}
@Override
public Mono<Void> save(Mono<RouteDefinition> route) {
return route.flatMap(routeDefinition -> {
redisTemplate.opsForHash().put(GATEWAY_ROUTE, routeDefinition.getId(), JSON.toJSONString(routeDefinition));
return Mono.empty();
});
}
@Override
public Mono<Void> delete(Mono<String> routeId) {
return routeId.flatMap(id->{
if(redisTemplate.opsForHash().hasKey(GATEWAY_ROUTE, id)){
redisTemplate.opsForHash().delete(GATEWAY_ROUTE, id);
return Mono.empty();
}else {
return Mono.defer(() -> Mono.error(new Exception("routeDefinition not found:" + routeId)));
}
});
}
}
4、添加 route 信息
http://localhost:8900/actuator/gateway/routes/baidu_route
{
"uri": "https://www.baidu.com",
"predicate": [{
"name":"Path",
"args":{
"pattern": "/baidu/**"
}
}],
"filters": [{
"name": "StripPrefix",
"value": 1
}],
"order": 0
}
查看 Redis 中的信息
说明自定义的 route 信息已写入到 Redis 中。
5、刷新路由信息
Post 请求刷新接口 http://localhost:8900/actuator/gateway/refresh
Get 请求接口 http://localhost:8900/actuator/gateway/routes
,可以看到刚刚添加的路由信息
6、通过新加的路由访问
浏览器访问:http://localhost:8900/baidu/s