Spring Cloud Zookeeper搭建实例

1. 简介

本文将介绍如何使用Zookeeper在微服务框架中实现服务发现,该服务发现机制可做为云服务的注册中心。经过Spring Cloud Zookeeper为应用程序提供一种Spring Boot集成,将Zookeeper经过自动配置和绑定 的方式集成到Spring环境中。html

在本例子中咱们将建立两个应用程序:java

  • 提供服务的应用程序(称为 服务提供者
  • 使用此服务的应用程序(称为 服务消费者

2. 安装Zookeeper

2.1 下载

Apache官方最新版本为:3.4.8
下载地址:http://mirrors.cnnic.cn/apach...web

2.2 安装

解压到指定目录下 D:\soft\zookeeper-3.4.8 修改zoo_sample.cfg 文件名(D:softzookeeper-3.4.8conf) 为 zoo.cfg主要修改一下日志位置,具体配置文件以下:spring

# The number of milliseconds of each tick
tickTime=2000
# The number of ticks that the initial 
# synchronization phase can take
initLimit=10
# The number of ticks that can pass between 
# sending a request and getting an acknowledgement
syncLimit=5
# the directory where the snapshot is stored.
# do not use /tmp for storage, /tmp here is just 
# example sakes.
dataDir=D:\\zookeeper\\data
dataLogDir=D:\\zookeeper\\log
# the port at which the clients will connect
clientPort=2181
# the maximum number of client connections.
# increase this if you need to handle more clients
#maxClientCnxns=60
#
# Be sure to read the maintenance section of the 
# administrator guide before turning on autopurge.
#
# http://zookeeper.apache.org/doc/current/zookeeperAdmin.html#sc_maintenance
#
# The number of snapshots to retain in dataDir
#autopurge.snapRetainCount=3
# Purge task interval in hours
# Set to "0" to disable auto purge feature
#autopurge.purgeInterval=1
  • tickTime:这个时间是做为 Zookeeper 服务器之间或客户端与服务器之间维持心跳的时间间隔,也就是每一个 tickTime 时间就会发送一个心跳。
  • dataDir:顾名思义就是 Zookeeper 保存数据的目录,默认状况下,Zookeeper 将写数据的日志文件也保存在这个目录里。
  • dataLogDir:顾名思义就是 Zookeeper 保存日志文件的目录
  • clientPort:这个端口就是客户端链接 Zookeeper 服务器的端口,Zookeeper 会监听这个端口,接受客户端的访问请求。

2.3 启动

进入到bin目录,而且启动zkServer.cmd,这个脚本中会启动一个java进程,双击该文件便可启动:apache

file

3. 搭建服务提供者

咱们将建立一个服务提供者,经过增长pring-cloud-starter-zookeeper-discovery依赖和在主程序中引入@EnableDiscoveryClient注释。服务的具体内容是经过GET请求返回“Hello World!”字符串。
整个项目结构以下:编程

file

3.1 导入依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.yiidian</groupId>
    <artifactId>spring-cloud-zookeeper-proivder</artifactId>
    <version>1.0-SNAPSHOT</version>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.1.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>


    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <!-- SpringBoot 对Web支持  SpringMVC相关功能,json转换的功能等等 -->
        <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>
        </dependency>
    </dependencies>

    <!-- 定义SpringCloud版本 -->
    <repositories>
        <repository>
            <id>spring-snapshots</id>
            <name>Spring Snapshots</name>
            <url>https://repo.spring.io/snapshot</url>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
        </repository>
        <repository>
            <id>spring-milestones</id>
            <name>Spring Milestones</name>
            <url>https://repo.spring.io/milestone</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </repository>
    </repositories>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Finchley.M9</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
</project>

3.2 启动类

使用@EnableDiscoveryClient注释咱们的主类,这将使HelloWorld 应用程序自动发布。json

package com.yiidian.provider;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

/**
 * 服务提供者启动类
 */
@SpringBootApplication
@EnableDiscoveryClient
public class ProviderStarter {

    public static void main(String[] args) {
        SpringApplication.run(ProviderStarter.class,args);
    }

}

3.3 Controller

package com.yiidian.provider.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * 一点教程网: http://www.yiidian.com
 * 控制器
 */
@RestController
public class HelloController {

    @GetMapping("/hello")
    public String hello(){
        return "Hello World";
    }

}

3.4 配置application.yml

在application.yml中定义服务名称用来被客户端调用,同时配置Zookeeper信息用来注册服务。segmentfault

server:
  port: 9001
spring:
  application:
    name: Provider
  cloud:
    zookeeper:
      discovery:
        enabled: true
      connect-string: localhost:2181
logging:
  level:
    org.apache.zookeeper.ClientCnxn: WARN

4. 搭建服务消费者

如今咱们来建立一个REST服务消费者,它使用spring Netflix Feign Client来调用服务。先看看整个项目结构:
file浏览器

4.1 导入依赖

在pom文件里增长须要依赖的一些组件包。服务器

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.yiidian</groupId>
    <artifactId>spring-cloud-zookeeper-consumer</artifactId>
    <version>1.0-SNAPSHOT</version>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.1.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>


    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <!-- SpringBoot 对Web支持  SpringMVC相关功能,json转换的功能等等 -->
        <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>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
    </dependencies>

    <!-- 定义SpringCloud版本 -->
    <repositories>
        <repository>
            <id>spring-snapshots</id>
            <name>Spring Snapshots</name>
            <url>https://repo.spring.io/snapshot</url>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
        </repository>
        <repository>
            <id>spring-milestones</id>
            <name>Spring Milestones</name>
            <url>https://repo.spring.io/milestone</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </repository>
    </repositories>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Finchley.M9</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
</project>

4.2 启动类

同服务提供者同样在主程序中增长@EnableDiscoveryClient 注解。

package com.yiidian.consumer;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;

/**
 *服务消费者启动类
 */
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class ConsumerStarter {

    public static void main(String[] args) {
        SpringApplication.run(ConsumerStarter.class,args);
    }

}

4.3 定义Feign远程接口

经过引入spring-cloud-starter-openfeign组件包使用声明式服务调用方式调用远程服务,使用@FeignClient(“service-name”)注解一个接口并将它自动链接到咱们的应用程序中,以便咱们以编程方式访问此服务。

package com.yiidian.consumer.client;

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;

/**
 * Feign远程接口
 */
@FeignClient("Provider")
public interface HelloClient {

    @GetMapping("/hello")
    public String hello();
}

4.4 Controller

如下是一个简单的服务控制器类,它经过注入接口helloWorldClient对象调用服务提供者的接口来消费该服务,并在响应中显示它的返回值。

package com.yiidian.consumer.controller;

import com.yiidian.consumer.client.HelloClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * 消费者控制器
 */
@RestController
public class GreetingController {

    @Autowired
    private HelloClient helloClient;

    @GetMapping("/get-greeting")
    public String greeting() {
        return helloClient.hello();
    }

}

4.5 配置application.yml

server:
  port: 9002
spring:
  application:
    name: Consumer
  cloud:
    zookeeper:
      discovery:
        enabled: true
      connect-string: localhost:2181
logging:
  level:
    org.apache.zookeeper.ClientCnxn: WARN

5. 测试

HelloWorld REST服务在Zookeeper中注册了本身,Greeting服务经过声明式客户端发现和调用HelloWorld 服务。

如今咱们能够运行这两个服务,而后在浏览器中访问 http://localhost:9002/get-greeting,将返回如下信息:

file

6. 总结

在本文中咱们看到了如何使用Spring Cloud Zookeeper实现服务发现,而且在Zookeeper中注册了一个名为Hello World的服务。而后经过声明式服务调用方式实现了一个服务消费者Greeting来发现和使用该服务。

顺便介绍下ZookeeperEureka这两种服务治理框架的区别。Spring Cloud Eureka实现的服务治理机制强调了CAP原理中的AP,即可用性可靠性,而Zookeeper强调CP(一致性可靠性)。Eureka为了实现更高的服务可用性,牺牲了必定的一致性,在极端状况下它宁愿接受故障实例也不要丢掉“健康”实例,好比,当服务注册中心的网络发生故障断开时,因为全部的服务实例没法维持续约心跳,在强调CP的服务治理中将会把全部服务实例都剔除掉,而Eureka则会触发保护机制,保留此时的全部节点,以实现服务间依然能够进行互相调用的场景。

file

欢迎关注个人公众号::一点教程。得到独家整理的学习资源和平常干货推送。
若是您对个人系列教程感兴趣,也能够关注个人网站: yiidian.com