Zookeeper

  1. Linux下zookeeper的安装

    • vim etc/profile
    • 安装jdk,并配置环境变量
    • 配置zookeeper的环境变量
      在这里插入图片描述
  2. zookeeper基本使用

    • 切换到zookeeper的bin目录 cd /usr/local/zookeeper/bin
    • ./zkServer.sh start 开启zk 服务器
    • ./zkCli.sh开启zk客户端
    • create /testNode testData 在根目录创建一个testNode节点,值为testData
    • ls /查询根目录下的节点
    • get /testNode 查看节点数据
      在这里插入图片描述
  • set /testNode testNewData 改变testNode节点的值
    在这里插入图片描述

  • 删除节点
    在这里插入图片描述

  1. ssm框架使用zookeeper
    • 创建配置文件applicationContext-zookeeper.xml
    • 创建重连策略
    <!-- 创建重连策略 -->
     <bean id="retryPolicy" class="org.apache.curator.retry.ExponentialBackoffRetry">
     	<!-- 每次重试连接的等待时间 -->
     	<constructor-arg index="0" value="1000"></constructor-arg>
     	<!-- 设置的重连的次数 -->
     	<constructor-arg index="1" value="5"></constructor-arg>
     </bean>
    
    • 创建zookeeper客户端
    <!-- 创建zookeeper客户端 -->
    <bean id="client" class="org.apache.curator.framework.CuratorFrameworkFactory" 
    	factory-method="newClient" init-method="start">
     	<!--  list of servers to connect to -->
    	<constructor-arg index="0" value="101.132.69.39:2181"></constructor-arg>
    	<!--  session timeout -->
    	<constructor-arg index="1" value="10000"></constructor-arg>
    	<!--  connection timeout -->
    	<constructor-arg index="2" value="10000"></constructor-arg>
    	<!--  retry policy to use -->
    	<constructor-arg index="3" ref="retryPolicy"></constructor-arg>
    </bean>
    
    <!-- init-method="init" 不使用zk的话,仅仅只是测试为了方便可以把这个方法暂时拿掉 -->
    <bean id="ZKCurator" class="com.imooc.web.util.ZKCurator" init-method="init">
    	<constructor-arg index="0" ref="client"></constructor-arg>
    </bean>
    
  • 配置对应的java类
package com.imooc.web.util;

import org.apache.curator.framework.CuratorFramework;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.ZooDefs.Ids;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class ZKCurator {

	// zk客户端
	private CuratorFramework client = null;	
	final static Logger log = LoggerFactory.getLogger(ZKCurator.class);
	
	public ZKCurator(CuratorFramework client) {
		this.client = client;
	}
	
	public void init() {
		client = client.usingNamespace("admin");
		
		try {
			// 判断在admin命名空间下是否有bgm节点  /admin/bmg
			if (client.checkExists().forPath("/bgm") == null) {
				/**
				 * 对于zk来讲,有两种类型的节点:
				 * 持久节点: 当你创建一个节点的时候,这个节点就永远存在,除非你手动删除
				 * 临时节点: 你创建一个节点之后,会话断开,会自动删除,当然也可以手动删除
				 */
				client.create().creatingParentsIfNeeded()
					.withMode(CreateMode.PERSISTENT)		// 节点类型:持久节点
					.withACL(Ids.OPEN_ACL_UNSAFE)			// acl:匿名权限
					.forPath("/bgm");
				log.info("zookeeper初始化成功...");
				
				log.info("zookeeper服务器状态:{}", client.isStarted());
			}
		} catch (Exception e) {
			log.error("zookeeper客户端连接、初始化错误...");
			e.printStackTrace();
		}
	}
	
	/**
	 * @Description: 增加或者删除bgm,向zk-server创建子节点,供小程序后端监听
	 */
	public void sendBgmOperator(String bgmId, String operObj) {
		try {
			
			client.create().creatingParentsIfNeeded()
				.withMode(CreateMode.PERSISTENT)		// 节点类型:持久节点
				.withACL(Ids.OPEN_ACL_UNSAFE)			// acl:匿名权限
				.forPath("/bgm/" + bgmId, operObj.getBytes());
		} catch (Exception e) { 
			e.printStackTrace();
		}
	}
	
}

  • 在对应接口函数调用sendBgmOperator
	public void addBgm(Bgm bgm) {
		String bgmId = sid.nextShort();
		bgm.setId(bgmId);
		bgmMapper.insert(bgm);
		
		Map<String, String> map = new HashMap<>();
		map.put("operType", BGMOperatorTypeEnum.ADD.type);
		map.put("path", bgm.getPath());
		
		zkCurator.sendBgmOperator(bgmId, JsonUtils.objectToJson(map));
	}
  1. spring boot使用zookeeper
    • 创建zookeeper客户端类并添加监听zookeeper的接口
