Dubbo+Zookeeper服务器实现集群(Dubbo第三炮)

说明:大概是3年前在一个Saas平台中接触到dubbo,此博文是复习笔记,作为分享和交流之用。阅读此篇博文必须先阅读笔者的另一篇博文"Dubbo框架搭建服务发布与订阅(Dubbo第二炮)",因为它们紧密联系。(此演示以为windows环境进行演示,笔者感觉zookeeper部署在linux上还简单一些,相对于windows毕竟linux提供太多好用的工具了)…

演示内容如下:
Dubbo+Zookeeper服务器实现集群(Dubbo第三炮)_第1张图片

 @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   (敲回车键)
  1. 连接Zookeeper服务器
    windows环境中,打开cmd进入zookeeper安装目录\bin目录下,输入以下命令即可连接zookeeper服务器
    D:\zookeeper-3.4.12\bin>zkCli.cmd -server localhost:2181
    语法:zkCli.cmd -server IP:端口
    在屏幕上的输出信息中可以看到:Welcome to Zookeeper! 表示成功连接服务器。接着按回车键,显示如下图:

Dubbo+Zookeeper服务器实现集群(Dubbo第三炮)_第2张图片

2 简单管理zookeeper服务器

客户端成功连接zookeeper服务器后,输入help(windows系统中),显示zookeeper使用命令:
Dubbo+Zookeeper服务器实现集群(Dubbo第三炮)_第3张图片

接着使用以下命令来管理znode(zookeeper中的概念,节点), 比如:
1. 查询列表 ls /
2. 创建create /zk “testData1”
3. 获取get /zk
4. 修改 set /zk “lovezookeeper” , 把testData1修改成lovezookeeper
5. 删除 delete /zk
6. 等操作

Dubbo+Zookeeper服务器实现集群(Dubbo第三炮)_第4张图片

Dubbo+Zookeeper服务器实现集群(Dubbo第三炮)_第5张图片

Dubbo+Zookeeper服务器实现集群(Dubbo第三炮)_第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,如下图:

Dubbo+Zookeeper服务器实现集群(Dubbo第三炮)_第7张图片

4.2配置每个zookeeper服务器
以zookeeper1为例,配置D:\zookeepers\zookeeper1\zookeeper-3.4.12\conf\ zoo.cfg,详细配置和说明如下图:

Dubbo+Zookeeper服务器实现集群(Dubbo第三炮)_第8张图片

配置好zoo.cfg后,创建相应的快照目录和日志目录,如下图

Dubbo+Zookeeper服务器实现集群(Dubbo第三炮)_第9张图片

然后在目录 E:\test_dubbo_cluster\zookeeper1\data中创建myid文件
以zookeeper1为例(myid中的内容为1,zookeeper2中同样创建myid文件且内容为2,而zookeeper3也要创建myid文件且内容为3),如下图:
Dubbo+Zookeeper服务器实现集群(Dubbo第三炮)_第10张图片

4.3 启动每台zookeeper服务器
以启动zookeeper1服务器为例,进入安装目录: D:\zookeepers\zookeeper1\zookeeper-3.4.12\bin(这里是笔者的安装目录,读者根据自己的而定)
Dubbo+Zookeeper服务器实现集群(Dubbo第三炮)_第11张图片
4.4 选举和查看Leader
成功启动三台zookeeper服务器的过程中,集群时进行选举Leader,如何查
看哪台zookeeper服务器是leader呢?这里笔者以windows系统且为一台机
器上安装三个zookeeper服务器为例(伪集群),通过看每台zookeeper服务器
的输出信息,笔者发现myid为2的zookeeper服务器为leader即zookeeper2
为leader,而zookeeper1和zookeeper3为follower,看下图信息:
Dubbo+Zookeeper服务器实现集群(Dubbo第三炮)_第12张图片

当然咯,如果是在linux系统中进行zookeeper集群,查看哪台zookeeper是leader或follower是非常简单的,进行每台zookeeper服务器的安装目录,
然后再进入bin目录,输入命令:./zkServer.sh status
其中输出信息中Mode:leader表示leader,而Mode:follower表示flower,贴一张windows下采用”瑞士军刀”来查看zookeeper是leader还是flower的图(因为zkServer.cmd 不能使用status选项来查看状态,所以这里使用"瑞士军刀"来查看)

Dubbo+Zookeeper服务器实现集群(Dubbo第三炮)_第13张图片

遇到一个问题提一下,就是启动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即可解决。

Dubbo+Zookeeper服务器实现集群(Dubbo第三炮)_第14张图片

解决方案如下图:
把zookeeper1,zookeeper2,zookeeper3服务器中的zoo.cfg集群配置原来的是这样的
Dubbo+Zookeeper服务器实现集群(Dubbo第三炮)_第15张图片

改成这样:

Dubbo+Zookeeper服务器实现集群(Dubbo第三炮)_第16张图片
4.5 在java代码中配置集群
以笔者的博文 ”Dubbo框架搭建服务发布与订阅(Dubbo第二炮)” 为例,只要在user-provider/pom.xml配置文件和user-consumer/pom.xml文件中
把原来的单个zookeeper服务器的配置改成集群配置即可,如下图:

Dubbo+Zookeeper服务器实现集群(Dubbo第三炮)_第17张图片

Dubbo+Zookeeper服务器实现集群(Dubbo第三炮)_第18张图片
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即可启动),如下图:

Dubbo+Zookeeper服务器实现集群(Dubbo第三炮)_第19张图片
同理,启动user-consumer工程访问user-provider工程提供的服务,如下
图:

Dubbo+Zookeeper服务器实现集群(Dubbo第三炮)_第20张图片

这样,java工程访问registry(zookeeper服务器)时,访问的就是zookeeper群,具体访问哪一台
zookeeper由dubbo和zookeeper的算法来决定。   OK就记录到此,匆忙写作,有落掉或有问题的请指
证。
后续博文:
dubbo第5炮将演示与MQ集成,
dubbo第6炮准备演示与redis集成……

你可能感兴趣的:(java,dubbo框架)