引言
zookeeper是一个分布式协调工具,可以实现注册中心功能
CentOS安装zookeeper(docker安装)
下载Zookeeper镜像
docker pull zookeeper:3.6.1
启动容器并添加映射
docker run --privileged=true -d --name zookeeper -p 2181:2181 -d zookeeper:3.6.1
查看容器是否启动
docker ps
启动zookeeper客户端
如果我们要启动zk的客户端,可以使用以下命令:
docker exec -it 容器id zkCli.sh
springcloud整合zookeeper
创建cloud-provider-payment8092
改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"><parent><artifactId>cloud2020</artifactId><groupId>com.sgy.cloud2020</groupId><version>1.0-SNAPSHOT</version></parent><modelVersion>4.0.0</modelVersion><artifactId>cloud-provider-payment8092</artifactId><dependencies><dependency><groupId>com.sgy.cloud2020</groupId><artifactId>cloud-provider</artifactId><version>${project.version}</version></dependency><!--springcloud整合zookeeper--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-zookeeper-discovery</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><scope>provided</scope></dependency></dependencies></project>
主启动类
/**
* Created by AaronShen on 2020/5/27
*/
@SpringBootApplication
// 整合consul和zookeeper都需要这个注解
@EnableDiscoveryClient
public class PaymentMain8092 {
public static void main(String[] args) {
SpringApplication.run(PaymentMain8092.class,args);
}
}
改配置yml
server:
port: 8092
spring:
application:
name: cloud-payment-server
datasource:
username: blog
password: 123456
url: jdbc:mysql://192.168.200.10:3306/cloud?useUnicode=true&characterEncoding=utf8&characterSetResults=utf8&serverTimezone=GMT%2B8
driver-class-name: com.mysql.cj.jdbc.Driver
# 使用我们自己的druid数据源
type: com.alibaba.druid.pool.DruidDataSource
initialSize: 10 #初始化连接个数
minIdle: 5 #最小连接个数
maxActive: 500 #最大连接个数
maxWait: 60000 #最大等待时间
timeBetweenEvictionRunsMillis: 60000
minEvictableIdleTimeMillis: 300000
validationQuery: SELECT 1 FROM DUAL
testWhileIdle: true
testOnBorrow: false
testOnReturn: false
poolPreparedStatements: true
# 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
filters: stat,wall,log4j
maxPoolPreparedStatementPerConnectionSize: 20
useGlobalDataSourceStat: true
connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500
cloud:
zookeeper:
connect-string: 192.168.200.10:2181
mybatis:
# config-location和configuration不能同时配置,否则会抛出异常
# 一般只配置configuration即可,会自动找到mybatis全局配置文件
# config-location: classpath:mybatis/mybatis-config.xml
mapper-locations: classpath:mapper/*Mapper.xml
# 对应实体类的路径,只能指定具体的包,多个配置可以使用英文逗号隔开
type-aliases-package: com.sgy.payment
configuration:
# Mybatis SQL语句控制台打印
# log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
# 开启驼峰命名规则
# 在数据库中字段可以采用驼峰命名规则,mybatis会把 下划线去掉并把下划线后面的首字母认为是大写
map-underscore-to-camel-case: true
logging:
level:
# 注意注意注意 一定要修改成自己的包名
com.sgy: debug
file:
path: log/
name: log/com.sgy.payment-dev.log
clean-history-on-start: true
pattern:
console: "%d{yyyy-MM-dd} [%thread] %-5level %logger{50} ===> %msg%n"
file: "%d{yyyy-MM-dd} === [%thread] === %-5level === %logger{50} ===> %msg%n"
编写controller
@RestController
@Slf4j
public class PaymentController {
@Value("${server.port}")
private String SERVER_PORT;
@GetMapping(value = "/zk")
public Object zk() {
log.info("测试zk , 服务端口号 = {},UUID = {}",SERVER_PORT, UUID.randomUUID().toString());
return "测试通过";
}
}
测试
启动
启动报错,让我们一点一点来分析
- 找到报错所在位置是自己定义的类包名
- 这是启动类报错,启动类报错,基本可以断定是环境配置有问题

- 接着看
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'baseDaoServiceImpl'
创建一个baseDaoServiceImpl失败,导致的原因就是在spring容器中没有找到创建baseDaoServiceImpl所继承的类
@Service
public class BaseDaoServiceImpl<T extends BaseEntities,ID,D extends MyMapper<T>>
implements BaseDaoService<T, ID> {
}
这个类是我自定义的服务层基础类,他是一个泛型,而其中MyMapper是一个接口,继承Mapper<T> , InsertListMapper<T>
/**
* Created by AaronShen on 2020/5/26
*/
public interface MyMapper<T> extends Mapper<T> , InsertListMapper<T> {
}
然后我们必须让MyMapper的子类被扫描到spring容器中,因此,在我新创建的工程中,我需要引入一个dao层文件并且添加@Mapper,让springboot扫描到Mapper<T>
@Mapper
public interface PaymentDao extends MyMapper<Payment> {
}
版本冲突问题
如果出现zookeeper版本冲突,centos中安装的zookeeper版本跟项目中使用的客户端版本不一致,你需要排除spring-cloud-starter-zookeeper-discovery已有的zookeeper,然后重新引入zookeeper客户端
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zookeeper-discovery</artifactId>
<exclusions>
<exclusion>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.5.6</version>
</dependency>
此处注意需要排除spring-cloud-zookeeper中自带的zookeeper版本,保持与服务端版本一致,否则连接步成功。
使用zk客户端查看服务注册
[zk: localhost:2181(CONNECTED) 6] ls /
[services, zookeeper]
[zk: localhost:2181(CONNECTED) 7] ls /services
[cloud-payment-server] 这就是注册的服务名称
[zk: localhost:2181(CONNECTED) 8] ls /services/cloud-payment-server
[d990d789-e0b8-441c-99bc-95986c057dca]
[zk: localhost:2181(CONNECTED) 10] ls /services/cloud-payment-server/d990d789-e0b8-441c-99bc-95986c057dca
[]
[zk: localhost:2181(CONNECTED) 11] get /services/cloud-payment-server/d990d789-e0b8-441c-99bc-95986c057dca
{"name":"cloud-payment-server","id":"d990d789-e0b8-441c-99bc-95986c057dca","address":"localhost","port":8092,"sslPort":null,"payload":{"@class":"org.springframework.cloud.zookeeper.discovery.ZookeeperInstance","id":"application-1","name":"cloud-payment-server","metadata":{}},"registrationTimeUTC":1590578412812,"serviceType":"DYNAMIC","uriSpec":{"parts":[{"value":"scheme","variable":true},{"value":"://","variable":false},{"value":"address","variable":true},{"value":":","variable":false},{"value":"port","variable":true}]}}
json格式化结果

zookeeper服务节点是持久节点还是临时节点
结论
是临时节点
探索过程
- 我们现在关掉支付服务节点
- 然后使用zk客户端,查看节点是否存在,发现服务节点已经被去掉了
[zk: localhost:2181(CONNECTED) 13] ls /services/cloud-payment-server
[d990d789-e0b8-441c-99bc-95986c057dca]
[zk: localhost:2181(CONNECTED) 14] ls /services/cloud-payment-server
[]
- 重启支付节点
- 服务节点又回来了
- 流水号是一个新值
[zk: localhost:2181(CONNECTED) 15] ls /services/cloud-payment-server
[]
[zk: localhost:2181(CONNECTED) 16] ls /services/cloud-payment-server
[93d772c8-8117-476a-8a6e-59020bac4cfc]
- 因此服务节点是一个临时节点
