1、前言
又到了金三银四的时候,大家都按耐不住内心的躁动,我在这里给大家分享下之前面试中遇到的一个知识点(zookeeper应用场景),希望对大家有些帮助。如有不足,欢迎大佬们指点指点。
2、zookeeper简介
ZooKeeper 是分布式应用程序的分布式开源协调服务。它公开了一组简单的api,分布式应用程序可以基于这些api实现更高级别的同步、配置维护、分组和命名服务。它被设计为易于编程,并使用一种数据模型,该模型以熟悉的文件系统目录树结构为风格。它在 Java 中运行,并具有 Java 和 C 的绑定。
众所周知,协调服务很难做好。它们特别容易出现竞争条件和死锁等错误。ZooKeeper背后的动机是减轻分布式应用程序从头开始实现协调服务的负担。
3、zookeeper应用场景
下面的代码都需要一个序列化类,所以放在最前面声明
/** * @author admin */public class MyZkSerializer implements ZkSerializer
{
String charset = "UTF-8";
@Override public Object deserialize(byte[] bytes) throws ZkMarshallingError
{
try
{
return new String(bytes, charset);
}
catch (UnsupportedEncodingException e)
{
throw new ZkMarshallingError(e);
}
}
@Override
public byte[] serialize(Object obj) throws ZkMarshallingError
{
try {
return String.valueOf(obj).getBytes(charset);
}
catch (UnsupportedEncodingException e)
{
throw new ZkMarshallingError(e);
}
}
3.1 配置中心
3.1.1什么是配置中心呢?
假设咱们的项目部署在5台机子上形成一个集群,那么这5个实例在启动时读取的配置信息应该是一样的,同时一旦咱们的配置信息更改了,需要马上通知到这5个实例上并生效,这就是配置中心的功能。
3.1.2zookeeper怎么实现配置中心呢?
必要条件
1、znode能存储数据
2、Watch能监听数据改变
实现方式
- 一个配置项对应一个zNode
// 1 将单个配置放到zookeeper上
public void putZk() {
ZkClient client = new ZkClient("192.168.10.11:2181");
client.setZkSerializer(new MyZkSerializer());
String configPath = "/config1";
String value = "1111111";
if (client.exists(configPath)) {
client.writeData(configPath, value);
} else {
client.createPersistent(configPath, value);
}
client.close();
}
// 需要配置的服务都从zk上取,并注册watch来实时获得配置更新
public void getConfigFromZk() {
ZkClient client = new ZkClient("192.168.10.11:2181");
client.setZkSerializer(new MyZkSerializer());
String configPath = "/config1";
String value = client.readData(configPath);
System.out.println("从zk读到配置config1的值为:" + value);
// 监控配置的更新,基于watch实现发布订阅功能
client.subscribeDataChanges(configPath, new IZkDataListener() {
@Override
public void handleDataDeleted(String dataPath) throws Exception {
// TODO 配置删除业务处理
}
@Override
public void handleDataChange(String dataPath, Object data) throws Exception {
System.out.println("获得更新的配置值:" + data);
}
});
// 这里只是为演示实时获取到配置值更新而加的等待。实际项目应用中根据具体场景写(可用阻塞方式)
try {
Thread.sleep(5 * 60 * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
- 一个配置文件对应一个zNode
// 将配置文件的内容存放到zk节点上
public void putConfigFile2ZK() throws IOException {
File f = new File(this.getClass().getResource("/config.xml").getFile());
FileInputStream fin = new FileInputStream(f);
byte[] datas = new byte[(int) f.length()];
fin.read(datas);
fin.close();
ZkClient client = new ZkClient("192.168.10.11:2181");
client.setZkSerializer(new BytesPushThroughSerializer(