Zookeeper介绍
ZooKeeper 是一个集中式服务,用于维护配置信息、命名、提供分布式同步和提供组服务。 分布式应用程序以某种形式使用所有这些类型的服务。 每次实现它们时,都需要进行大量工作来修复不可避免的错误和竞争条件。 由于实现这些服务的难度,应用程序最初通常会吝啬它们,这使得它们在发生变化时变得脆弱且难以管理。 即使正确完成,在部署应用程序时,这些服务的不同实现也会导致管理复杂性。
入门:协调分布式应用程序 ZooKeeper
下载
https://downloads.apache.org/zookeeper/
独立操作
在独立模式下设置 ZooKeeper 服务器是 直截了当。 服务器包含在单个 JAR 文件中, 所以安装包括创建配置。
下载稳定的 ZooKeeper 版本后,解压缩 它和 cd 到根目录
要启动 ZooKeeper,需要一个配置文件。zoo_sample.cfg是一个样本, 需要在config下创建 zoo.cfg :
tickTime=2000 #检查时间
dataDir=/var/lib/zookeeper #保存的路径,绝对路径或者相对路径
clientPort=2181 #Zookeeper运行的端口,默认值
tickTime:ZooKeeper 使用的基本时间单位,以毫秒为单位。 这是 用于做心跳和最小会话超时将是 两倍的时间。
dataDir:存储内存数据库快照的位置,以及, 除非另有说明,更新的事务日志 数据库。
clientPort:侦听客户端连接的端口
ZooKeeper 使用 log4j 记录消息——
二进制文件说明
Files ending in .cmd are msdos/windows compatible,CMD文件是window客运行的文件
zkCli 启动客户端、zkServer启动服务、zkEnv的介绍https://blog.csdn.net/u011784767/article/details/50601211/
zkCli 的相关命令
help #查看命令
ZooKeeper host:port cmd args
get path [watch]
ls path [watch]
set path data [version]
delquota [-n|-b] path
quit
printwatches on|off
createpath data acl
stat path [watch]
listquota path
history
setAcl path acl
getAcl path
sync path
redo cmdno
addauth scheme auth
delete path [version]
setquota -n|-b val path
#基本包括了查看、获取、设置、重做、删除、查看版本
双击zkServer.cmd,启动服务。
项目案例
正如使用SpringBoot中的Eureka注册中心一样。服务的提供方和消费放都需要连接到Zookeeper,
服务方
配置服务名称,暴露的端口号,注册,暴露的借口,dubbo配置service
<?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:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd
">
<!-- 提供方应用信息,用于计算依赖关系 -->
<dubbo:application name="hello-world-app" />
<!-- 用dubbo协议在20880端口暴露服务 -->
<dubbo:protocol name="dubbo" port="20880" />
<!-- 使用zookeeper进行注册中心化 -->
<dubbo:registry address="zookeeper://localhost:2181"/>
<!-- 和本地bean一样实现服务 -->
<bean id="quickStartService" class="com.mooc.jiangzh.dubbo.quickstart.QuickStartServiceImpl" />
<!-- 声明需要暴露的服务接口
async="true"
timeout="10000" 默认超过一秒就会超时 业务中注意设置重试一次或者超时时长多点
-->
<dubbo:service
timeout="10000"
interface="com.mooc.jiangzh.dubbo.ServiceAPI"
ref="quickStartService"/>
<!-- registry="N/A" -->
</beans>
提供的接口
package com.mooc.jiangzh.dubbo;
import java.util.List;
public interface ServiceAPI {
String sendMessage(String message);
String sendMessage02(String message);
List<String> mergeTest(String message);
}
接口的具体实现
package com.mooc.jiangzh.dubbo.quickstart;
import com.mooc.jiangzh.dubbo.ServiceAPI;
import java.util.List;
public class QuickStartServiceImpl implements ServiceAPI {
@Override
public String sendMessage(String message) {
System.out.println("服务提供方:message="+message);
// 模拟业务执行时长
// try {
// Thread.sleep(2000);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
return "quickstart-provider-message="+message;
}
@Override
public String sendMessage02(String message) {
System.out.println("message02="+message);
try {
Thread.sleep(4000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "quickstart-provider-message02 ="+message;
}
@Override
public List<String> mergeTest(String message) {
return null;
}
}
提供方的启动类
package com.mooc.jiangzh.dubbo;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.io.IOException;
public class ProviderClient {
public static void main(String[] args) {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext-hello-provider.xml");
context.start();
try {
System.in.read();
} catch (IOException e) {
e.printStackTrace();
}
}
}
消费方
消费方的应用命名、注册地址、dubbo的关联接口
<?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:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd
">
<!-- 消费方应用名,用于计算依赖关系,不是匹配条件,不要与提供方一样 -->
<dubbo:application name="consumer-of-helloworld-app" />
<!-- 使用zookeeper进行注册中心化 -->
<dubbo:registry address="zookeeper://localhost:2181"/>
<!-- 生成远程服务代理,可以和本地bean一样使用demoService
connections="10"
async="true"
-->
<dubbo:reference
id="consumerService"
interface="com.mooc.jiangzh.dubbo.ServiceAPI"/>
<!-- url="dubbo://localhost:20880" -->
</beans>
与提供方保持一致
package com.mooc.jiangzh.dubbo;
import java.util.List;
public interface ServiceAPI {
String sendMessage(String message);
String sendMessage02(String message);
List<String> mergeTest(String message);
}
启动类
package com.mooc.jiangzh.dubbo;
import com.alibaba.dubbo.rpc.RpcContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.util.Scanner;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
public class ConsumerClient {
public static void main(String[] args) throws ExecutionException, InterruptedException {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext-hello-consumer.xml");
context.start();
while (true){
Scanner scanner = new Scanner(System.in);
System.out.println("请输入你要输入的内容:");
String message = scanner.next();
// 获取接口
ServiceAPI serviceAPI = (ServiceAPI)context.getBean("consumerService");
// 简单条用测试
System.out.println(serviceAPI.sendMessage("消费方发送消息:" + message));
}
}
}
结果演示