- 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 ticktickTime=2000# The number of ticks that the initial# synchronization phase can takeinitLimit=10# The number of ticks that can pass between# sending a request and getting an acknowledgementsyncLimit=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 connectclientPort=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 /zookeepercZxid = 0x0ctime = Thu Jan 01 08:00:00 CST 1970mZxid = 0x0mtime = Thu Jan 01 08:00:00 CST 1970pZxid = 0x0cversion = -1dataVersion = 0aclVersion = 0ephemeralOwner = 0x0dataLength = 0numChildren = 1[zk: localhost:2181(CONNECTED) 2]如是空,则表示当前节点没有数据!还可以通过dataLength 看!key = zookeeper value=null;stat 结构中: 包含节点的数据信息,时间戳等[zk: localhost:2181(CONNECTED) 2] stat /zookeepercZxid = 0x0ctime = Thu Jan 01 08:00:00 CST 1970mZxid = 0x0mtime = Thu Jan 01 08:00:00 CST 1970pZxid = 0x0cversion = -1dataVersion = 0aclVersion = 0ephemeralOwner = 0x0dataLength = 0numChildren = 1重点:ephemeralOwner- 如果是临时节点,这个是znode拥有者的session id。如果不是临时节点则是0x0。dataLength- znode的数据长度numChildren - znode子节点数量案例:1.创建新的子节点,并添加数据create [-s] [-e] path data aclcreate /java java012.获取新创建的子节点[zk: localhost:2181(CONNECTED) 4] get /javajava01cZxid = 0xactime = Tue Dec 07 10:59:41 CST 2021mZxid = 0xamtime = Tue Dec 07 10:59:41 CST 2021pZxid = 0xacversion = 0dataVersion = 0aclVersion = 0ephemeralOwner = 0x0 表示持久化节点!dataLength = 6numChildren = 03.修改创建的子节点内容[zk: localhost:2181(CONNECTED) 2] set /java htmlcZxid = 0xactime = Tue Dec 07 10:59:41 CST 2021mZxid = 0xdmtime = Tue Dec 07 11:02:13 CST 2021pZxid = 0xacversion = 0dataVersion = 1aclVersion = 0ephemeralOwner = 0x0dataLength = 4numChildren = 04.获取修改后的子节点内容[zk: localhost:2181(CONNECTED) 3] get /javahtmlcZxid = 0xactime = Tue Dec 07 10:59:41 CST 2021mZxid = 0xdmtime = Tue Dec 07 11:02:13 CST 2021pZxid = 0xacversion = 0dataVersion = 1aclVersion = 0ephemeralOwner = 0x0dataLength = 4numChildren = 0[zk: localhost:2181(CONNECTED) 3] helpZooKeeper -server host:port cmd argsstat path [watch]set path data [version]ls path [watch]delquota [-n|-b] pathls2 path [watch]setAcl path aclsetquota -n|-b val pathhistoryredo cmdnoprintwatches on|offdelete path [version]sync pathlistquota pathrmr pathget path [watch]create [-s] [-e] path data acladdauth scheme authquitgetAcl pathcloseconnect host:port[zk: localhost:2181(CONNECTED) 4]节点类型:create [-s] [-e] path data acl持久化:当节点创建完成,断开连接,再次连接。这个节点依然存在!ephemeralOwner = 0x0create /java java01 默认持久化节点持久化顺序节点:create -s /demo01 demo01临时:create -e /demo03 demo03 临时节点create -e -s /demo04 demo04 临时顺序节点[zk: localhost:2181(CONNECTED) 12] get /demo03demo03cZxid = 0x13ctime = Tue Dec 07 11:23:54 CST 2021mZxid = 0x13mtime = Tue Dec 07 11:23:54 CST 2021pZxid = 0x13cversion = 0dataVersion = 0aclVersion = 0ephemeralOwner = 0x100001732c80005 不是 ephemeralOwner = 0x0 则是临时的!dataLength = 6numChildren = 0[zk: localhost:2181(CONNECTED) 13]当节点创建完成,断开连接,再次连接。这个节点不存在!删除:delete 节点:表示这个节点下不能有子节点!rmr 递归删除!慎用!四字命令:由四个字符组成的命令! 了解!要想知道这个服务器是否正在运行!echo rouk | nc 192.168.200.129 2181 imokecho conf | nc 192.168.200.129 2181 输出配置信息!java 客户端链接zk! 必会!1. 项目依赖配置!ls /get /create /path dataset /path datarmr
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
```
