Spring cloud 如何使用URL动态路由传入请求->;负责的后端服务映射服务?
我是SpringCloudGateway的新手,如果我按照预期的方式解决了问题,我无法回答这个问题。我希望有人能给我指出正确的方向,给出建议或提供一些示例代码 要求: my spring cloud gateway服务的传入请求应转发到正确的后端服务(有X个这样的后端服务,每个后端服务负责一个特定任务)。 请求本身没有足够的信息来决定路由到哪个后端服务 存在将任意URL映射到负责的后端服务名称的其他REST服务。响应格式是一些小型JSON,包含要转发到的后端服务的名称 使用SpringCloudGateway实现此功能的最简单/最佳/最智能/预期解决方案是什么 我尝试实现一个Spring cloud 如何使用URL动态路由传入请求->;负责的后端服务映射服务?,spring-cloud,spring-cloud-gateway,Spring Cloud,Spring Cloud Gateway,我是SpringCloudGateway的新手,如果我按照预期的方式解决了问题,我无法回答这个问题。我希望有人能给我指出正确的方向,给出建议或提供一些示例代码 要求: my spring cloud gateway服务的传入请求应转发到正确的后端服务(有X个这样的后端服务,每个后端服务负责一个特定任务)。 请求本身没有足够的信息来决定路由到哪个后端服务 存在将任意URL映射到负责的后端服务名称的其他REST服务。响应格式是一些小型JSON,包含要转发到的后端服务的名称 使用SpringCloud
GatewayFilter
,它首先调用映射服务,并根据交换的结果集GATEWAY\u REQUEST\u URL\u ATTR
。
这样行。但我还有其他问题
.uri(“not://needed”)
路线设置中的零件@springboot应用程序
@RestController
公共类应用程序{
公共静态void main(字符串[]args){
SpringApplication.run(Application.class,args);
}
@豆子
公共RouteLocator myRoutes(RouteLocatorBuilder生成器){
返回生成器.routes().route(r->r
.alwaysTrue()
.filters(f->f.filter(新的CustomRequestFilter()))
.uri(“not://needed)//如何省略?
.build();
}
公共静态类CustomRequestFilter实现GatewayFilter,已订购{
@凌驾
public int getOrder(){
返回10000;//为什么订单>9999?(低于10000不起作用)
}
@凌驾
公共Mono筛选器(服务器WebExchange exchange、网关筛选器链){
返回getBackendServiceMappingResult(exchange.getRequest().getURI().toString())//异步调用REST服务映射URL->后端服务名称
.flatMap(映射结果->{
URI URI=mapServiceNameToBackendService(mappingResult.getServiceName());
exchange.getAttributes().put(ServerWebExchangeUtils.GATEWAY\u请求\u URL\u属性,uri);
返回链。过滤器(交换);
});
}
私有URI mapServiceNameToBackendService(字符串serviceName){
试一试{
交换机(serviceName){
案例“serviceA”:返回新URI(“http://httpbin.org:80/get");
案例“serviceB”:返回新URI(“https://someotherhost:443/");
}
}捕获(URISyntaxException e){
//忽略
}
返回null;
}
}
静态类映射结果{
字符串serviceName;
公共字符串getServiceName(){
返回serviceName;
}
}
静态Mono getBackendServiceMappingResult(字符串uri){
WebClient客户端=WebClient.create(“http://localhost:8080");
返回client.get();
}
}
是否有更好的方法(使用SpringCloudGateway)来解决此需求?URI是必需的。我通常使用
no://op
,因为它很短。排序很重要,因为还有其他过滤器可能会影响结果。感谢您的回答@Spencergib。你能提供更多关于过滤器链的信息吗?我只设置了一个单独的过滤器,不管排序是什么,它都应该首先启动。如果我将order设置为Ordered.HIGHEST\u priority或Ordered.LOWEST\u priority,则会产生相同的错误结果。响应只是一个空的body 200er,而不是请求服务的响应。我真的不理解这种行为。此外,我很想知道实现是否与SpringCloudGateway的主要贡献者的想法一致。他们是否以不同的方式解决了需求?我写了gateway的大部分内容。我有一个与此类似的用例,但是我需要进行两个非阻塞调用,第一个之后的第二个,将其拆分为不同的过滤器是最佳做法吗?
@SpringBootApplication
@RestController
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@Bean
public RouteLocator myRoutes(RouteLocatorBuilder builder) {
return builder.routes().route(r -> r
.alwaysTrue()
.filters(f -> f.filter(new CustomRequestFilter()))
.uri("not://needed")) // how to omit ?
.build();
}
public static class CustomRequestFilter implements GatewayFilter, Ordered {
@Override
public int getOrder() {
return 10000; // why order > 9999 ? (below 10000 does not work)
}
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
return getBackendServiceMappingResult(exchange.getRequest().getURI().toString()) //async call to REST service mapping URL->backend service name
.flatMap(mappingResult -> {
URI uri = mapServiceNameToBackendService(mappingResult.getServiceName());
exchange.getAttributes().put(ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR, uri);
return chain.filter(exchange);
});
}
private URI mapServiceNameToBackendService(String serviceName) {
try {
switch (serviceName) {
case "serviceA": return new URI("http://httpbin.org:80/get");
case "serviceB": return new URI("https://someotherhost:443/");
}
} catch (URISyntaxException e) {
//ignore
}
return null;
}
}
static class MappingResult {
String serviceName;
public String getServiceName() {
return serviceName;
}
}
static Mono<MappingResult> getBackendServiceMappingResult(String uri) {
WebClient client = WebClient.create("http://localhost:8080");
return client.get().uri(uriBuilder -> uriBuilder.path("/mapping").queryParam("uri", uri).build()).retrieve().bodyToMono(MappingResult.class);
}
}