说明:大概是3年前在一个Saas平台中接触到dubbo,此博文是复习笔记,作为分享和交流之用。阅读此篇博文必须先阅读笔者的另一篇博文"Dubbo框架搭建服务发布与订阅(Dubbo第二炮)",因为它们紧密联系。(此演示以为windows环境进行演示,笔者感觉zookeeper部署在linux上还简单一些,相对于windows毕竟linux提供太多好用的工具了)…
@author拈花为何不一笑。
1 Zookeeper服务器基本操作
(1.1)配置文件说明:
编写配置文件
D:\zookeeper-3.4.12\conf目录下,把默认的zoosample.cfg复制重命名为zoo.cfg, 配置文件zoo.cfg需要在每台服务器中都要编写,以下是一个zookeeper集群配置文件的样本:
# Filename zoo.cfg
tickTime=2000
dataDir=/home/zookeeper/data
clientPort=2181
initLimit=5
syncLimit=2
server.1=202.115.36.251:2888:3888
server.2=202.115.36.241:2888:3888
server.3=202.115.36.242:2888:3888
此配置文件属性项说明:
(1)tickTime: Zookeeper服务器之间或客户端与服务器之间维持心跳的时间间隔,单位毫秒
(2) initLimit: Zookeeper 集群时leader与follower服务器之间初始化连接时,维持心跳的时
间长度,超过这个时间服务器之间的连接则失败,单位毫秒(多台zookeeper服务器集群时选
举一台作为leader其它的作为follower)
(3) syncLimit: Leader 与 Follower 之间发送消息,请求和应答时间长度。计算方式比如:tickTime=2000(毫秒) syncLimit =2 ,则syncLimit = 2 * 2000 =4秒,initLimit计算同
理。
(4)dataDir:存储快照的目录。不要将/tmp用于存储数据目录. 默认情况下,Zookeeper 将写数据的日志文件也保存在这个目录里。
(5) dataLogDir:日志文件存放目录
(6)clientPort:Zookeeper服务器开放给客户端使用的端口号
Zookeeper中几个端口号说明
(a) zookeeper服务器中的集群配置文件
1. # 服务器开放给客户端使用的端口
2. clientPort=2181
3. #Clusters集群,下面配置格式
4. #servier.序号=IP:P1:P2
5. #说明:
6. # 序号用数字来表示,在集群时用来标识是哪一台zookeeper服务器
7. # P1表示Zookeeper服务器之间正常交换信息时使用的端口,这个有点类似redis中主从复制
8. # p2表示选举Leader时使用的端口
9. #每台机器上Zookeeper服务器都分别有自己设置的端口。
10.
11. #如果是伪集群要求每台zookeeper服务器:server.1 server.2 和server.3的P1,P2不能相同
12. server.1=192.168.179.129:2888:3888
13. server.2=192.168.179.129:2889:3889
14. server.3=192.168.179.129:2890:3890
15.
16. #如果是真实的集群(非伪集群),注意看每台zookeeper服务器对应的P1,P2是可以相同的,因为这些#zookeeper服务器都不同的机器上。配置如下:
17. server.1=192.168.179.129:2888:3888
18. server.1=192.168.179.130:2888:3888
19. server.1=192.168.179.131:2888:3888
(b)java代码中的集群配置文件
1. #本机伪集群配置,这里的端口是指clientPort
2.
不集群时的java代码中user-provider/application-provider.xml中的配置
(1.2) 启动zookeeper服务器
windows环境中,打开cmd进入zookeeper安装目录\bin目录下,输入以下命令即可
启动zookeeper服务器
D:\zookeeper-3.4.12\bin> zkServer.cmd (敲回车键)
2 简单管理zookeeper服务器
客户端成功连接zookeeper服务器后,输入help(windows系统中),显示zookeeper使用命令:
接着使用以下命令来管理znode(zookeeper中的概念,节点), 比如:
1. 查询列表 ls /
2. 创建create /zk “testData1”
3. 获取get /zk
4. 修改 set /zk “lovezookeeper” , 把testData1修改成lovezookeeper
5. 删除 delete /zk
6. 等操作
3 使用zookeeper提供的java API操作zookeeper服务器
通过java代码来与服务器交互(操作服务器,类似于java通过jdbc来操作DB)
Java事例代码如下(所需要jar包在zookeeper安装目录下,
具体位置D:\zookeeper-3.4.12\ zookeeper-3.4.12.jar,这个类似于tomcat服务器):
package com.it.qh.dataControl.demo;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooDefs.Ids;
import org.apache.zookeeper.ZooKeeper;
/**
* 通过java代码来与Zookeeper服务器交互(操作服务器,类似于java通过jdbc来操作DB)
* 所需要jar包在zookeeper安装目录下,
* 笔者机器中zookeeper的jar包位置D:\zookeeper-3.4.12\zookeeper-3.4.12.jar,
*
*/
public class Java2ZookeeperServer {
public static void main(String[] args) throws Exception {
// 创建一个与服务器的连接
ZooKeeper zk = new ZooKeeper(
"192.168.179.129:2181,192.168.179.130:2181,192.168.179.131:2181",
1000 * 60, new Watcher() {
// 监控所有被触发的事件
public void process(WatchedEvent event) {
System.out.println("已经触发了" + event.getType() + "事件!");
}
});
// 创建一个目录节点
zk.create("/testRootPath", "testRootData".getBytes(),
Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
// 创建一个子目录节点
zk.create("/testRootPath/testChildPathOne", "testChildDataOne"
.getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
System.out.println(new String(zk.getData("/testRootPath", false, null)));
// 取出子目录节点列表
System.out.println(zk.getChildren("/testRootPath", true));
// 修改子目录节点数据
zk.setData("/testRootPath/testChildPathOne", "modifyChildDataOne"
.getBytes(), -1);
System.out.println("目录节点状态:[" + zk.exists("/testRootPath", true) + "]");
// 创建另外一个子目录节点
zk.create("/testRootPath/testChildPathTwo", "testChildDataTwo"
.getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
System.out.println(new String(zk.getData("/testRootPath/testChildPathTwo", true, null)));
// 删除子目录节点
zk.delete("/testRootPath/testChildPathTwo", -1);
zk.delete("/testRootPath/testChildPathOne", -1);
// 删除父目录节点
zk.delete("/testRootPath", -1);
// 关闭连接
zk.close();
}
}
4.zookeeper集群
4.1安装zookeeper服务器
安装三个zookeeper服务器(其实是压缩包,直接解压复制三份即可):
zookeeper1,zookeeper2,zookeeper3,如下图:
4.2配置每个zookeeper服务器
以zookeeper1为例,配置D:\zookeepers\zookeeper1\zookeeper-3.4.12\conf\ zoo.cfg,详细配置和说明如下图:
配置好zoo.cfg后,创建相应的快照目录和日志目录,如下图
然后在目录 E:\test_dubbo_cluster\zookeeper1\data中创建myid文件
以zookeeper1为例(myid中的内容为1,zookeeper2中同样创建myid文件且内容为2,而zookeeper3也要创建myid文件且内容为3),如下图:
4.3 启动每台zookeeper服务器
以启动zookeeper1服务器为例,进入安装目录: D:\zookeepers\zookeeper1\zookeeper-3.4.12\bin(这里是笔者的安装目录,读者根据自己的而定)
4.4 选举和查看Leader
成功启动三台zookeeper服务器的过程中,集群时进行选举Leader,如何查
看哪台zookeeper服务器是leader呢?这里笔者以windows系统且为一台机
器上安装三个zookeeper服务器为例(伪集群),通过看每台zookeeper服务器
的输出信息,笔者发现myid为2的zookeeper服务器为leader即zookeeper2
为leader,而zookeeper1和zookeeper3为follower,看下图信息:
当然咯,如果是在linux系统中进行zookeeper集群,查看哪台zookeeper是leader或follower是非常简单的,进行每台zookeeper服务器的安装目录,
然后再进入bin目录,输入命令:./zkServer.sh status
其中输出信息中Mode:leader表示leader,而Mode:follower表示flower,贴一张windows下采用”瑞士军刀”来查看zookeeper是leader还是flower的图(因为zkServer.cmd 不能使用status选项来查看状态,所以这里使用"瑞士军刀"来查看)
遇到一个问题提一下,就是启动zookeeper服务器时报错误信息,如下:
"java.net.BindException: Cannot assign requested address: JVM_Bind"
这个笔者netstat -nao 查看到3888端口号被192.168.0.102建立了连接,当时吓我一跳,为什么呢?
因为笔者最近正在玩"瑞士军刀"在做"渗透实验",而本机昨天的ip是192.168.0.100"以为电脑被黑了...
立刻沉静下来。
心想:不对,局域网是笔者自己搭建的,这台192.168.0.102的机器不可能连接到笔者的局域网中来,如
果存在,那么现实中,笔者就可以排查出是谁连接到笔者的局域网了...
接着ipconfig 一看,原来是自己的ip地址,因为笔者设置的是局域网自动分配ip的,昨天是192.168.0.100,
今天重新分配了ip地址为192.168.0.102...哇艹!
上图分析图,解决方案把集群的ip从昨天的192.168.0.100改成192.168.0.102即可解决。
解决方案如下图:
把zookeeper1,zookeeper2,zookeeper3服务器中的zoo.cfg集群配置原来的是这样的
改成这样:
4.5 在java代码中配置集群
以笔者的博文 ”Dubbo框架搭建服务发布与订阅(Dubbo第二炮)” 为例,只要在user-provider/pom.xml配置文件和user-consumer/pom.xml文件中
把原来的单个zookeeper服务器的配置改成集群配置即可,如下图:
5.dubbo框架访问集群的zookeeper
5.1启动zookeeper集群服务器
通过三台zookeeper服务器(zookeeper1,zookeeper2,zookeeper3)
进行集群(这里指的是在一台机器上使用伪集群,其实真实集群原理跟这个是一样的,linux上玩也很简单,这里笔者就不演示linux中搭建真实zookeeper集群,如果你遇到问题可以与本人交流!!!)
启动zookeeper1,zookeeper2,zookeeper3三个zookeeper服务器让它们根据选举算法进行leader的选举。
5.2 启动java工程
说明,此博文联系着笔者的一篇博文” Dubbo框架搭建服务发布与订阅(Dubbo第二炮)”,下面谈到的java工程就是在该博文中进行演示的。
接着启动我们的工程user-provider(运行
UserProvider2Application.java即可启动),如下图:
同理,启动user-consumer工程访问user-provider工程提供的服务,如下
图:
这样,java工程访问registry(zookeeper服务器)时,访问的就是zookeeper群,具体访问哪一台
zookeeper由dubbo和zookeeper的算法来决定。 OK就记录到此,匆忙写作,有落掉或有问题的请指
证。
后续博文:
dubbo第5炮将演示与MQ集成,
dubbo第6炮准备演示与redis集成……