为啥dubbo使用ZkClient作为zookeeper的客户端

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了为啥dubbo使用ZkClient作为zookeeper的客户端相关的知识,希望对你有一定的参考价值。

参考技术A 一、先看看zookeeper本身自带的客户端的问题。
1 ) ZooKeeper的Watcher是一次性的,用过了需要再注册;
2 ) session的超时后没有自动重连,生产环境中如果网络出现不稳定情况,那么这种情况出现的更加明显;
3) 没有领导选举机制,集群情况下可能需要实现stand by,一个服务挂了,另一个需要接替的效果;
4) 客户端只提供了存储byte数组的接口,而项目中一般都会使用对象。
5 )客户端接口需要处理的异常太多,并且通常,我们也不知道如何处理这些异常。

二、I0Itec这个zookeeper客户端基本上解决了上面的所有问题,主要有以下特性:
1) 提供了zookeeper重连的特性------能够在断链的时候,重新建立连接,无论session失效与否.
2) 持久的event监听器机制------ ZKClient框架将事件重新定义分为了stateChanged、znodeChanged、dataChanged三种情况,用户可以注册这三种情况下的监听器(znodeChanged和dataChanged和路径有关),而不是注册Watcher。
3) zookeeper异常处理-------zookeeper中繁多的Exception,以及每个Exception所需要关注的事情各有不同,I0Itec简单的做了封装.
4) data序列化------简单的data序列化.(Serialzer/Deserialzer)
5)有默认的领导选举机制

三、请注意使用I0Itect-zkClient暂时有几个方法仍需要重写:
1) create方法 : 创建节点时,如果节点已经存在,仍然抛出NodeExistException,可是我期望它不在抛出此异常.
2) retryUtilConnected : 如果向zookeeper请求数据时(create,delete,setData等),此时链接不可用,那么调用者将会被阻塞直到链接建立成功;不过我仍然需要一些方法是非阻塞的,如果链接不可用,则抛出异常,或者直接返回.
3) create方法 : 创建节点时,如果节点的父节点不存在,我期望同时也要创建父节点,而不是抛出异常.
4) data监测: 我需要提供一个额外的功能来补充watch的不足,开启一个线程,间歇性的去zk server获取指定的path的data,并缓存起来..归因与watch可能丢失,以及它不能持续的反应znode数据的每一次变化,所以只能手动去同步获取。

dubbo框架----初探索-配置

使用框架版本

dubbo-2.5.3

spring-4.2.1.RELEASE

jdk-1.8

tomcat-8.0

zookeeper-3.3.6

 

Dubbo与Zookeeper、SpringMVC整合使用

第一步:在Linux上安装Zookeeper

(1)下载Zookeeper-3.4.6.tar.gz  地址http://www.apache.org/dist/zookeeper/

(2) 我们放到Linux下的一个文件夹,然后解压: 

(3)然后在对应的zookeeper-3.4.6/conf 下有一个文件zoo_sample.cfg的这个文件里面配置了监听客户端连接的端口等一些信息,Zookeeper 在启动时会找zoo.cfg这个文件作为默认配置文件,所以我们复制一个名称为zoo.cfg的文件

 我们查看一下这个文件的里面的一些配置信息,如图所示:

 (4)启动Zookeeper 的服务,如图所示:

 

第二步:配置dubbo-admin的管理页面,方便我们管理页面

    (1)下载dubbo-admin-2.4.5.war包,在Linux的tomcat部署,先把dubbo-admin-2.4.1放在tomcat的webapps/ROOT下,然后进行解压:

   dubbo 源代码地址:https://github.com/alibaba/dubbo 

 关于dubbo在jdk 1.8 环境下打包,报错,参考:https://github.com/alibaba/dubbo/issues/50

   提供dubbo-admin-2.5.4.war 访问地址:http://share.weiyun.com/006e0a25a056dcbdc0664841ab9e5feb

  初次访问需要用户名:root;密码:root;

 

 第三步:SpringMVC与Dubbo的整合,这边使用的Maven的管理项目

  我们先开发服务注册的,就是提供服务,项目结构如图所示:

    (1)test-maven-api项目加入了一个服务接口,代码如下:

package com.dubbo.registry.service;
public interface TestRegistryService {
   public String hello(String name);
}

  (2)test-maven-console 工程在pom.xml加入Dubbo和Zookeeper的jar包、引用test-maven-api的jar包,代码如下:

		<dependency>
			<groupId>cn.test</groupId>
			<artifactId>test-maven-api</artifactId>
			<version>0.0.1-SNAPSHOT</version>
		</dependency>
		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>dubbo</artifactId>
			<version>2.5.3</version>
			<exclusions>
				<exclusion>
					<groupId>org.springframework</groupId>
					<artifactId>spring</artifactId>
				</exclusion>
			</exclusions>
		</dependency>
		<dependency>
			<groupId>org.apache.zookeeper</groupId>
			<artifactId>zookeeper</artifactId>
			<version>3.4.6</version>
		</dependency>
		<dependency>
			<groupId>com.github.sgroschupf</groupId>
			<artifactId>zkclient</artifactId>
			<version>0.1</version>
		</dependency>

  具体的实现Java代码为:

