spring-cloud-gateway动态路由
实现了spring-cloud的动态路由,一个真正可用的网关就成型了,从应用的角度来看,这就是spring-cloud的最后的一课了
动态路由其实不难实现 RouteDefinitionRepository 接口即可。
配置
代码语言:txt复制spring:
application:
name: zuul-gateway-dynamic
cloud:
gateway:
discovery:
locator:
enabled: true
lower-case-service-id: true
consul:
discovery:
service-name: zuul-gateway-dynamic
health-check-path: /health/status
prefer-ip-address: true
ip-address: 127.0.0.1
host: localhost
port: 8500
redis:
database: 0
host: 127.0.0.1
port: 6379
connect-timeout: 100ms
timeout: 500ms
jedis:
pool:
max-active: 200
min-idle: 10
max-idle: 20
max-wait: 10000ms
server:
port: 10013
address: 127.0.0.1
debug: true
management:
endpoint:
gateway:
enabled: true
endpoints:
web:
exposure:
include: "*"
logging:
config: classpath:logback-spring.xml
代码
代码语言:txt复制package cn.beckbi.route;
import com.alibaba.fastjson2.JSON;
import lombok.extern.slf4j.Slf4j;
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 org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import java.util.ArrayList;
import java.util.List;
/**
* @program: spring-cloud
* @description:
* @author: bikang
* @create: 2022-08-22 07:47
*/
@Slf4j
@Component
public class RedisRouteDefinitionRepository implements RouteDefinitionRepository {
private static final String GATEWAY_ROUTE = "SPRING_CLOUD_GATEWAY_ROUTE_LIST";
@Autowired
private StringRedisTemplate stringRedisTemplate;
@Override
public Flux<RouteDefinition> getRouteDefinitions() {
List<RouteDefinition> routeDefinitionList = new ArrayList<>();
stringRedisTemplate.opsForHash().values(GATEWAY_ROUTE).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 -> {
stringRedisTemplate.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(stringRedisTemplate.opsForHash().hasKey(GATEWAY_ROUTE, id)){
stringRedisTemplate.opsForHash().delete(GATEWAY_ROUTE, id);
return Mono.empty();
}else {
return Mono.defer(() -> Mono.error(new Exception("routeDefinition not found:" routeId)));
}
});
}
}
动态增加路由
代码语言:txt复制curl --location --request POST 'http://localhost:10013/actuator/gateway/routes/test1'
--header 'Content-Type: application/json'
--data-raw '{"uri":"http://www.example.com/","predicates":[{"name":"Path","args":{"pattern":"/abc/**"}}],"filters":[{"name":"StripPrefix","args":{"value":1}}],"order":0}'