16 Spring Boot和ZooKeeper

本文是读《Spring Boot2精髓-从构建小系统到架构分布式大系统》的读书笔记。

ZooKeeper 就是这样一款协调器。协调器本身也是分布式的,以保证协调器的高可用,所以也称为分布式协调器 。 分布式协调器是分布式系统和大数据系统必备的一个基础服务 。

16.1 ZooKeeper

ZooKeeper (下面简称 zk )有以下特点:

  • 简单的 API 和数据结构完成协调服务, zk 提供了易于理解的数据结构来完成协调服务, 其 Java API 非常简单。 Curator进一步封装了这些 API ,直接提供了分布式协调服务而 不需要关心细节 。
  • 分布式,不会出现单点故障, 一般来说,至少部署 3 台 zk 以避免单点故障 。 客户端(指 Spring Boot 应用)如果连接的 zk 窑机, 客户端将自动连接到另外一台。
  • 保证操作的时序性, zk 对每次更新都有时间戳记录,从而保证操作的时序性,保证可 以完成更高层次的协调服务,如分布式锁 。
  • 性能测试结果, zk 本身的性能非常好,既可以处理分布式系统的管理协调任务,如选 举领导 ,也能胜任高井发量的业务协调处理,如业务处理的分布式锁 。
    ZooKeeper的数据结构

zk 提供的命名 空 间 ( name space )类似文件系统,每一个节点都是通过路径来表示的,不同的是,节点可以包含一定的数据 (2MB 字节),这些节点可以用来存放业务信息,如配置信息等 。
安装ZooKeeper

https://zookeeper.apache.org/

为了启动 ZooKeeper,进入 conf 目录,创建一个文件,命名为 zoo.cfg,内容如下:

tickTime=2000
dataDir= .. /data
clientPort=2181

然后进入 Bin 目录,运行 zkServer:

D: \apache\zookeeper- 3 . 4 . 8\ bin>zkServer

使用 Ctrl+C 停止 zkServer 。
ZooKeeper 的基本命令
服务器启动成功,我们可以运行 zkCli 来连接到 ZooKeeper 服务器上进行操作 。

ls , 查看目录 。

create ,创建节点 。

create -e,创建临时节点, 一旦用户会话结束,则节点自动删除 。

create -s,创建带有序列号的节点,带有-s 的 create 命令会自动为节点增加一个序列号
递增后缀,可以通过这个判断节点创建的先后顺序。

get ,获取节点数据 。

delete ,删 除节点 。

set path data , 设置节点数据 。

watch 操作

领导选取演示

分布式锁演示
实现分布式锁可以利用节点唯一性,比如创建一个/locks/xxx 的节点,这里的 xxx 是任意名字,例如对应到业务逻辑的合同号等。

服务注册演示

16.2 Spring Boot 集成 ZooKeeper

Curator 是 Apache 提供的一个访问 zk 的工具包,封装了这些低级别操作 , 同时也提供一些高级服务,比如分布式锁、领导选取等

集成 Curator

pom中添加依赖

<dependency>
	<groupid>org.apache . curator</groupid>
	<artifactid>curator-recipes</artifactid>
	<version >2 .12 . 0</version>
</dependency>
@Configuration
public class ZookeeperConf {
	@Value (”${ zk . url })
	private String zkUrl;
	@Bean
	public CuratorFramework getCuratorFramework() {
		RetryPolicy retryPolicy =new ExponentialBackoffRetry(lOOO, 3);
		CuratorFramework client= CuratorFrameworkFactory.newClient(zkUrl,		retryPolicy) ;
		client.start() ;
		return client ;
	}
}

Curator API
Curator API 是链式调用风格,遇到 forPath 接口就触发 ZooKeeper 调用,比如创建一个节点:
这样,当节点变化时,将通知 Curator,只需要添加一个 CuratorListener 即可。
Curator API 支持异步执行,通过在调用链式方法中加入backgroud()实现。异步的执行结果也将通过CuratorListener 通知,除了上面提到的CuratorEventType.WATCHED,还支持后台执行的CREATE 、DELETE 、EXISTS等操作。

16.3 实现分布式锁

Curator 提供了zk场景的绝大部分实现,使用Curator,就不必关心其内部算法,Curator 提供了 InterProcessMutex 来实现分布式锁,InterProcessMutex 用 acquire 方法获取锁,以及用 release释放锁,同其他锁一样, release 方法需要放在 finally 代码块中 ,确保锁能正确释放 。

package com.bee.sample.ch16.service.impl;

import java.util.concurrent.TimeUnit;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.recipes.locks.InterProcessMutex;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.bee.sample.ch16.service.OrderService;

@Service
public class OrderServiceImpl implements OrderService {
	Log log = LogFactory.getLog(OrderServiceImpl.class);
	@Autowired
	CuratorFramework zkClient ;
	String lockPath = "/lock/order";
	//处理某种订单类型
	public void makeOrderType(String type) {
		String path = lockPath+"/"+type;
		log.info("try do job for "+type);
		try{
			InterProcessMutex lock = new InterProcessMutex(zkClient, path);
			if ( lock.acquire(10, TimeUnit.HOURS) ){ 
			    try {
			    		
			        //模拟用时5秒
			        Thread.sleep(1000*5);
			        //即使获得分布式锁,在实际业务处理过程中,也应该检查数据是否已经被处理
			        log.info("do job "+type+" done");
			    }
			    finally{
			        lock.release();
			    }
			    
			}
		}catch(Exception ex){
			//zk异常
			ex.printStackTrace();
		}
	}
}

16.4 服务注册

Curator 提供了 一个服务注册与发现的封装库,需要在 porn 中 添加以下依赖:
通过 Service Discovery 注册服务

获取服务
获取服务也是调用 ServiceDiscovery 类来实现的,通过调用 queryForInstances 可以获得当前所有可用服务。

领导选取
分布式应用中,有时候必须选出一个节点来分配任务给其他节点,或者负责协调其他节点,比如有多台机器协作处理一批任务,那这些任务应该由哪台机器来分配呢?必须选出 一个领导节点来负责。

使用 Curator,无须关心 zk 的领导节点的选取算法,通过 LeaderSelector 即可实现领导的选取

        

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值