作者 | QiaoZhi


Springcloud用Zookeeper做注册中心。需要先安装好zookeeper。

1. 支付模块用zookeeper做注册中心

1新建支付模块 cloud-providerzk-payment8084

选择父工程之后新建moudle,GroupId和Version采用继承的即可,如下:




zookeeper查询白名单 zookeeper cap_ide


2.修改pom.xml

<?xml  version="1.0" encoding="UTF-8"?>            cloud        cn.qz.cloud        1.0-SNAPSHOT        4.0.0    cloud-providerzk-payment8084                                org.springframework.cloud            spring-cloud-starter-zookeeper-discovery                                    cn.qz.cloud            cloud-api-commons            ${project.version}                            org.springframework.boot            spring-boot-starter-web                            org.projectlombok            lombok            true                            org.springframework.boot            spring-boot-starter-test            test                            org.springframework.boot            spring-boot-starter-test            test

3.新建yml配置文件:

#8084表示注册到zookeeper服务器的支付服务提供者端口号server:  port: 8084#服务别名----注册zookeeper到注册中心名称spring:  application:    name: cloud-provider-payment  cloud:    zookeeper:      connect-string: 127.0.0.1:2181

4.新建启动类:

package cn.qz.cloud;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.cloud.client.discovery.EnableDiscoveryClient;/** * @Author: qlq * @Description * @Date: 22:49 2020/10/14 */@SpringBootApplication@EnableDiscoveryClient //该注解用于向使用consul或者zookeeper作为注册中心时注册服务public class PaymentMain8084 {    public static void main(String[] args) {        SpringApplication.run(PaymentMain8084.class, args);    }}

5.新建测试Controller

package cn.qz.cloud.controller;import lombok.extern.slf4j.Slf4j;import org.springframework.beans.factory.annotation.Value;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;import java.util.UUID;@RestController@RequestMapping("/pay")@Slf4jpublic class PaymentController{    @Value("${server.port}")    private String serverPort;    @RequestMapping(value = "/paymentzk")    public String paymentzk()    {        return "springcloud with zookeeper: "+serverPort+""+ UUID.randomUUID().toString();    }}

6.启动服务后查看zookeeper中注册的服务


zookeeper查询白名单 zookeeper cap_spring_02


是在zookeeper建立了一个/services/appname/UUID这样的节点来存放数据,节点值格式化后如下:

{    "name": "cloud-provider-payment",    "id": "ae024e43-703b-4edc-8a73-2cb7758fdb35",    "address": "root",    "port": 8084,    "sslPort": null,    "payload": {        "@class": "org.springframework.cloud.zookeeper.discovery.ZookeeperInstance",        "id": "application-1",        "name": "cloud-provider-payment",        "metadata": {}    },    "registrationTimeUTC": 1602687210606,    "serviceType": "DYNAMIC",    "uriSpec": {        "parts": [            {                "value": "scheme",                "variable": true            },            {                "value": "://",                "variable": false            },            {                "value": "address",                "variable": true            },            {                "value": ":",                "variable": false            },            {                "value": "port",                "variable": true            }        ]    }}

可以看到上面的zk注册中心的address是主机名称,改为IP:

(1)修改yml文件:

#8084表示注册到zookeeper服务器的支付服务提供者端口号server:  port: 8084#服务别名----注册zookeeper到注册中心名称spring:  application:    name: cloud-provider-payment  cloud:    zookeeper:      connect-string: 127.0.0.1:2181      discovery:        enabled: true        instance-host: 127.0.0.1

(2)启动后再次查看:

{    "name": "cloud-provider-payment",    "id": "8f8a28b8-d154-469e-aef3-7073ebcad93b",    "address": "127.0.0.1",    "port": 8084,    "sslPort": null,    "payload": {        "@class": "org.springframework.cloud.zookeeper.discovery.ZookeeperInstance",        "id": "application-1",        "name": "cloud-provider-payment",        "metadata": {}    },    "registrationTimeUTC": 1602754345242,    "serviceType": "DYNAMIC",    "uriSpec": {        "parts": [            {                "value": "scheme",                "variable": true            },            {                "value": "://",                "variable": false            },            {                "value": "address",                "variable": true            },            {                "value": ":",                "variable": false            },            {                "value": "port",                "variable": true            }        ]    }}

