介紹如何在Spring Cloud中使用Zookeeper作為服務註冊中心

weixin_34353714發表於2018-03-26

本文將介紹如何使用Zookeeper在微服務框架中實現服務發現,該服務發現機制可作為雲服務的註冊中心。通過Spring Cloud Zookeeper為應用程式提供一種Spring Boot整合,將Zookeeper通過自動配置和繫結 的方式整合到Spring環境中。

在本例子中我們將建立兩個應用程式:

  • 提供服務的應用程式(稱為 服務提供者)
  • 使用此服務的應用程式(稱為 服務消費者)

Apache Zookeeper將充當我們服務發現設定中的協調者。Apache Zookeeper安裝說明可在以下連結中找到。《zookeeper安裝和使用 windows環境

1 服務提供者

我們將建立一個服務提供者,通過增加pring-cloud-starter-zookeeper-discovery依賴和在主程式中引入@EnableDiscoveryClient註釋。服務的具體內容是通過GET請求返回“Hello World!”字串。

1.1 Maven依賴

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-zookeeper-discovery</artifactId>
    <exclusions>
        <exclusion>
            <artifactId>commons-logging</artifactId>
            <groupId>commons-logging</groupId>
        </exclusion>
    </exclusions>
</dependency>

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter</artifactId>
</dependency>

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

1.2 SpringBoot主程式

使用@EnableDiscoveryClient註釋我們的主類,這將使HelloWorld 應用程式自動釋出。

@SpringBootApplication
@EnableDiscoveryClient
public class HelloWorldApplication {
    public static void main(String[] args) {
        SpringApplication.run(HelloWorldApplication.class, args);
    }
}

一個簡單的Controller

@RestController
public class HelloWorldController {
    @GetMapping("/helloworld")
    public String HelloWorld() {
        return "Hello World!";
    }
}

1.3 配置檔案

在application.yml中定義服務名稱用來被客戶端呼叫,同時配置Zookeeper資訊用來註冊服務。

spring:
  application:
    name: HelloWorld
  cloud:
    zookeeper:
      connect-string: localhost:2181
      discovery:
        enabled: true
server:
  port: 8081
endpoints:
  restart:
    enabled: true
logging:
  level:
    org.apache.zookeeper.ClientCnxn: WARN

2 服務消費者

現在我們來建立一個REST服務消費者,它使用spring Netflix Feign Client來呼叫服務。

2.1 Maven依賴

在pom檔案裡增加需要依賴的一些元件包。

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-zookeeper-discovery</artifactId>
    <exclusions>
        <exclusion>
            <artifactId>commons-logging</artifactId>
            <groupId>commons-logging</groupId>
        </exclusion>
    </exclusions>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-feign</artifactId>
</dependency>

2.2 SpringBoot主程式

同服務提供者一樣在主程式中增加@EnableDiscoveryClient 註解。

@SpringBootApplication
@EnableDiscoveryClient
public class GreetingApplication {
    public static void main(String[] args) {
        SpringApplication.run(GreetingApplication.class, args);
    }
}

2.3 Controller類

以下是一個簡單的服務控制器類,它通過注入介面helloWorldClient物件呼叫服務提供者的介面來消費該服務,並在響應中顯示它的返回值。

@RestController
public class GreetingController {
    @Autowired
    private HelloWorldClient helloWorldClient;

    @GetMapping("/get-greeting")
    public String greeting() {

        return helloWorldClient.HelloWorld();

    }
}

2.4 宣告式服務呼叫客戶端

通過引入spring-cloud-starter-feign元件包使用宣告式服務呼叫方式呼叫遠端服務,使用@FeignClient(“service-name”)註釋一個介面並將它自動連線到我們的應用程式中,以便我們以程式設計方式訪問此服務。

@Configuration
@EnableFeignClients
@EnableDiscoveryClient
public class HelloWorldClient {
    @Autowired
    private TheClient theClient;

    @FeignClient(name = "HelloWorld")
    interface TheClient {

        @RequestMapping(path = "/helloworld", method = RequestMethod.GET)
        @ResponseBody
        String HelloWorld();
    }

    public String HelloWorld() {
        return theClient.HelloWorld();
    }
}

2.5 配置檔案

spring:
  application:
    name: Greeting
  cloud:
    zookeeper:
      connect-string: localhost:2181
server:
  port: 8083
logging:
  level:
    org.apache.zookeeper.ClientCnxn: WARN

3 執行

HelloWorld REST服務在Zookeeper中註冊了自己,Greeting服務通過宣告式客戶端發現和呼叫HelloWorld 服務。

現在我們可以執行這兩個服務,然後在瀏覽器中訪問 http://localhost:8083/get-greeting,將返回

Hello World!

4 總結

在本文中我們看到了如何使用Spring Cloud Zookeeper實現服務發現,並且在Zookeeper中註冊了一個名為Hello World的服務。然後通過宣告式服務呼叫方式實現了一個服務消費者Greeting來發現和使用該服務。

在這裡介紹下Zookeeper與Eureka這兩種服務治理框架的區別。Spring Cloud Eureka實現的服務治理機制強調了CAP原理中的AP,即可用性與可靠性,而Zookeeper這類強調CP(一致性、可靠性)。Eureka為了實現更高的服務可用性,犧牲了一定的一致性,在極端情況下它寧願接受故障例項也不要丟掉“健康”例項,比如,當服務註冊中心的網路發生故障斷開時,由於所有的服務例項無法維持續約心跳,在強調CP的服務治理中將會把所有服務例項都剔除掉,而Eureka則會觸發保護機制,保留此時的所有節點,以實現服務間依然可以進行互相呼叫的場景。

相關文章