首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Spring Cloud Gateway -为每条路由设置不同的代理

Spring Cloud Gateway -为每条路由设置不同的代理
EN

Stack Overflow用户
提问于 2021-07-14 21:12:24
回答 2查看 213关注 0票数 0

我们是否可以为每条路由配置代理。

传入请求A ->路由A匹配->仅转发到目标系统传入请求B ->路由B匹配目标系统调用的->集代理使用代理转发到目标系统

如果我使用使用spring云网关的set proxy,它将应用于所有路由

spring.cloud.gateway.httpclient.proxy.host= spring.cloud.gateway.httpclient.proxy.port=

你有任何想法/链接/代码片段如何解决这个问题吗?欢迎任何提示。

EN

回答 2

Stack Overflow用户

发布于 2021-07-15 15:11:14

这对你有帮助吗?

在我的服务中,每个客户端都有自己的API服务器。因此,OriginMappingFilter根据clientId分配不同的端点。

例如,在认证之后,

如果clientId报头与client1匹配,

连接到http://client1.com/shops/every-resource的是http://gateway.com/shops/every-resource

如果clientId报头与client2匹配,

连接到http://client2.com/shops/every-resource的是http://gateway.com/shops/every-resource

代码语言:javascript
复制
@SpringBootApplication
public class GatewayApplication {

    @Value("${token.secret}")
    String tokenSecret;
    
    @Autowired
    private AuthenticationFilter authenticationfilter;
    
    @Autowired
    private OriginMappingFilter originMappingFilter;
    
    public static void main(String[] args) {
        SpringApplication.run(AutomangatewayApplication.class, args);
    }
    
    @Bean
    public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
        
        return builder.routes()
                .route(r -> r.path("/clients/*/tokens-with/*").uri("http://localhost:8081"))
                                    
                .route(r -> r.path("/shops/**").filters(f -> f.filter(authenticationfilter).filter(originMappingFilter)).uri("no://op"))
                
                .build();
    }
    
    @Bean
    public TokenUtils tokenUtils() {
        return new TokenUtils(tokenSecret);
    }
    
    @Bean
    public RestTemplate restTemplate() {
       return new RestTemplate();
    }
    
}
代码语言:javascript
复制
@Component
public class OriginMappingFilter implements GatewayFilter, Ordered {
    
    private static final String LEGACY_WEBSERVER_ORIGIN = "http://localhost:9095";
    
    @Autowired
    private RestTemplate restTemplate;

    @Override
    public int getOrder() {
        return 10000;
    }

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        try {

            ServerHttpRequest request = exchange.getRequest();
            
            String clientId = request.getHeaders().get("clientId").get(0);
            String origin = originOfClient(clientId);

            URI newURI = new URI(origin + request.getPath().pathWithinApplication().value());
            
            System.out.println("destination: " + newURI.toString());

            exchange.getAttributes().put(ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR, newURI);
            return chain.filter(exchange);
            
            
        } catch (URISyntaxException e ) {
            e.printStackTrace();
            throw new IllegalStateException("can't map client to origin",e);
        } catch (HttpServerErrorException e) {
            e.printStackTrace();
            throw new IllegalStateException("can't access to client resource",e);
        }
    }

    private String originOfClient(String clientId) {
        
        ResponseEntity<String> response =  restTemplate.getForEntity(LEGACY_WEBSERVER_ORIGIN+"/clients/"+clientId+"/ip", String.class);
        String ip = response.getBody();
        String origin = "http://"+ip+":8082";
        
        return origin;
    }
}
票数 0
EN

Stack Overflow用户

发布于 2021-11-25 01:53:20

代码语言:javascript
复制
spring:
  cloud:
    gateway:
      routes:
        - id: route1
          metadata:
            proxy-host: proxyhost
            proxy-port: 1000
          predicates:
          - Path=...
          uri: ...

        - id: route2
          metadata:
            proxy-host: proxyhost2
            proxy-port: 1000
          predicates:
          - Path=...
          uri: ...

kotlin

代码语言:javascript
复制
@Component
class CustomNettyRoutingFilter(
    private val httpClient: HttpClient,
    headersFiltersProvider: ObjectProvider<List<HttpHeadersFilter>>,
    properties: HttpClientProperties,
) : NettyRoutingFilter(
    httpClient,
    headersFiltersProvider,
    properties
) {
    private val httpClientCacheMap: ConcurrentMap<String, HttpClient> = ConcurrentHashMap()

    override fun getHttpClient(route: Route, exchange: ServerWebExchange): HttpClient {
        val proxyHost = route.metadata["proxy-host"] as? String
        val proxyPort = route.metadata["proxy-port"] as? Int
        return httpClientCacheMap.getOrPut(route.id) {
            when {
                proxyHost != null && proxyPort != null -> {
                    httpClient.proxy { proxySpec ->
                        proxySpec.type(ProxyProvider.Proxy.HTTP)
                            .host(proxyHost)
                            .port(proxyPort)
                    }
                }
                else -> httpClient
            }
        }
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68378781

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档