一、zookeeper作为注册中心

eureka现在已经不更新,如果再继续使用,出现重大BUG就是一个棘手的事情了,当然现在已经推出了更为优秀的nacos作为注册中心,但是zookeeper也是一种备选方案嘛。上一篇文章我们讲解了eureka的使用及注意点,这篇我们接着上篇的继续,将注册中心修改为zookeeper。


二、准备工作

既然使用zookeeper作为注册中心了,第一步肯定只要有一台zookeeper的服务作为支撑,zookeeper搭建可以参考下面一篇我的博客:


还是和上篇文章中讲的一样,在父pom,或者自己的boot项目中声明出SpringCloud的版本:

版本我们采用H版的SR9版本

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.bxc</groupId>
    <artifactId>cloud-demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>cloud-parent</name>
    <packaging>pom</packaging>

    <properties>
        <java.version>1.8</java.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <spring-boot.version>2.3.7.RELEASE</spring-boot.version>
        <spring-cloud.version>Hoxton.SR9</spring-cloud.version>
        <model.version>0.0.1-SNAPSHOT</model.version>
    </properties>


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

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.16</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.62</version>
        </dependency>

    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring-boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

            <!--spring cloud Hoxton.SR9-->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.8.1</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                    <encoding>UTF-8</encoding>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>2.3.7.RELEASE</version>
                <configuration>
                    <mainClass>com.bxc.clouddemo.CloudDemoApplication</mainClass>
                </configuration>
                <executions>
                    <execution>
                        <id>repackage</id>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

</project>

三、服务提供者修改

在pom中引入依赖:

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

<!-- SpringBoot整合zookeeper客户端 -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-zookeeper-discovery</artifactId>
    <!--先排除自带的zookeeper-->
    <exclusions>
        <exclusion>
            <groupId>org.apache.zookeeper</groupId>
            <artifactId>zookeeper</artifactId>
        </exclusion>
    </exclusions>
</dependency>
<!--添加zookeeper3.4.9版本-->
<dependency>
    <groupId>org.apache.zookeeper</groupId>
    <artifactId>zookeeper</artifactId>
    <version>3.4.9</version>
    <exclusions>
        <exclusion>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
        </exclusion>
        <exclusion>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
        </exclusion>
    </exclusions>
</dependency>

<dependency>
    <groupId>com.bxc</groupId>
    <artifactId>common</artifactId>
    <version>0.0.1-SNAPSHOT</version>
</dependency>

spring-cloud-starter-zookeeper-discovery自带的zookeeper 包版本比较高,可能和自己安装的版本不一致,我这里用的3.4.x版的,所以排除了原先自带了,添加相应版本 ,添加后会报log4冲突的错误,直接排除掉即可。common是我们上篇博客中讲到的公共的module,大家可以参考上篇博客,也可以不依赖,将controller的返回修改为自定义的即可。

修改配置文件:

server:
  port: 8091
spring:
  application:
    name: provider
  cloud:
    zookeeper:
      connect-string: 127.0.0.1:2181
      discovery:
        instance-host: 127.0.0.1

主启动类修改:

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

启动服务提供者,查看zookeeper中的节点:

centos zookeeper 注册服务 zookeeper做注册中心_eureka


可以看出服务信息,已经存储在了zookeeper中,此时切换一个端口,再启动一个提供者,在查看zookeeper节点的信息:

centos zookeeper 注册服务 zookeeper做注册中心_spring_02


provider节点下,就出现两个信息了,这里需要知道的是,provider下的节点信息是临时节点并非持久节点,服务断开链接该节点便不存在,这点和eureka有些许差别,当然这也符合zookeeper cp的理念。

最后编写提供者提供的服务接口:

@RestController
public class ProviderController {

    @Value("${server.port}")
    private String port;

    @GetMapping("/getData")
    public ResponseTemplate providerData() {

        return ResSuccessTemplate.builder().data("come from : " + port).build();
    }

    @GetMapping("/getTimeData")
    public ResponseTemplate getTimeData() throws InterruptedException {
        TimeUnit.SECONDS.sleep(5);
        return ResSuccessTemplate.builder().data("come from : " + port).build();
    }

}

四、服务消费者修改

消费者端的pom和配置和提供者相同,可以完全拷贝过来,将端口改为8080,在消费端,我们还是采用ribbon + restTemplate 的方式进行演示,后面我们会讲解feign的具体使用。

声明 RestTemplate

@Configuration
public class RestTemplateConfig {
    @Bean
    @LoadBalanced
    public RestTemplate getRestTemplate() {
        return new RestTemplate();
    }
}

编写测试接口

@RestController
@RequestMapping("/rest/consumer")
public class ConsumerController {
    @Autowired
    RestTemplate restTemplate;

    @GetMapping("/getData")
    public ResponseTemplate getData() {
        ResponseTemplate responseTemplate = restTemplate.getForObject("http://provider/getData", ResSuccessTemplate.class);
        return responseTemplate;
    }

    @GetMapping("/getTimeData")
    public ResponseTemplate getTimeData() {
        ResponseTemplate responseTemplate = restTemplate.getForObject("http://provider/getTimeData", ResSuccessTemplate.class);
        return responseTemplate;
    }

}

注意,这里的服务是区分大小写的,在eureka中是不分大小写的。

接口测试,在浏览器输入:http://localhost:8080/rest/consumer/getData

centos zookeeper 注册服务 zookeeper做注册中心_zookeeper_03


centos zookeeper 注册服务 zookeeper做注册中心_spring_04


已经实现和Eureka相同的效果,但也只修改了少量的配置。