package com.fanqiao;

import java.io.File;
import java.net.URL;
import java.net.URLEncoder;
import java.util.Map;

import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.curator.RetryPolicy;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.framework.recipes.cache.PathChildrenCache;
import org.apache.curator.framework.recipes.cache.PathChildrenCacheEvent;
import org.apache.curator.framework.recipes.cache.PathChildrenCacheListener;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.fanqiao.cofig.ResourceConfig;
import com.fanqiao.enums.BGMOperatorTypeEnum;
import com.fanqiao.utils.JsonUtils;

@Component
public class ZKCuratorClient {

	// zk客户端
	private CuratorFramework client = null;	
	final static Logger log = LoggerFactory.getLogger(ZKCuratorClient.class);

//	@Autowired
//	private BgmService bgmService;
	
//	public static final String ZOOKEEPER_SERVER = "192.168.1.210:2181";
	
	@Autowired
	private ResourceConfig resourceConfig;
	
	public void init() {
		
		if (client != null) {
			return;
		}
		
		// 重试策略
		RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 5);
		// 创建zk客户端
		client = CuratorFrameworkFactory.builder().connectString(resourceConfig.getZookeeperServer())
				.sessionTimeoutMs(10000).retryPolicy(retryPolicy).namespace("admin").build();
		// 启动客户端
		client.start();
		
		try {
//			String testNodeData = new String(client.getData().forPath("/bgm/18052674D26HH3X4"));
//			log.info("测试的节点数据为: {}", testNodeData);
			addChildWatch("/bgm");
		} catch (Exception e) {
			e.printStackTrace();
		}
		
	}
	
	- 监听zookeeper节点数据变更的接口
	public void addChildWatch(String nodePath) throws Exception {
		
		final PathChildrenCache cache = new PathChildrenCache(client, nodePath, true);
		cache.start();
		cache.getListenable().addListener(new PathChildrenCacheListener() {
			
			@Override
			public void childEvent(CuratorFramework client, PathChildrenCacheEvent event) 
					throws Exception {
				
				if (event.getType().equals(PathChildrenCacheEvent.Type.CHILD_ADDED)) {
					log.info("监听到事件 CHILD_ADDED");
					
					// 1. 从数据库查询bgm对象,获取路径path
					String path = event.getData().getPath();
					String operatorObjStr = new String(event.getData().getData());
					Map<String, String> map = JsonUtils.jsonToPojo(operatorObjStr, Map.class);
					String operatorType = map.get("operType");
					String songPath = map.get("path");
					
//					String arr[] = path.split("/");
//					String bgmId = arr[arr.length - 1];
					
//					Bgm bgm = bgmService.queryBgmById(bgmId);
//					if (bgm == null) {
//						return;
//					}
					
					// 1.1 bgm所在的相对路径
//					String songPath = bgm.getPath();
					
					// 2. 定义保存到本地的bgm路径
//					String filePath = "C:\\imooc_videos_dev" + songPath;
					String filePath = resourceConfig.getFileSpace() + songPath;
					
					// 3. 定义下载的路径(播放url)
					String arrPath[] = songPath.split("\\\\");
					String finalPath = "";
					// 3.1 处理url的斜杠以及编码
					for(int i = 0; i < arrPath.length ; i ++) {
						if (StringUtils.isNotBlank(arrPath[i])) {
							finalPath += "/";
							finalPath += URLEncoder.encode(arrPath[i], "UTF-8") ;
						}
					}
//					String bgmUrl = "http://192.168.1.2:8080/mvc" + finalPath;
					String bgmUrl = resourceConfig.getBgmServer() + finalPath;
					
					if (operatorType.equals(BGMOperatorTypeEnum.ADD.type)) {
						// 下载bgm到spingboot服务器
						URL url = new URL(bgmUrl);
						File file = new File(filePath);
						FileUtils.copyURLToFile(url, file);
						client.delete().forPath(path);
					} else if (operatorType.equals(BGMOperatorTypeEnum.DELETE.type)) {
						File file = new File(filePath);
						FileUtils.forceDelete(file);
						client.delete().forPath(path);
					}
				}
			}
		});
	}
	
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值