我目前正在使用 SCG 访问我的服务器,
没有服务发现,我直接获取主机名和端口
我的路线豆:
@Bean
public RouteLocator gateWayRouteLocator(RouteLocatorBuilder builder) {
return builder.routes()
.route(p -> p.header(INSTANCE_TYPE, athenaProperties.getData().getPath())
.filters(f -> f.filter(dataFilter))
.uri(NO_OP))
//more routing
.build();
}
我正在使用动态过滤器来修改代码中的 URL
@Component
public class DataFilter implements GatewayFilter, Ordered {
public DataFilter(AthenaProperties athenaProperties) {
this.athenaProperties = athenaProperties;
}
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest request = exchange.getRequest();
String host = getHost(request);
Integer port = athenaProperties.getData().getPort();
exchange.getAttributes().put(ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR,
createUri(exchange.getRequest().getURI(), host, port));
return chain.filter(exchange);
}
//additional methods
}
但在某些情况下,我想在所有可能getHost
返回的主机之间进行轮询(通常我使用请求标头来查找主机),
所以对于那些情况,我createUri
以 的形式返回lb://lbid1...
,但我似乎找不到如何将 lb 链接到服务器列表
我的问题是如何在配置文件中使用 SCLB 来完成我需要添加什么?这样 lb 就会知道它应该在它们之间循环的服务器列表?
我找到的最接近的是以下答案,但它使用的是功能区而不是 SCLB
任何帮助将不胜感激
更新
我找到了解决方案
在跨服务器实例的负载平衡下
首先,注册一个 ServiceInstanceListSupplier bean
@Bean
@Primary
public ServiceInstanceListSupplier serviceInstanceListSupplier() {
return new CustomServiceInstanceListSupplier("lbid1", athenaProperties.getEngine());
}
CustomServiceInstanceListSupplier
服务器返回列表中的第二个
class CustomServiceInstanceListSupplier implements ServiceInstanceListSupplier {
private final String serviceId;
private final ServersData serversData;
public CustomServiceInstanceListSupplier(String serviceId, ServersData serversData) {
this.serviceId = serviceId;
this.serversData = serversData;
}
@Override
public String getServiceId() {
return serviceId;
}
@Override
public Flux<List<ServiceInstance>> get() {
return Flux.just(serversData.getHosts().entrySet().stream()
.map(this::createDefaultServiceInstance).collect(Collectors.toList()));
}
private ServiceInstance createDefaultServiceInstance(Map.Entry<String, String> assetToHostEntry) {
return new DefaultServiceInstance(assetToHostEntry.getKey(), serviceId, assetToHostEntry.getValue(), serversData.getPort(), true);
}
}
但是现在我有另一个问题,我如何
ServiceInstanceListSupplier
在 SCG 中定义几个(因为它只有 1 serviceId
)?
ServiceInstanceListSupplier
是一个bean,因此我只能创建一个。
例如,我想创建以下 2 磅:
"lbid1": <list of servers>
"lbid2": <other list of servers>
有人在 github 上问了同样的问题:question
但我没有看到任何动态答案(答案是使用配置spring.cloud.discovery.client.simple.instances.lbid1[i]
),虽然它确实有效,但我正在寻找使用代码的动态 lb 配置。
我该怎么做?