我有一个 3 个前端应用程序和 3 个后端应用程序,假设 1 个虚拟机同时托管前端和后端应用程序,如下图所示,每个前端应用程序都使用由支持的发现客户端连接到后端动物园管理员。
现在我想创建网络关联或区域,以便 FE1 连接到 BE1(如果可用),如果 BE1 关闭连接到 BE2/BE3。这可以在 spring-cloud-zookeeper 中实现吗?
虽然这可以使用 eureka 来完成,但我更喜欢使用 zookeeper 来完成。
编辑
好的,在尤里卡中,我们可以设置区域字段,功能区可以根据从尤里卡为每个服务器检索的区域字段在客户端中进行区域关联。尽管功能区使用相同的 zonepreference 过滤器,但问题出在 zookeeper 中,但由于 zookeeper 不传递区域信息,它始终保持不变UNKNOWN
,因此不应用区域过滤。
作为解决方法,我尝试在注册服务时将区域信息作为元数据传递,如下所示。
spring:
application:
name: kp-zk-server
cloud:
zookeeper:
discovery:
metadata:
zone: default
现在在客户端创建功能区配置,从元数据中检索区域信息作为过滤器,如下所示。
@Configuration
public class DefaultRibbonConfig {
@Value("${archaius.deployment.zone:default}")
private String zone;
private Predicate<Server> filter = server -> {
if (server instanceof ZookeeperServer) {
ZookeeperServer zkServer = (ZookeeperServer) server;
String str = zkServer.getInstance().getPayload().getMetadata().get("zone");
return zone.equals(str);
}
return true;
};
@Bean
public ServerListFilter<Server> ribbonServerListFilter(IClientConfig config) {
return new ServerListFilter<Server>() {
@Override
public List<Server> getFilteredListOfServers(List<Server> servers) {
List<Server> selected = servers.stream().filter(filter).collect(Collectors.toList());
return selected.isEmpty() ? servers : selected;
}
};
}
}
boostrap.yml
archaius:
deployment:
zone: Zone1
spring:
application:
name: kp-zk-consumer
cloud:
zookeeper:
dependency:
enabled: true
resttemplate:
enabled: false
discovery:
enabled: true
default-health-endpoint: /actuator/health
dependencies:
kWebClient:
path: /kp-zk-server
loadBalancerType: ROUND_ROBIN
required: true
#ribbon:
# NIWSServerListFilterClassName: io.github.kprasad99.zk.KZoneAffinityServerFilter
问题
现在的问题是我的自定义过滤器类没有被启用/使用,功能区仍在使用默认区域过滤器,如果我使用定义配置@RibbonClients
@RibbonClients(defaultConfiguration = DefaultRibbonConfig.class)
但是,如果我声明ribbon.NIWSServerListFilterClassName
未应用过滤器,但在这种情况下我无法设置区域属性,则需要对区域属性进行硬编码。