1

我有一个 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未应用过滤器,但在这种情况下我无法设置区域属性,则需要对区域属性进行硬编码。

4

1 回答 1

0

据我所知,开箱即用的 Zookeeper 无法做到这一点。但是,您可以通过使用spring-cloud-loadbalancer和自定义来实现相同的结果,该自定义根据已设置的给定元数据ServiceInstanceSupplier扩展和过滤实例,或者如果没有符合条件的实例返回完整列表,为您提供一些回退。DiscoveryClientServiceInstanceSupplier这是一个通用的解决方案,即使您在同一个数据中心运行,也可以解决您的问题。

希望这可以帮助!

于 2019-02-26T14:52:42.983 回答