- systemctl disable firewalld:禁止firewall开机启动(禁用防火墙服务)。
- systemctl stop firewalld.service:停止firewall,只是临时关闭了防火墙,当重启操作系统后,防火墙服务还是会再次启动。
查看防火墙状态。
[root@localhost bin]# systemctl status firewalld
启动第1台Zookeeper服务器。
[root@localhost bin]# ./zkServer.sh start
ZooKeeper JMX enabled by default
Using config: /opt/zookeeper/bin/../conf/zoo.cfg
Starting zookeeper ... STARTED
查看Zookeeper状态。
[root@localhost bin]# ./zkServer.sh status
ZooKeeper JMX enabled by default
Using config: /opt/zookeeper/bin/../conf/zoo.cfg
Client port found: 2181. Client address: localhost.
Error contacting service. It is probably not running.
注意:因为没有超过半数以上的服务器被启动,所以第一台服务器启动后查看服务状态,发现集群失败 (如果防火墙没有关闭,也会导致集群失败)。
使用同样的方式启动第2台和第3台Zookeeper服务器。
- 查看第1台的状态:Mode: follower
- 查看第2台的状态:Mode: leader
- 查看第3台的状态:Mode: follower
**二.**客户端命令行操作
1.客户端命令
启动客户端。
[root@localhost bin]# ./zkCli.sh
显示所有操作命令。
[zk: localhost:2181(CONNECTED) 0] help
查看当前ZNode中所包含的内容。
[zk: localhost:2181(CONNECTED) 1] ls /
[zookeeper]
查看当前节点详细数据。
[zk: localhost:2181(CONNECTED) 2] ls -s /
[zookeeper]
cZxid = 0x0
ctime = Wed Dec 31 19:00:00 EST 1969
mZxid = 0x0
mtime = Wed Dec 31 19:00:00 EST 1969
pZxid = 0x0
cversion = -1
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 0
numChildren = 1
当前节点参数的介绍见下:
参数名 | 描述 |
cZxid | 创建节点的事务。每次修改ZooKeeper状态都会收到一个zxid形式的时间戳,也就是ZooKeeper事务ID。事务ID是ZooKeeper中所有修改总的次序。每个修改都有唯一的zxid,如果zxid1小于zxid2,那么zxid1在zxid2之前发生。 |
ctime | 被创建的毫秒数(从1970年开始) |
mZxid | 最后更新的事务zxid |
mtime | 最后修改的毫秒数(从1970年开始) |
pZxid | 最后更新的子节点zxid |
cversion | 创建版本号,子节点修改次数 |
dataVersion | 数据变化版本号 |
aclVersion | 权限版本号 |
ephemeralOwner | 如果是临时节点,这个是znode拥有者的session id。如果不是临时节点则是0 |
dataLength | 数据长度 |
numChildren | 子节点数 |
2.节点操作
在根目录下,创建中国和美国两个节点。
create /cn
create /us
在根目录下,创建俄罗斯节点,并保存“普京”数据到节点上。
create /rus 'pujing'
获得节点的值。
get /rus
多级创建节点:
- 在日本节点下,创建东京节点并保存数据“热”。
- jp必须提前创建好,否则将报错“节点不存在”。
# 提示:Node does not exist: /jp/Tokyo
create /jp/Tokyo 'hot'
# 因此需要先创建jp节点,然后再在jp下创建Tokyo节点
create jp
create /jp/Tokyo 'hot'
# 获取Tokyo节点的值
get /jp/Tokyo
创建短暂节点。短暂节点创建成功后, 使用quit命令退出客户端,然后再重新连接到客户端,发现短暂节点自动消失。
# 参数-e用于标注创建的节点是短暂节点
create -e /uk
ls /
quit
ls /
创建带序号的节点。
- 在中国cn下,创建3个city顺序编号的节点。
- 如果原来没有序号节点,序号从0开始递增。
- 如果原节点下已有2个节点,则再排序时从2开始,以此类推。
# 参数-s用于标注创建的节点是顺序编号目录节点
create -s /cn/city # 执行三次
ls /cn
[city0000000000, city0000000001, city0000000002]
修改节点数据值。
set /jp/Tokyo "too hot"
get /jp/Tokyo
监听节点的值变化或子节点变化(路径变化)。
(1) 在server3主机上注册监听/us节点的数据变化。
[root@localhost bin]# ./zkCli.sh
[zk: locahost:2181(CONNECTED) 0] addWatch /us
(2) 在Server1主机上修改/us的数据。
set /us 'telangpu'
(3) Server3会立刻响应。
WATCHER::
WatchedEvent state:SyncConnected type:NodeDataChanged
(4) 如果在Server1的/us下面创建子节点NewYork。
br
(5) Server3会立刻响应。
WATCHER::
WatchedEvent state:SyncConnected type:NodeCreatedpath:/us/NewYork
删除节点。
delete /us/NewYork
递归删除节点(非空节点,节点下有子节点)。
deleteall /cn
说明:不仅删除/cn,而且/cn下的所有子节点也随之删除。
三.Zookeeper集群实战案例
1.项目环境搭建
使用IDEA创建一个项目名称为【test_zookeeper】的Maven工程。
在项目的pom.xml文件中添加依赖。
<dependencies>
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.8.0</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.8.2</version>
</dependency>
</dependencies>
在resources下创建log4j.properties。
log4j.rootLogger=INFO, stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m%n
log4j.appender.logfile=org.apache.log4j.FileAppender
log4j.appender.logfile.File=target/zk.log
log4j.appender.logfile.layout=org.apache.log4j.PatternLayout
log4j.appender.logfile.layout.ConversionPattern=%d %p [%c] - %m%n
2.创建ZooKeeper客户端
在项目的src/test/java目录下创建com.cy.test包,并在该包下创建ZooKeeperTests测试类。
package com.cy.test;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooKeeper;
import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
public class ZooKeeperTests {
// 集群IP
private String connectString = "192.168.230.131:2181,192.168.230.132:2181,192.168.230.133:2181";
/*
* session超时60秒:session超时不能设置太小,因为连接Zookeeper和加载集群环境会因为性能原因延迟略高;
* 如果时间太小,还没有创建好客户端,就开始操作节点,会报错的
/
private int sessionTimeout = 60 1000;
private ZooKeeper zooKeeperClient;
@Before
public void init() throws IOException {
// 创建监听器
Watcher watcher = new Watcher() {
@Override
public void process(WatchedEvent watchedEvent) {
System.out.println("监听事件...");
}
};
zooKeeperClient = new ZooKeeper(connectString, sessionTimeout, watcher);
}
}
3.创建节点
3.1 ACL****对象介绍
一个ACL对象就是一个Id和permission对。
- 表示哪个/哪些范围的Id(Who)在通过了怎样的鉴权(How)之后,就允许进行那些操作(What)。即Who How What。
- permission(What)就是一个int表示的位码,每一位代表一个对应操作的允许状态。
- 类似Linux的文件权限,不同的是共有5种操作:CREATE、READ、WRITE、DELETE、ADMIN(对应更改ACL的权限)。
参数 | 描述 |
OPEN_ACL_UNSAFE | 创建开放节点,允许任意操作(用的最多,其余的权限用的很少) |
READ_ACL_UNSAFE | 创建只读节点 |
CREATOR_ALL_ACL | 创建者才有全部权限 |
3.2****创建节点实现
在ZooKeeperTests测试类中添加创建节点的createNode()方法。
@Before
// @Test
public void init() throws IOException {
// ...
}
@Test
public void createNode() throws InterruptedException, KeeperException {
/*
* 参数1:要创建的节点的路径
* 参数2:节点数据
* 参数3:节点权限
* 参数4:节点的类型
*/
String nodeCreated = zooKeeperClient.create("/yuanxin", "laoyuan".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
System.out.println("nodeCreated = " + nodeCreated);
}
运行createNode()方法将看到如下的日志输入。
...
监听事件...
06:41:32.749 [main-SendThread(192.168.230.133:2181)] DEBUG org.apache.zookeeper.ClientCnxn - Reading reply session id: 0x300003339b10000, packet:: clientPath:null serverPath:null finished:false header:: 1,1 replyHeader:: 1,8589934594,0 request:: '/yuanxin,#6c616f7975616e,v{s{31,s{'world,'anyone}}},0 response:: '/yuanxin
nodeCreated = /yuanxin
**3.**3 Session超时异常
如果createNode()方法运行出现ClientCnxn$SessionTimeoutException异常。
org.apache.zookeeper.ClientCnxn$SessionTimeoutException: Client session timed out, have not heard from server in 60111ms for session id 0x0
at org.apache.zookeeper.ClientCnxn$SendThread.run(ClientCnxn.java:1230)
org.apache.zookeeper.KeeperException$ConnectionLossException: KeeperErrorCode = ConnectionLoss for /yuanxin
at org.apache.zookeeper.KeeperException.create(KeeperException.java:102)
at org.apache.zookeeper.KeeperException.create(KeeperException.java:54)
at org.apache.zookeeper.ZooKeeper.create(ZooKeeper.java:1733)
at com.cy.TestZookeeper.createNode(TestZookeeper.java:42)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
...
针对Session超时异常问题,解决方案见下:
- 增加连接时间
- 检查集群IP是否编写正确
- 关闭防火墙:systemctl stop firewalld
4.查询节点的值
在ZooKeeperTests测试类中添加查询节点的值find()方法。
@Test
public void find() throws InterruptedException, KeeperException {
// 路径不存在时会报错
byte[] data = zooKeeperClient.getData("/yuanxin", false, new Stat());
String content = new String(data);
System.out.println("content = " + content);
}
5.修改节点的值
在ZooKeeperTests测试类中添加更新节点的值update()方法。
@Test
public void update() throws InterruptedException, KeeperException {
// 先查看节点详情(ls -s /),获得dataVersion = 0的取值作为setData()方法的第三个参数
Stat stat = zooKeeperClient.setData("/yuanxin", "xinge".getBytes(), 0);
// Stat对象输出的内容表示节点的详情信息
System.out.println(stat);
}
6.删除节点
学习路线:
这个方向初期比较容易入门一些,掌握一些基本技术,拿起各种现成的工具就可以开黑了。不过,要想从脚本小子变成黑客大神,这个方向越往后,需要学习和掌握的东西就会越来越多以下是网络渗透需要学习的内容:
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!