package com.dubbo.registry.serviceImpl;

import org.springframework.stereotype.Service;

import com.dubbo.registry.service.TestRegistryService;

@Service("testRegistryService")  
public class TestRegistryServiceImpl implements TestRegistryService{
	
	public String hello(String name) {    
	    return "hello"+name;  
	}  

}

  为了让dubbo和zookeeper来管理过程,我们还需要做额外的配置(前提是spring已经加入到工程中来)

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jee="http://www.springframework.org/schema/jee"
	xmlns:tx="http://www.springframework.org/schema/tx" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
	http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
	http://www.springframework.org/schema/tx
	http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
	http://www.springframework.org/schema/jee
	http://www.springframework.org/schema/jee/spring-jee-3.1.xsd
	http://code.alibabatech.com/schema/dubbo
	http://code.alibabatech.com/schema/dubbo/dubbo.xsd
	http://www.springframework.org/schema/context
	http://www.springframework.org/schema/context/spring-context-3.1.xsd"
	default-lazy-init="false">
	<!-- 提供方应用名称信息,这个相当于起一个名字,我们dubbo管理页面比较清晰是哪个应用暴露出来的 -->
	<dubbo:application name="dubbo_provider"></dubbo:application>
	<!-- 使用zookeeper注册中心暴露服务地址 -->
	<dubbo:registry address="zookeeper://127.0.0.1:2181"
		check="false" subscribe="false" register=""></dubbo:registry>
	<!-- 要暴露的服务接口 -->
	<dubbo:service interface="com.dubbo.registry.service.TestRegistryService" ref="testRegistryService" />
</beans>

  启动过程,效果如下图:

 

(3)test-maven-customer项目的具体实现,相关pom代码如下:

		<dependency>
			<groupId>cn.test</groupId>
			<artifactId>test-maven-api</artifactId>
			<version>0.0.1-SNAPSHOT</version>
		</dependency>
		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>dubbo</artifactId>
			<version>2.5.3</version>
			<exclusions>
				<exclusion>
					<groupId>org.springframework</groupId>
					<artifactId>spring</artifactId>
				</exclusion>
			</exclusions>
		</dependency>
		<dependency>
			<groupId>org.apache.zookeeper</groupId>
			<artifactId>zookeeper</artifactId>
			<version>3.4.6</version>
		</dependency>
		<dependency>
			<groupId>com.github.sgroschupf</groupId>
			<artifactId>zkclient</artifactId>
			<version>0.1</version>
		</dependency>

  web层,控制器代码

package com.dubbo.registry.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

import com.dubbo.registry.service.TestRegistryService;

@Controller
public class IndexController {
	
	@Autowired
	private TestRegistryService testRegistryService;
	
	@RequestMapping("/hello")
	public String index(Model model){
	     String name = testRegistryService.hello("zz");
	     System.out.println("xx=="+name);
		return "";
	}

}

  dubbo和zookeeper配置如下

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jee="http://www.springframework.org/schema/jee"
	xmlns:tx="http://www.springframework.org/schema/tx" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
	http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
	http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.1.xsd
	http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd
	http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd"
	default-lazy-init="false">

	<dubbo:application name="dubbo_consumer"></dubbo:application>
	<!-- 使用zookeeper注册中心暴露服务地址 -->
	<dubbo:registry address="zookeeper://127.0.0.1:2181"
		check="false"></dubbo:registry>
	<!-- 要引用的服务 -->
	<dubbo:reference interface="com.dubbo.registry.service.TestRegistryService" id="testRegistryService"></dubbo:reference>
</beans>

  启动项目:效果如下

 

(5)然后访问消费者项目,Controller层能像调用本地一样调用服务的具体实现,如图所示:

 

 

 

参考:

http://dubbo.io/Developer+Guide-zh.htm#DeveloperGuide-zh-%E6%9A%B4%E9%9C%B2%E6%9C%8D%E5%8A%A1%E6%97%B6%E5%BA%8F

http://www.cnblogs.com/Javame/p/3632473.html

http://blog.csdn.net/congcong68/article/details/41113239

http://doc.okbase.net/congcong68/archive/112508.html

以上是关于为啥dubbo使用ZkClient作为zookeeper的客户端的主要内容,如果未能解决你的问题,请参考以下文章

dubbo在Github上为啥不更新了

Dubbo报org.I0Itec.zkclient.exception.ZkNoNodeException异常

短信平台README.MD

Dubbo-002

【Dubbo】与ZK交互

Dubbo学习-4-dubbo简单案例-2-服务提供者和消费者配置