分布式服务框架DUBBO

DUBBO 简介

  • Dubbo是[1] 阿里巴巴公司开源的一个高性能优秀的服务框架,使得应用可通过高性能的 RPC(远程过程调用协议) 实现服务的输出和输入功能,可以和Spring框架无缝集成。
  • 阿里的DUBBO团队解散了,现在由当当团队维护了一个叫DUBBOX的项目。

Zookeeper 安装配置

  1. 下载Zookeeper
  2. 解压到安装目录
  3. 将文件zookeeper-3.3.6\conf\zoo_sample.cfg改名称zoo.cfg
  4. 执行zookeeper-3.3.6\bin\zkServer.cmd启动服务

配置文件

	# 这个时间是作为 Zookeeper 服务器之间或客户端与服务器之间维持心跳的时间间隔,也就是每个 tickTime 时间就会发送一个心跳。
	tickTime=2000
	# 初始化时连接到服务器端的间隔次数
	initLimit=10
	# ZK Leader 和follower之间通讯的次数,总时间5*2=10秒   
	syncLimit=5
	# 保存数据的目录,默认情况下将写数据的日志文件也保存在这个目录里。
	dataDir=D:\\apps\\zookeeper-3.3.6\\zookeeper_test_001\\tmp\\zookeeper
	# 日志目录
	dataLogDir=D:\\apps\\zookeeper-3.3.6\\zookeeper_test_001\\logs 
	# 这个端口就是客户端连接Zookeeper服务器的端口,Zookeeper 会监听这个端口,接受客户端的访问请求。
	clientPort=2181
  • zoo.cfg配置详情
  • Zookeeper原理
  • Paxos算法与Zookeeper分析
  • Paxos 算法百科

Zookeeper客户端命令(zkCli.cmd)

  • [zk: localhost:2181(CONNECTED) 4] ls /
    • 查看当前Zookeeper所包含内容
  • [zk: localhost:2181(CONNECTED) 4] ls2 /
    • 查看当前Zookeeper所包含内容并能看到更新次数等数据
  • [zk: localhost:2181(CONNECTED) 4] creater /zk myData
    • 创建一个新的znode节点“zk”以及它关联的字符串
  • [zk: localhost:2181(CONNECTED) 4] get /zk
    • 查看znode节点“zk”的关联字符串等信息
  • [zk: localhost:2181(CONNECTED) 4] set /zk shenlan211314
    • 对znode节点“zk”所关联的字符串进行设置
  • [zk: localhost:2181(CONNECTED) 4] delete /zk
    • 删除znode节点“zk”
  • [zk: localhost:2181(CONNECTED) 4] connect host:port
    • 连接Zookeeper

zookeeper 集群(单机模拟)

  • 将Zookeeper复制成3份
  • 修改每份Zookeeper的配置文件zoo.cfg
  • 在dataDir目录下创建一个myid文件里面写1~255的数字(表示自身的id)
  • 启动所有Zookeeper

第一份Zookeeper的配置文件

		# 这个时间是作为 Zookeeper 服务器之间或客户端与服务器之间维持心跳的时间间隔,也就是每个 tickTime 时间就会发送一个心跳。
		tickTime=2000
		# 初始化时连接到服务器端的间隔次数
		initLimit=10
		# ZK Leader 和follower之间通讯的次数,总时间5*2=10秒   
		syncLimit=5
		# 保存数据的目录,默认情况下将写数据的日志文件也保存在这个目录里。
		dataDir=D:\\apps\\zookeeper-3.3.6\\zookeeper_test_001\\tmp\\zookeeper
		# 日志目录
		dataLogDir=D:\\apps\\zookeeper-3.3.6\\zookeeper_test_001\\logs 
		# 这个端口就是客户端连接Zookeeper服务器的端口,Zookeeper 会监听这个端口,接受客户端的访问请求。
		clientPort=2181

		server.1=localhost:2887:3887 
		server.2=localhost:2888:3888
		server.3=localhost:2889:3889

第二份Zookeeper的配置文件

		# 这个时间是作为 Zookeeper 服务器之间或客户端与服务器之间维持心跳的时间间隔,也就是每个 tickTime 时间就会发送一个心跳。
		tickTime=2000
		# 初始化时连接到服务器端的间隔次数
		initLimit=10
		# ZK Leader 和follower之间通讯的次数,总时间5*2=10秒   
		syncLimit=5
		# 保存数据的目录,默认情况下将写数据的日志文件也保存在这个目录里。
		dataDir=D:\\apps\\zookeeper-3.3.6\\zookeeper_test_002\\tmp\\zookeeper
		# 日志目录
		dataLogDir=D:\\apps\\zookeeper-3.3.6\\zookeeper_test_002\\logs 
		# 这个端口就是客户端连接Zookeeper服务器的端口,Zookeeper 会监听这个端口,接受客户端的访问请求。
		clientPort=2182

		server.1=localhost:2887:3887 
		server.2=localhost:2888:3888
		server.3=localhost:2889:3889

