Service Discovery with Zookeeper

服务发现是基于微服务的体系结构的关键原则之一。尝试手动配置每个客户端或某种形式的约定可能会很困难且脆弱。 Curator(用于 Zookeeper 的 Java 库)通过 Service Discovery Extension 提供服务发现。Spring Cloud Zookeeper 使用此扩展进行服务注册和发现。

Service Discovery is one of the key tenets of a microservice based architecture. Trying to hand-configure each client or some form of convention can be difficult to do and can be brittle. Curator(A Java library for Zookeeper) provides Service Discovery through a Service Discovery Extension. Spring Cloud Zookeeper uses this extension for service registration and discovery.

Activating

依赖 org.springframework.cloud:spring-cloud-starter-zookeeper-discovery 可以启用自动配置,以设置 Spring Cloud Zookeeper Discovery。

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

针对 Web 功能性,您仍需要包含`org.springframework.boot:spring-boot-starter-web`。

For web functionality, you still need to include org.springframework.boot:spring-boot-starter-web.

在使用 Zookeeper 版本 3.4 时,您需要按照 here 中的说明更改包含依赖项的方式。

When working with version 3.4 of Zookeeper you need to change the way you include the dependency as described here.

Registering with Zookeeper

当客户端在 Zookeeper 中注册时,它会提供有关自身元数据(例如主机和端口、ID 和名称)。

When a client registers with Zookeeper, it provides metadata (such as host and port, ID, and name) about itself.

以下示例展示了一个 Zookeeper 客户端:

The following example shows a Zookeeper client:

@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 应用程序。

The preceding example is a normal Spring Boot application.

如果 Zookeeper 位于`localhost:2181` 之外的其他位置,配置必须提供服务器的位置,如下例所示:

If Zookeeper is located somewhere other than localhost:2181, the configuration must provide the location of the server, as shown in the following example:

application.yml
spring:
  cloud:
    zookeeper:
      connect-string: localhost:2181

如果您使用 Spring Cloud Zookeeper Config,则在前一个示例中显示的值需要在 bootstrap.yml 中而不是 application.yml 中。

If you use Spring Cloud Zookeeper Config, the values shown in the preceding example need to be in bootstrap.yml instead of application.yml.

默认服务名、实例 ID 和端口(取自 Environment)分别是`${spring.application.name}`、Spring 上下文 ID 和 ${server.port}

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-cloud-starter-zookeeper-discovery 会让该应用同时变成 Zookeeper “service”(也就是说它将注册自身)和 “client”(也就是说它可以查询 Zookeeper 来找到其他服务)。

Having spring-cloud-starter-zookeeper-discovery on the classpath makes the app into both a Zookeeper “service” (that is, it registers itself) and a “client” (that is, it can query Zookeeper to locate other services).

如果你想禁用 Zookeeper Discovery Client,你可以将`spring.cloud.zookeeper.discovery.enabled` 设置为 false

If you would like to disable the Zookeeper Discovery Client, you can set spring.cloud.zookeeper.discovery.enabled to false.

Using the DiscoveryClient

Spring Cloud 通过 Spring Cloud Loadbalancer,使用逻辑服务名称而非物理 URL,对 OpenFeign(REST 客户端生成器)、`RestTemplate`和 `WebClient`提供支持。

Spring Cloud has support for OpenFeign (a REST client builder), RestTemplate and WebClient via Spring Cloud Loadbalancer, using logical service names instead of physical URLs.

你还可以使用 org.springframework.cloud.client.discovery.DiscoveryClient,该 API 为与 Netflix 无关的发现客户端提供了一个简单的 API,如下例所示:

You can also use the org.springframework.cloud.client.discovery.DiscoveryClient, which provides a simple API for discovery clients that is not specific to Netflix, as shown in the following example:

@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;
}