3. 使用Zookeeper的服务发现

服务发现是微服务架构的一个关键特性。尝试为每个客户端手动配置或采用某种约定可以实现困难且容易产生脆弱性。Curator(一个用于Zookeeper的Java库) 通过 服务发现扩展 提供服务发现。Spring Cloud Zookeeper 使用此扩展进行服务注册和服务发现。spring-doc.cadn.net.cn

3.1. 激活

Including a dependency on org.springframework.cloud:spring-cloud-starter-zookeeper-discovery enables autoconfiguration that sets up Spring Cloud Zookeeper Discovery.spring-doc.cadn.net.cn

对于网页功能,你仍然需要包含 org.springframework.boot:spring-boot-starter-web
在使用 Zookeeper 版本 3.4 时,需要更改 包含依赖的方式,如在 此处 所描述。

3.2. 使用Zookeeper注册

当客户端向Zookeeper注册时,它会提供关于自身的元数据(如主机和端口、ID和名称)。spring-doc.cadn.net.cn

以下示例显示了一个Zookeeper客户端:spring-doc.cadn.net.cn

@SpringBootApplication
@RestController
public class Application {

    @RequestMapping("/")
    public String home() {
        return "Hello world";
    }

    public static void main(String[] args) {
        new SpringApplicationBuilder(Application.class).web(true).run(args);
    }

}
前面的例子是一个正常的 Spring Boot 应用程序。

如果Zookeeper位于非localhost:2181处,配置必须 提供服务器位置的配置,如以下示例所示:spring-doc.cadn.net.cn

application.yml
spring:
  cloud:
    zookeeper:
      connect-string: localhost:2181
如果使用 Spring Cloud Zookeeper Config,前面示例中显示的值需要在 bootstrap.yml 而不是 application.yml 中。

The default service name, instance ID, and port (taken from the Environment) are ${spring.application.name}, the Spring Context ID, and ${server.port}, respectively.spring-doc.cadn.net.cn

具有在类路径上具有spring-cloud-starter-zookeeper-discovery的配置会使应用程序同时成为Zookeeper的“服务”(也就是说,它会注册自己)和“客户端”(也就是说,它可以查询Zookeeper以定位其他服务)。spring-doc.cadn.net.cn

如果您希望禁用Zookeeper Discovery Client,可以将spring.cloud.zookeeper.discovery.enabled设置为falsespring-doc.cadn.net.cn

3.3. 使用 DiscoveryClient

Spring Cloud 支持 Feign (一个 REST 客户端构建器), Spring RestTemplate 以及 Spring WebFlux,使用逻辑服务名代替物理URL。spring-doc.cadn.net.cn

您也可以使用 org.springframework.cloud.client.discovery.DiscoveryClient,它 提供了一个不特定于 Netflix 的简单发现客户端API,如以下示例所示:spring-doc.cadn.net.cn

@Autowired
private DiscoveryClient discoveryClient;

public String serviceUrl() {
    List<ServiceInstance> list = discoveryClient.getInstances("STORES");
    if (list != null && list.size() > 0 ) {
        return list.get(0).getUri().toString();
    }
    return null;
}