第三份Zookeeper的配置文件

		# 这个时间是作为 Zookeeper 服务器之间或客户端与服务器之间维持心跳的时间间隔,也就是每个 tickTime 时间就会发送一个心跳。
		tickTime=2000
		# 初始化时连接到服务器端的间隔次数
		initLimit=10
		# ZK Leader 和follower之间通讯的次数,总时间5*2=10秒   
		syncLimit=5
		# 保存数据的目录,默认情况下将写数据的日志文件也保存在这个目录里。
		dataDir=D:\\apps\\zookeeper-3.3.6\\zookeeper_test_003\\tmp\\zookeeper
		# 日志目录
		dataLogDir=D:\\apps\\zookeeper-3.3.6\\zookeeper_test_003\\logs 
		# 这个端口就是客户端连接Zookeeper服务器的端口,Zookeeper 会监听这个端口,接受客户端的访问请求。
		clientPort=2183

		server.1=localhost:2887:3887 
		server.2=localhost:2888:3888
		server.3=localhost:2889:3889

配置文件server.N=YYY:A:B

  • N:服务器id(myid文件中的id)
  • YYY:服务器的IP地址
  • A:LF通信端口,表示该服务器与集群中的leader交换的信息的端口
  • B:选举端口,表示选举新leader时服务器间相互通信的端口
    • 集群中每个服务器的A端口都是一样,每个服务器的B端口也是一样。但是当所采用的为伪集群时,IP地址都一样,只能时A端口和B端口不一样。

JAVA 操作Zookeeper

		/* 注册回调 */
		Watcher watcher =  new Watcher() {
			public void process(WatchedEvent event) {
			}
		};
		
		try {
			ZooKeeper zk = new ZooKeeper("127.0.0.1:2181", 500000, watcher);
			//创建一个节点root,数据是mydata,不进行ACL权限控制,节点为永久性的(即客户端shutdown了也不会消失)
			zk.create("/root", "mydata".getBytes(),Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);

			//在root下面创建一个childone znode,数据为childone,不进行ACL权限控制,节点为永久性的
			zk.create("/root/childone","childone".getBytes(), Ids.OPEN_ACL_UNSAFE,CreateMode.PERSISTENT);

			//取得/root节点下的子节点名称,返回List<string>
			zk.getChildren("/root",true);

			//取得/root/childone节点下的数据,返回byte[]
			zk.getData("/root/childone", true, null);

			//修改节点/root/childone下的数据,第三个参数为版本,如果是-1,那会无视被修改的数据版本,直接改掉
			zk.setData("/root/childone","childonemodify".getBytes(), -1);

			//删除/root/childone这个节点,第二个参数为版本,-1的话直接删除,无视版本
			zk.delete("/root/childone", -1);
			      
			//关闭session
			zk.close();
		} catch (IOException e) {
			e.printStackTrace();
		} catch (KeeperException e) {
			e.printStackTrace();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}

编译DUBBO

  • 从GitHub下载源码(建议下载DUBBOX的最新版本)
  • 进入源码工程目录
  • mvn install -Dmaven.test.skip=true
  • 如果报包依赖错误就添加几个maven镜像
    	<mirror>
    		<id>kafeitu</id>
    		<mirrorOf>central</mirrorOf>
    		<name>Human Readable Name for this Mirror.</name>
    		<url>http://maven.kafeitu.me/nexus/content/repositories/public</url>
    	</mirror>
    	<mirror>
    		<id>ibiblio.org</id>
    		<name>ibiblio Mirror of http://repo1.maven.org/maven2/</name>
    		<url>http://mirrors.ibiblio.org/pub/mirrors/maven2</url>
    		<mirrorOf>*</mirrorOf>
    	</mirror>
    	<mirror>
    		<id>lvu.cn</id>
    		<name>lvu.cn</name>
    		<url>http://lvu.cn/nexus/content/groups/public</url>
    		<mirrorOf>*</mirrorOf>
    	</mirror>
    	

DUBBO示例

创建Maven工程User-Server-Api(实体Bean和接口)

  • Bean
	public class User implements java.io.Serializable{
	
		private static final long serialVersionUID = -1591493796674994627L;
		
		private String name;

		public String getName() {
			return name;
		}
		public void setName(String name) {
			this.name = name;
		}
		public User(String n){
			this.name = n;
		}
	}
  • 提供的服务
	public interface UserService {
		
		public List<user> getUser();
	}
</user>

