分布式服务框架DUBBO-源自技术
分布式服务框架DUBBO--源自技术
DUBBO 简介
- Dubbo是[1] 阿里巴巴公司开源的一个高性能优秀的服务框架,使得应用可通过高性能的 RPC(远程过程调用协议) 实现服务的输出和输入功能,可以和Spring框架无缝集成。
- 阿里的DUBBO(http://dubbo.io/)团队解散了,现在由当当团队维护了一个叫DUBBOX(https://github.com/dangdangdotcom/dubbox)的项目。
Zookeeper 安装配置
- 下载Zookeeper
- 解压到安装目录
- 将文件zookeeper-3.3.6\conf\zoo_sample.cfg改名称zoo.cfg
- 执行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();
- }
- lt;/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;
- }
- }
- lt;/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进行测试