- zookeeper
介绍:zk 它是一个树形目录结构! /
ZooKeeper是一个分布式协调技术、高性能的,开源的分布式系统的协调(Coordination)服务!
了解zookeeper的生态圈!dubbo solr …等技术!
安装:
linux 服务器上! 创建目录 mkdir /myzookeeper 导入压缩包! ```
解压! tar -zxvf zookeeper-3.4.14.tar.gz
安装jdk!zk 使用java 语言编写! 导入解压! vim /etc/profile export JAVA_HOME=/usr/local/jdk export JRE_HOME=$JAVA_HOME/jre export CLASSPATH=.:$CLASSPATH:$JAVA_HOME/lib:$JRE_HOME/lib export PATH=$PATH:$JAVA_HOME/bin:$JRE_HOME/bin
source /etc/profile 表示使当前配置生效!
进入目录!conf cp zoo_sample.cfg zoo.cfg
进入目录!bin 启动! [root@localhost bin]# ./zkServer.sh start ZooKeeper JMX enabled by default Using config: /myzookeeper/zookeeper-3.4.14/bin/../conf/zoo.cfg Starting zookeeper … STARTED [root@localhost bin]# ./zkServer.sh status ZooKeeper JMX enabled by default Using config: /myzookeeper/zookeeper-3.4.14/bin/../conf/zoo.cfg Mode: standalone
standalone 表示单机模式! ./zkServer.sh start ./zkServer.sh status ./zkServer.sh restart ./zkServer.sh stop
还可以通过ps -ef | grep zookeeper! 查看zk是否启动!
zookeeper 的核心配置文件!
默认读取: zoo.cfg
# 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=/tmp/zookeeper
# 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
默认端口:2181
进入客户端:
./zkCli.sh
两个命令:
1. 查看 ls / [目录]
2. 获取节点数据 get /zookeeper [目录]
[zk: localhost:2181(CONNECTED) 1] get /zookeeper
cZxid = 0x0
ctime = Thu Jan 01 08:00:00 CST 1970
mZxid = 0x0
mtime = Thu Jan 01 08:00:00 CST 1970
pZxid = 0x0
cversion = -1
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 0
numChildren = 1
[zk: localhost:2181(CONNECTED) 2]
如是空,则表示当前节点没有数据!还可以通过dataLength 看!
key = zookeeper value=null;
stat 结构中: 包含节点的数据信息,时间戳等
[zk: localhost:2181(CONNECTED) 2] stat /zookeeper
cZxid = 0x0
ctime = Thu Jan 01 08:00:00 CST 1970
mZxid = 0x0
mtime = Thu Jan 01 08:00:00 CST 1970
pZxid = 0x0
cversion = -1
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 0
numChildren = 1
重点:
ephemeralOwner- 如果是临时节点,这个是znode拥有者的session id。如果不是临时节点则是0x0。
dataLength- znode的数据长度
numChildren - znode子节点数量
案例:
1.创建新的子节点,并添加数据
create [-s] [-e] path data acl
create /java java01
2.获取新创建的子节点
[zk: localhost:2181(CONNECTED) 4] get /java
java01
cZxid = 0xa
ctime = Tue Dec 07 10:59:41 CST 2021
mZxid = 0xa
mtime = Tue Dec 07 10:59:41 CST 2021
pZxid = 0xa
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0 表示持久化节点!
dataLength = 6
numChildren = 0
3.修改创建的子节点内容
[zk: localhost:2181(CONNECTED) 2] set /java html
cZxid = 0xa
ctime = Tue Dec 07 10:59:41 CST 2021
mZxid = 0xd
mtime = Tue Dec 07 11:02:13 CST 2021
pZxid = 0xa
cversion = 0
dataVersion = 1
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 4
numChildren = 0
4.获取修改后的子节点内容
[zk: localhost:2181(CONNECTED) 3] get /java
html
cZxid = 0xa
ctime = Tue Dec 07 10:59:41 CST 2021
mZxid = 0xd
mtime = Tue Dec 07 11:02:13 CST 2021
pZxid = 0xa
cversion = 0
dataVersion = 1
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 4
numChildren = 0
[zk: localhost:2181(CONNECTED) 3] help
ZooKeeper -server host:port cmd args
stat path [watch]
set path data [version]
ls path [watch]
delquota [-n|-b] path
ls2 path [watch]
setAcl path acl
setquota -n|-b val path
history
redo cmdno
printwatches on|off
delete path [version]
sync path
listquota path
rmr path
get path [watch]
create [-s] [-e] path data acl
addauth scheme auth
quit
getAcl path
close
connect host:port
[zk: localhost:2181(CONNECTED) 4]
节点类型:
create [-s] [-e] path data acl
持久化:
当节点创建完成,断开连接,再次连接。这个节点依然存在!
ephemeralOwner = 0x0
create /java java01 默认持久化节点
持久化顺序节点:
create -s /demo01 demo01
临时:
create -e /demo03 demo03 临时节点
create -e -s /demo04 demo04 临时顺序节点
[zk: localhost:2181(CONNECTED) 12] get /demo03
demo03
cZxid = 0x13
ctime = Tue Dec 07 11:23:54 CST 2021
mZxid = 0x13
mtime = Tue Dec 07 11:23:54 CST 2021
pZxid = 0x13
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x100001732c80005 不是 ephemeralOwner = 0x0 则是临时的!
dataLength = 6
numChildren = 0
[zk: localhost:2181(CONNECTED) 13]
当节点创建完成,断开连接,再次连接。这个节点不存在!
删除:
delete 节点:表示这个节点下不能有子节点!
rmr 递归删除!慎用!
四字命令:由四个字符组成的命令! 了解!
要想知道这个服务器是否正在运行!
echo rouk | nc 192.168.200.129 2181 imok
echo conf | nc 192.168.200.129 2181 输出配置信息!
java 客户端链接zk! 必会!
1. 项目依赖配置!
ls /
get /
create /path data
set /path data
rmr
zk 集群:必会! 集群的配置方式: server.N=YYY:A:B N: 那台机器! YYY: 表示ip 地址! A: 主机交互信息的端口号 B: 主从选举端口!
线上配置集群的方式:
server.0=233.34.9.144:2008:6008
server.1=233.34.9.145:2008:6008
server.2=233.34.9.146:2008:6008
server.3=233.34.9.147:2008:6008
要搭建测试的集群方式:测试的案例配置!
server.0=127.0.0.1:2008:6008
server.1=127.0.0.1:2007:6007
server.2=127.0.0.1:2006:6006
server.3=127.0.0.1:2005:6005
集群搭建:zk01 ,zk02 ,zk03
1. 先创建一个zk01的zookeeper!
2. 在zk01 目录下创建相关的文件夹!
mkdir mydata;
mkdir mylog; # 可选!
3. 生成zoo.cfg 配置文件!
dataDir=/opt/zk01/mydata
dataLogDir=/opt/zk01/mylog # 可选!
在配置文件中的最后面添加:
server.1=127.0.0.1:2991:3991
server.2=127.0.0.1:2992:3992
server.3=127.0.0.1:2993:3993
注意修改端口号!
2181--->2191
4. 创建一个myid 的文件 在里面写入机器号
cd /opt/zk01/mydata
vim myid
1
:wq
退出并保存!
使用 ./zkCli.sh -server 127.0.0.1:2191
5. 制作zk02 ,zk03 !
cp -r zk01 zk02
cp -r zk01 zk03
[root@localhost opt]# vi zk02/conf/zoo.cfg
[root@localhost opt]# vi zk02/mydata/myid
[root@localhost opt]# vi zk03/conf/zoo.cfg
[root@localhost opt]# vi zk03/mydata/myid
6. 启动zk01,zk02,zk03
使用脚本启动!
7. 测试!
zk01 2191,zk02 2192,zk03 2193
zk01 从,zk02 主,zk03 从
在 zk01 2191 服务器中创建一个节点,删除一个节点,其他节点数据会同步!
zk02 主 stop!
zk03 主 zk01 从!
此时,需要创建节点!
现在:zk02 复活!
Q1:zk02 还会是主机么?
不会!
Q2:zk02 会同步数据么?
数据会同步!
结论:
1. 无论在主节点,从节点都可以进行数据同步!
2. 主机宕机之后,在复活不会是主机!
3. 主机复活之后,数据会同步!
dubbo:
ssm + dubbo
spring boot + dubbo;
spring boot + spring cloud
介绍:
高性能的RPC 框架!
架构图:
服务提供者:
注册中心: 推荐使用zookeeper!
服务消费者:
监控中心:
注册中心:链接服务提供者,消费者的桥梁!
启动时的容器:spring ---> 音乐学博士出于爱好写的!
注册中心到消费者 这个过程是异步!
消费者根据地址调用服务提者这个过程是同步!
1. 创建一个项目:
spring boot 项目!
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.alibaba.boot</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>0.2.0</version>
</dependency>
</dependencies>
创建接口:common
创建提供者,消费者!
启动的时候,一定要注意关闭本地防火墙! 还有linux 服务器防火墙!
dubbo 使用!
https://dubbo.apache.org/zh/docs/references/configuration/annotation/
两个注解,两个配置,一个启动类!
@Reference
@Service
provider:
consumer:
@EnableDubbo
三个注解,两个配置:
dubbo 高可用!
1. zookeeper注册中心宕机,还可以消费dubbo暴露的服务。
注册中心全部宕掉后,服务提供者和服务消费者仍能通过本地缓存通讯!
2. 负载均衡测试!
Random LoadBalance
随机,按权重设置随机概率。
在一个截面上碰撞的概率高,但调用量越大分布越均匀,而且按概率使用权重后也比较均匀,有利于动态调整提供者权重。
RoundRobin LoadBalance
轮循,基于权重设置轮循比率。
存在慢的提供者累积请求的问题,比如:第二台机器很慢,但没挂,当请求调到第二台时就卡在那,久而久之,所有请求都卡在调到第二台上。
LeastActive LoadBalance
最少活跃调用数,相同活跃数的随机,活跃数指调用前后计数差。
使慢的提供者收到更少请求,因为越慢的提供者的调用前后计数差会越大。
ConsistentHash LoadBalance
一致性 Hash,相同参数的请求总是发到同一提供者。
dubbo 相关配置!
1. 重试次数:
在服务提供者中设置一个睡眠!
dubbo.consumer.timeout=3000 3秒钟超时!
重试3次!
自己在浏览器访问一次!
4次!
@Reference(retries = 3)
2. 版本号:
@Service(version = "1.0.1")
@Service(version = "1.0.2")
@Reference(version = "1.0.2") 指定版本
@Reference(version = "*") 不指定版本 不推荐使用!
dubbo 原理:
RPC:原理
一次完整的RPC调用流程(同步调用,异步另说)如下:
1)服务消费方(client)调用以本地调用方式调用服务;
2)client stub接收到调用后负责将方法、参数等组装成能够进行网络传输的消息体;
3)client stub找到服务地址,并将消息发送到服务端;
4)server stub收到消息后进行解码;
5)server stub根据解码结果调用本地的服务;
6)本地服务执行并将结果返回给server stub;
7)server stub将返回结果打包成消息并发送至消费方;
8)client stub接收到消息,并进行解码;
9)服务消费方得到最终结果。
RPC框架的目标就是要2~8这些步骤都封装起来,这些细节对用户来说是透明的,不可见的。
config 配置层:对外配置接口,以 ServiceConfig, ReferenceConfig 为中心,可以直接初始化配置类,也可以通过 spring 解析配置生成配置类
proxy 服务代理层:服务接口透明代理,生成服务的客户端 Stub 和服务器端 Skeleton, 以 ServiceProxy 为中心,扩展接口为 ProxyFactory
registry 注册中心层:封装服务地址的注册与发现,以服务 URL 为中心,扩展接口为 RegistryFactory, Registry, RegistryService
cluster 路由层:封装多个提供者的路由及负载均衡,并桥接注册中心,以 Invoker 为中心,扩展接口为 Cluster, Directory, Router, LoadBalance
monitor 监控层:RPC 调用次数和调用时间监控,以 Statistics 为中心,扩展接口为 MonitorFactory, Monitor, MonitorService
protocol 远程调用层:封装 RPC 调用,以 Invocation, Result 为中心,扩展接口为 Protocol, Invoker, Exporter
exchange 信息交换层:封装请求响应模式,同步转异步,以 Request, Response 为中心,扩展接口为 Exchanger, ExchangeChannel, ExchangeClient, ExchangeServer
transport 网络传输层:抽象 mina 和 netty 为统一接口,以 Message 为中心,扩展接口为 Channel, Transporter, Client, Server, Codec
serialize 数据序列化层:可复用的一些工具,扩展接口为 Serialization, ObjectInput, ObjectOutput, ThreadPool
```