У меня есть 3 интерфейсных приложения и 3 серверных приложения. Допустим, 1 виртуальная машина содержит как интерфейсное, так и серверное приложение, как показано на диаграмме ниже. Каждое интерфейсное приложение подключается к серверной части с помощью функции обнаруженияклиент работает на zookeeper.
Теперь я хочу создать сетевую привязку или зону, такую, чтобы FE1 подключался к BE1, если он доступен, если BE1 не работает, подключайтесь кВЕ2 / BE3.Может ли это быть достигнуто в spring-cloud-zookeeper?
Хотя это можно сделать с помощью eureka, но я бы предпочел сделать это с помощью zookeeper.
EDIT
Хорошо, в eureka мы можем установить поле зоны, и лента может выполнять привязку зоны в клиенте на основе поля зоны, полученного из eureka для каждого сервера.Проблема в 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
, фильтр не применяется, но в этом случае я не могу установить свойство зоны, необходимо жестко закодировать свойство зоны,