创建Maven工程User-Server-Provider(服务提供者)

  • 添加第三方依赖
    <!--- 接口依赖  -->
    <dependency>
	    <groupId>dubbo-test</groupId>
	    <artifactId>User-Server-Api</artifactId>
	    <version>0.0.1-SNAPSHOT</version>
    </dependency>

    <!--- 第三方依赖  -->
    <dependency>
	    <groupId>com.alibaba</groupId>
	    <artifactId>dubbo</artifactId>
	    <version>2.5.3</version>
    </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>
    <dependency>
	    <groupId>io.netty</groupId>
	    <artifactId>netty</artifactId>
	    <version>4.0.0.Alpha8</version>
    </dependency>
    <dependency>
	    <groupId>org.slf4j</groupId>
	    <artifactId>slf4j-api</artifactId>
	    <version>1.7.14</version>
    </dependency>
    <dependency>
	    <groupId>org.slf4j</groupId>
	    <artifactId>slf4j-log4j12</artifactId>
	    <version>1.7.14</version>
    </dependency>
  • 提供服务的实现
	public class UserServiceImpl implements UserService{
	
		public List<user> getUser(){
			List<user> users = new ArrayList<user>();
			users.add(new User("李连杰"));
			users.add(new User("成龙"));
			users.add(new User("吴京"));
			return users;
		}
	}
</user></user></user>
  • 添加dubbo-provider.xml(文件名随意)配置提供的服务
    • XML默认存放路径"META-INF/spring/dubbo-provider.xml"
    • 添加dubbo.properties文件可以修改XML的默认路径
      • dubbo.spring.config=classpath*:dubbo-provider.xml
	<?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:dubbo="http://code.alibabatech.com/schema/dubbo"  
	    xsi:schemaLocation="http://www.springframework.org/schema/beans          
	    http://www.springframework.org/schema/beans/spring-beans.xsd          
	    http://code.alibabatech.com/schema/dubbo          
	    http://code.alibabatech.com/schema/dubbo/dubbo.xsd">  
	   
	    <!-- 提供方应用信息,用于计算依赖关系 -->  
	    <dubbo:application name="User-Server"  />
	   
	    <!-- 使用zookeeper注册中心暴露服务地址 -->  
	    <dubbo:registry address="zookeeper://127.0.0.1:2181" />  
	   
	    <!-- 用dubbo协议在20880端口暴露服务 -->  
	    <dubbo:protocol name="dubbo" port="20880" />  

	    <!-- 和本地bean一样实现服务 -->  
	    <bean id="userService" class="com.wwq.test.UserServiceImpl" />  
	   
	    <!-- 声明需要暴露的服务接口 -->  
	    <dubbo:service interface="com.wwq.test.UserService" ref="userService" />
	   
	</beans>  
  • DUBBO服务启动入口
	public class Main {
		 public static void main(String[] args) throws Exception {
		 		/* 启动DUBBO服务 */
		        com.alibaba.dubbo.container.Main.main(args);
		 }
	}

创建Maven工程User-Consumption(消费者)

  • 添加第三方依赖
    <!--- 接口依赖  -->
    <dependency>
	    <groupId>dubbo-test</groupId>
	    <artifactId>User-Server-Api</artifactId>
	    <version>0.0.1-SNAPSHOT</version>
    </dependency>

    <!--- 第三方依赖  -->
    <dependency>
	    <groupId>com.alibaba</groupId>
	    <artifactId>dubbo</artifactId>
	    <version>2.5.3</version>
    </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>
    <dependency>
	    <groupId>io.netty</groupId>
	    <artifactId>netty</artifactId>
	    <version>4.0.0.Alpha8</version>
    </dependency>
    <dependency>
	    <groupId>org.slf4j</groupId>
	    <artifactId>slf4j-api</artifactId>
	    <version>1.7.14</version>
    </dependency>
    <dependency>
	    <groupId>org.slf4j</groupId>
	    <artifactId>slf4j-log4j12</artifactId>
	    <version>1.7.14</version>
    </dependency>
  • 添加配置文件spring-dubbo.xml
	<?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:dubbo="http://code.alibabatech.com/schema/dubbo"  
	    xsi:schemaLocation="http://www.springframework.org/schema/beans          
	    http://www.springframework.org/schema/beans/spring-beans.xsd          
	    http://code.alibabatech.com/schema/dubbo          
	    http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
	     
	    <!-- 消费方应用名,用于计算依赖关系,不是匹配条件,不要与提供方一样 -->  
	    <dubbo:application name="User-consumer"/>
	    
	    <dubbo:registry address="zookeeper://127.0.0.1:2181" />
	    
	    <!-- 生成远程服务代理,可以和本地bean一样使用demoService -->  
	    <dubbo:reference id="userService" interface="com.wwq.test.UserService" />  
	</beans> 
  • 获取提供的服务进行业务操作
	public class UserAction {

		public static void main(String[] args) {
			String connFile = "spring-dubbo.xml";
			ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext(connFile);
			UserService userService = (UserService)applicationContext.getBean("userService");
			System.out.println(userService.getUser());
		}
	}

测试我们编写的DUBOO

  • 启动注册中心Zookeeper
  • 启动服务管理中心dubbo-admin
  • 运行服务提供项目的Main.java启动Dubbo服务
  • 运行服务消费项目的UserAction.java进行测试

你可能感兴趣的:(分布式服务框架DUBBO)