(3)查看节点的属性如下:ephemeralOwner代表是临时节点,值为会话的ID


zookeeper查询白名单 zookeeper cap_zookeeper_03


2.订单模块调用zookeeper服务

1.新建子模块:cloud-consumerzk-order80


zookeeper查询白名单 zookeeper cap_zookeeper_04


2.修改pom.xml

<?xml  version="1.0" encoding="UTF-8"?>            cloud        cn.qz.cloud        1.0-SNAPSHOT        4.0.0    cloud-consumerzk-order80                                org.springframework.cloud            spring-cloud-starter-zookeeper-discovery                                    cn.qz.cloud            cloud-api-commons            ${project.version}                            org.springframework.boot            spring-boot-starter-web                            org.projectlombok            lombok            true                            org.springframework.boot            spring-boot-starter-test            test                            org.springframework.boot            spring-boot-starter-test            test

3.修改yml文件:

server:  port: 80spring:  application:    name: cloud-consumer-order  cloud:  #注册到zookeeper地址    zookeeper:      connect-string: 127.0.0.1:2181

4.新建启动类:

package cn.qz.cloud;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.cloud.client.discovery.EnableDiscoveryClient;/** * @Author: qlq * @Description * @Date: 23:05 2020/10/14 */@SpringBootApplication@EnableDiscoveryClientpublic class OrderZKMain80 {    public static void main(String[] args) {        SpringApplication.run(OrderZKMain80.class, args);    }}

5.建立业务类:

(1)注册RestTemplate:

package cn.qz.cloud.config;import org.springframework.cloud.client.loadbalancer.LoadBalanced;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.web.client.RestTemplate;@Configurationpublic class ApplicationContextConfig {    @Bean    @LoadBalanced    public RestTemplate getRestTemplate() {        return new RestTemplate();    }}

(2)Controller调用注册中心服务:

package cn.qz.cloud.controller;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;import org.springframework.web.client.RestTemplate;import javax.annotation.Resource;@RestController@RequestMapping("/consumer")public class OrderZKController {    public static final String INVOKE_URL = "http://cloud-provider-payment";    @Resource    private RestTemplate restTemplate;    @GetMapping("/pay/paymentzk")    public String paymentzk() {        String result = restTemplate.getForObject(INVOKE_URL + "/pay/paymentzk", String.class);        return result;    }}

6.启动服务查看zk信息如下:


zookeeper查询白名单 zookeeper cap_ide_05


7.访问测试结果如下:


zookeeper查询白名单 zookeeper cap_zookeeper查询白名单_06


补充:Consul简介

  Consul是一套开源的分布式服务发现和配置管理系统,由HashiCorp公司用Go语言开发。提供了服务治理、控制总线等功能。

  和zookeeper一样,需要安装客户端后使用。

补充:Eureka、zk、Consul三个注册中心的异同点

一张图如下:


zookeeper查询白名单 zookeeper cap_zookeeper查询白名单_07


分布式环境有个CAP原则,又称为CAP理论,主要思想是在任何一个分布式系统中都无法同时满足CAP。

C(Consistency):表示一致性,所有的节点同一时间看到的是相同的数据。

A(Avaliablity):表示可用性,不管是否成功,确保一个请求都能接收到响应。

P(Partion Tolerance):分区容错性,系统任意分区后,在网络故障时,仍能操作。

(1)由于当前的网络硬件肯定会出现延迟丢包等问题,所以分区容忍性是我们必须需要实现的。所以我们只能在一致性和可用性之间进行权衡。

CA满足的情况下,P不能满足的原因:数据同步需要时间,也要正常的时间内响应(A),那么机器数量就要少,所以P就不满足

CP 满足的情况下,A不能满足的原因:数据同步需要时间, 机器数量也多,但是同步数据需要时间,所以不能再正常时间内响应,所以A就不满足

AP 满足的情况下,C不能满足的原因:机器数量也多,正常的时间内响应(A),那么数据就不能及时同步到其他节点,所以C不满足。

(2)关于三个注册中心满足的原则:

Zookeeper和Consul :CP设计,保证了一致性,集群搭建的时候,某个节点失效,则会进行选举行的leader,或者半数以上节点不可用,则无法提供服务,因此可用性没法满足。

Eureka:AP原则,无主从节点,一个节点挂了,自动切换其他节点可以使用,去中心化。