zk111111111111111111

news2024/12/23 11:32:59
Zookeeper
1 zookeeper(作为 dubbo 的注册中心):
概述: zookeper 是 一个分布式的、开源的分布式应用程序的协调服务,管理分布式应
作用: 配置管理,分布式锁,集群管理
2 zookeeper 的安装 (dubbo 的资料中已经整理)
3 zookeeper 的数据模型
zookeeper 是一个树形的服务目录,具有明确的层次化结构,树的每一个节点叫
znode,每个节点都记录自己的信息和数据,节点上存储的数据大小为 1m,在我们的
window 目录结构中目录不存数据,(注意对比)
节点分类:
PERSISTENT 持久化节点
EPHEMERAL 临时节点 :-e
PERSISTENT_SEQUENTIAL 持久化顺序节点 :-s
EPHEMERAL_SEQUENTIAL 临时顺序节点 :-es
图示

 

4 zookeeper 的服务端命令
启动 ZooKeeper 服务: ./zkServer.sh start
查看 ZooKeeper 服务状态: ./zkServer.sh status
停止 ZooKeeper 服务: ./zkServer.sh stop
重启 ZooKeeper 服务: ./zkServer.sh restart
5 zookeeper 的客户端命令:
连接 zookeeper 的服务端: ./zkCli.sh –server ip:port
断开连接: quit
设置节点值: set /节点 path value
删除单个节点: delete /节点 path
获取帮助: help
显示指定目录下节点: ls 目录
删除带有子节点的节点: deleteall /节点 path
创建子节点: create /path value
获取节点值: get /节点 path
创建临时节点: create -e /节点 path value
创建顺序节点: create -s /节点 path value
查询节点详细信息: ls –s /节点 path
6 zookeeper 通过 javaapi 进行操作
Curator 一套操作 zookeeper 的 Java api:
pom.xml 文件(注意在版本上有限制,直接使用交高的版本)
<!--curator-->
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>4.0.0</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>4.0.0</version>
</dependency>
(1) 创建连接 zookeeper 的对象(可以抽取为工具类):
代码:

package utils;
import org.apache.curator.RetryPolicy;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.retry.ExponentialBackoffRetry;
/**
* @ClassName: CuratorUtils
* @Author: nanfeng
* @Date: 2021/1/20 11:26
* @Description: curator 发音: [ˈkjʊrˌeɪdər]
*/
public class CuratorUtils {
private static CuratorFramework client;
static {
/*
* @param connectString 连接字符串。zk server 地址和端口
"192.168.149.135:2181,
* 192.168.149.136:2181" 多个连接地址
* @param sessionTimeoutMs 会话超时时间 单位 ms
* @param connectionTimeoutMs 连接超时时间 单位 ms
* @param retryPolicy 重试策略
*/
// 重试策略:参数为休眠时间和最大重试次数
RetryPolicy retryPolicy = new ExponentialBackoffRetry(3000, 10);
/*
//1.第一种方式
CuratorFramework client =
CuratorFrameworkFactory.newClient("192.168.149.135:2181",
60 * 1000, 15 * 1000, retryPolicy);
*/
//2.第二种方式:链式创建
//CuratorFrameworkFactory.builder();
client = CuratorFrameworkFactory.builder()
.connectString("127.0.0.1:2181") //zookeeper 的连接地
址和端口号
.sessionTimeoutMs(60 * 1000) //会话时间
.connectionTimeoutMs(15 * 1000) //连接超时时间
.retryPolicy(retryPolicy) //重试策略
.namespace("nanfeng") //名称空间,可有可无,
根据情况进行添加
.build();
//开启连接
client.start();
}
/**
* 获取连接对象
*
* @param client
* @return
*/
public static CuratorFramework getClient(CuratorFramework client) {
return client;
}
/**
* 释放连接
*
* @param client
*/
public static void clossConnection(CuratorFramework client) {
if (client != null) {
client.close(); }}}
(2) 进行基本的增删改查:
package test;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.api.BackgroundCallback;
import org.apache.curator.framework.api.CuratorEvent;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.data.Stat;
import org.junit.Test;
import utils.CuratorUtils;
import java.util.Arrays;
import java.util.List;
/**
* @ClassName: curatorTest
* @Author: nanfeng
* @Date: 2021/1/20 14:40
* @Description: Curator 的 api 操作 zookeeper
*/
public class CuratorTest {
private static CuratorFramework client;
/*获取公共的连接对象*/
static {
client = CuratorUtils.getClient();
}
/* 创建节点
*/
/**
* 创建节点:create 持久 临时 顺序 数据
* 1. 基本创建 :create().forPath("")
* 2. 创建节点 带有数据:create().forPath("",data)
* 3. 设置节点的类型:create().withMode().forPath("",data)
* 4. 创建多级节点 /app1/p1 :
create().creatingParentsIfNeeded().forPath("",data)
*/
@Test
/*增加*/
public void addZnode1() throws Exception {
//创建节点
String nanfeng1 = client.create().forPath("/nanfeng1");
System.out.println(nanfeng1);
//释放连接
CuratorUtils.clossConnection(client);
}
@Test
public void addZnode2() throws Exception {
//创建节点带有数据
String nanfeng2 = client.create().forPath("/nanfeng2",
"nanfeng2".getBytes());
System.out.println(nanfeng2);
CuratorUtils.clossConnection(client);
}
@Test
public void addZnode3() throws Exception {
//创建节点设置节点类型
//节点默认类型为持久化的
String nanfeng3w =
client.create().withMode(CreateMode.EPHEMERAL).forPath("/nanfeng3");
System.out.println(nanfeng3w);
CuratorUtils.clossConnection(client);
}
@Test
public void addZnode4() throws Exception {
//创建多级节点
String s =
client.create().creatingParentContainersIfNeeded().forPath("/nanfeng4
/nanzi");
System.out.println(s);
CuratorUtils.clossConnection(client);
}
/* 删除节点 */
/**
* 删除节点: delete deleteall
* 1. 删除单个节点:delete().forPath("/app1");
* 2. 删除带有子节点的节
点:delete().deletingChildrenIfNeeded().forPath("/app1");
* 3. 必须成功的删除:为了防止网络抖动。本质就是重试。
client.delete().guaranteed().forPath("/app2");
* 4. 回调:inBackground
*
* @throws Exception
*/
/* 关于回调函数: 在执行某项操作时,自动开启自定义的一系列业务,即
监听执行 */
@Test
/*删除*/
public void deleteZnode1() throws Exception {
//删除单个节点
client.delete().forPath("/nanfeng1");
CuratorUtils.clossConnection(client);
}
@Test
public void deleteZnode2() throws Exception {
//删除带有子节点的节点
client.delete().deletingChildrenIfNeeded().forPath("/nanfeng4");
CuratorUtils.clossConnection(client);
}
@Test
public void deleteZnode3() throws Exception {
//强制删除(必须删除成功)
client.delete().guaranteed().forPath("/nanfeng2");
CuratorUtils.clossConnection(client);
}
@Test
public void deleteZnode4() throws Exception {
//删除回调(可以完成一些特殊的功能)
client.delete().guaranteed().inBackground(new
BackgroundCallback() {
@Override
public void processResult(CuratorFramework
curatorFramework, CuratorEvent curatorEvent) throws Exception {
//回调
//此处执行特定功能,
System.out.println("回调函数触发了");
}
}).forPath("/nanfeng3");
CuratorUtils.clossConnection(client);
}
/* 修改 */
/**
* 修改数据
* 1. 基本修改数据:setData().forPath()
* 2. 根据版本修改: setData().withVersion().forPath()
* * version 是通过查询出来的。目的就是为了让其他客户端或者线程不
干扰我。
*/
@Test
public void setZnode1() throws Exception {
//修改主要是修改节点存放的数据
Stat stat = client.setData().forPath("/nanfeng2",
"nanzi".getBytes());
//将修改的状态打印查看
System.out.println(stat);
CuratorUtils.clossConnection(client);
}
/* 获取
*/
/**
* 查询节点:
* 1. 查询数据:get: getData().forPath()
* 2. 查询子节点: ls: getChildren().forPath()
* 3. 查询节点状态信息:ls -s:getData().storingStatIn(状态对
象).forPath()
*/
@Test
public void getZnode1() throws Exception {
//查询节点数据
byte[] bytes = client.getData().forPath("/nanfeng2");
System.out.println(Arrays.toString(bytes));
CuratorUtils.clossConnection(client);
}
@Test
public void getZnode2() throws Exception {
//查询子节点
List<String> list = client.getChildren().forPath("/");
System.out.println(list);
CuratorUtils.clossConnection(client);
}
@Test
public void getZnode3() throws Exception {
//查询节点的状态信息
Stat stat = new Stat();
System.out.println(stat);
client.getData().storingStatIn(stat).forPath("/nanfeng1");
//打印刷新后的状态信息
System.out.println(stat);
CuratorUtils.clossConnection(client);
}
}
(3) Watch 事件监听
package test;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.recipes.cache.*;
import org.junit.Test;
import utils.CuratorUtils;
import java.util.Arrays;
/**
* @ClassName: WatchTesyt
* @Author: nanfeng
* @Date: 2021/1/20 21:10
* @Description: TODO
*/
public class WatchTest {
CuratorFramework client;
public WatchTest() {
client = CuratorUtils.getClient();
}
@Test
/*1:NodeCache 监听某一个特定的节点*/
public void testNodeCache() throws Exception {
//创建 NodeCache 对象
final NodeCache nodeCache = new NodeCache(client, "/nanfeng1");
//注册监听
nodeCache.getListenable().addListener(new NodeCacheListener()
{
@Override
public void nodeChanged() throws Exception {
//处理节点变化后的业务;
//类似触发器业务
System.out.println("发生改变了");
//获取修改后的数据
byte[] data = nodeCache.getCurrentData().getData();
System.out.println(Arrays.toString(data));
}
});
//开启监听,同时加载缓冲数据
nodeCache.start(true);
//设置死循环为了不断续监听
for (; ; ) {
}
}
/*2:PathChildreCache 监听一个 ZNode 的子节点,不包含本节点*/
public void testPathChildrenCache() throws Exception {
//创建监听器对象
PathChildrenCache pathChildrenCache = new
PathChildrenCache(client,"/nanfeng"/*监听对象*/,true/*缓存状态信息*/);
//绑定监听器
pathChildrenCache.getListenable().addListener(new
PathChildrenCacheListener() {
@Override
public void childEvent(CuratorFramework curatorFramework,
PathChildrenCacheEvent pathChildrenCacheEvent) throws Exception {
//发生变化后需要处理的业务代码
//触发某个信息
System.out.println("发生变化了");
//查看这个对象的状态
System.out.println(pathChildrenCacheEvent);
PathChildrenCacheEvent.Type type =
pathChildrenCacheEvent.getType();
//如果 type 是升级,就获取最新的数据
if
(type.equals(PathChildrenCacheEvent.Type.CHILD_UPDATED)){
//确认是升级了
System.out.println("升级了");
//获取最新的数据
byte[] data =
pathChildrenCacheEvent.getData().getData();
System.out.println(Arrays.toString(data));
}
}
});
//开启监听
pathChildrenCache.start();
//死循环为了查看,当真正部署到服务器不用使用这种
while (true){}
}
/*3:TreeCach 监听整个树的节点 */
public void testTreeCache() throws Exception {
//1. 创建监听器
TreeCache treeCache = new TreeCache(client,"/nanfeng");
//2. 注册监听
treeCache.getListenable().addListener(new TreeCacheListener()
{
@Override
public void childEvent(CuratorFramework client,
TreeCacheEvent event) throws Exception {
System.out.println("节点变化了");
System.out.println(event);
}
});
//3. 开启监听
treeCache.start();
while (true){
}}}
7 分布式锁
7 分布式锁
作用: 解决跨机器的进程之间的数据同步问题
实现分布式锁的三种方式:
(1) 基于 redis 的
图示:
实现原理:
前提说明 (每次执行的 key 访问 redis 消费者约定相同,因为在当前的服务执行完毕当前的
业务后会删除(即释放锁/超时),再次执行相同的键 设置值,会根据结果返回锁的获取结果)
1> 当第一个 client 来访问 redis 获取生产者信息数据时,redis 执行 setnx key value 同
时限制有效时间,(在限制了有效时间后即使当前的 client 宕机了,当有效时间过了,锁也会
自动被释放,控制不会产生死锁),
If(result=1){
执行业务
释放锁
}
//超时,自动释放
2 > 当第二个 client 再来访问 redis 时,执行 setnx key value
If(result=1){
执行业务
释放锁
} else{ 排队
}
3 >.......
(2) 基于数据库的
思想:让服务端去访问数据库,在数据库中设置一张表,每一有消费者访问数据库,请求
锁时,在特定的表中为其设置数据,消费者拿到锁后,去进行资源的访问,执行完毕后,释
放锁(中间会要设置消费者的数据的有效时间,过时自动清除消费者的请求信息),当后
面的消费者来请求锁时,先查询这张约存放锁信息的表,若是表中含有数据,排队,若是
表中没有数据则执行后续操作.......
(3) zookeeper 实现分布式锁的原理:
思想:客户端想要获取去访问资源, 先注册节点,执行完毕后,释放锁(即删除节点)
解析图:

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/439515.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

微信小程序php+vue 校园租房指南房屋租赁系统

本着诚信的原则&#xff0c;平台必须要掌握出租方必要的真实可信的信息&#xff0c;这样就可以防止欺诈事件的发生&#xff0c;事后也可以联系找到出租方。并且租金等各方面规范标准化&#xff0c;在这易租房诚信可信的平台让承租方与出租方充分有效对接&#xff0c;既方便了承…

扫清盲点:带你学习 树状数组 这种数据结构

什么是树状数组 树状数组是一种用于维护数列前缀和的数据结构&#xff0c;它可以在 O(logn) 的时间复杂度内修改单个元素的值&#xff0c;以及查询某个区间的元素和。 树状数组的特点是什么&#xff1f; 树状数组的特点其实就是&#xff0c;在单点修改 &#xff0c;和区间查询…

rancher2.7丢失集群信息

使用Docker 单节点安装rancher&#xff0c;然后在rancher中创建了一个k8s的集群。重启rancher所在的虚拟机后&#xff0c;登录rancher发现这是新的实例&#xff0c;集群信息丢失了。但是k8s集群还是好好的。 检查k8s的日志&#xff0c;api server日志会报错 time"2023-0…

11 - 多平台适配

多平台适配 11-1&#xff1a;开篇 在上一章中&#xff0c;我们知道了&#xff0c;当【慕课热搜】运行到 h5 端的时候&#xff0c;那么会出现一些问题&#xff0c;这些问题具体有&#xff1a; hot 列表滚动&#xff0c;tabs 置顶效果消失在火狐浏览器中&#xff0c;横线出现非…

kafka-kafka集群配置、kafka集群启动创建kafka主题、获取主题数据

本文章使用三台主机&#xff0c;分别为&#xff1a;master、slave1、slave2 一、解压kafka安装包至目录下 tar -zxvf kafka_2.12-2.4.1.tgz -C /需要放置的路径/ 二、修改配置文件 server.properties 该配置在kafka目录的config目录下 #修改文件中id数值 broker.id0 kafka集群…

Linux -- Web服务器-Apache 快速安装及主配置文件分析

目录 快速安装 Apache : 预处理 &#xff1a; 关闭安全上下文检测 : 关闭防火墙 : 启动 Apache 服务 &#xff08; 启动 httpd &#xff09;: 测试 &#xff1a; 主配置文件分析 &#xff1a; 常见配置文件所在位置 &#xff1a; 目录文件结构 &#xff1a;…

购物车--订单模块,练习完成

目标&#xff1a; 在购物车页面&#xff0c;增加一个创建订单的超链接。通过创建订单&#xff0c;在Order表里新增一条数据&#xff0c;同时把session中的订单条目都保存到数据库中。 1、创建两个表&#xff0c;orders用来具体存储每一个订单的细节&#xff0c;order_用来存储…

基于MobileNetV2的Transfer Learning模型,实现物体检测(附源码)

文章目录 一、MobileNet1. 深度可分离卷积&#xff08;Depthwise separable convolution&#xff09;2. MobileNet V13. MobileNet V2 二、物体检测源码&#xff08;基于MobileNetV2&#xff09; 一、MobileNet 1. 深度可分离卷积&#xff08;Depthwise separable convolution…

智慧园区综合管理平台开发基本功能有哪些?

随着智慧城市建设与信息化发展&#xff0c;园区管理也需要更加智能便捷化&#xff0c;于是智慧园区管理系统开发应运而生。智慧园区综合管理系统就是利用物联网、大数据等技术工具&#xff0c;顺应产业园区升级发展需求&#xff0c;实现园区环境、设备、安全、基础管理、资源服…

【Linux】进程间通信——命名管道

文章目录 命名管道1. 见一见管道文件mkfifo函数管道文件的使用 2. 命名管道原理如何保证两个毫不相关的进程&#xff0c;看到的是同一个文件&#xff0c;并打开&#xff1f; 3. 用命名管道实现server&client通信如何使用makefile连续生成可执行程序comm.hpp文件server.cc 服…

如何通过 Baklib 平台实现知识共享(内含案例介绍)

在这个信息时代&#xff0c;知识被认为是最重要的资源之一。企业要想保持发展&#xff0c;就必须善于利用和管理知识。而知识管理则是一种涵盖人、过程和技术的活动&#xff0c;它通过收集、整理、传递和应用知识&#xff0c;使组织获得更高的效率、创造力和竞争力。本文将以知…

【Linux】八、Linux进程信号详解(一)

目录 一、认识信号 1.1 生活中的信号 1.2 将1.1的概念迁移到进程 1.3 信号概念 1.4 查看系统定义信号列表 1.5 man 7 signal 1.6 解释1.2的代码样例 1.7 信号处理常见方式概览 二、产生信号 2.1 signal函数 2.2 通过终端按键产生信号 2.3 调用系统函数向进程发信号…

前后端的身份认证【Node.js】

1. 前后端的身份认证 1.1 Web 开发模式 目前主流的 Web 开发模式有两种&#xff0c;分别是&#xff1a; &#xff08;1&#xff09;基于服务端渲染的传统 Web 开发模式 &#xff08;2&#xff09;基于前后端分离的新型 Web 开发模式 服务端渲染的传统 Web 开发模式 服务端渲染…

力扣面试题 08.06. 汉诺塔问题:思路分析+图文详解+代码实现

文章目录 第一部分&#xff1a;问题描述1.1 题目1.2 示例&#x1f340; 示例一&#x1f340; 示例二 1.3 提示 第二部分&#xff1a;思路分析第三部分&#xff1a;代码实现 第一部分&#xff1a;问题描述 1.1 题目 &#x1f3e0; 链接&#xff1a;面试题 08.06. 汉诺塔问题 -…

windows安装rabbitmq和环境erlang(最详细版,包括对应关系)

写在最前&#xff1a;不知何时起安装一个mq需要翻无数文章才能安上了&#xff0c;没有一个讲全的&#xff0c;这里写一个详细的教程。 删除旧版本对应关系: 1.在官方文档中找到RabbitMQ版本对应的Erlang版本重新下载安装包文档RabbitMQ Erlang Version Requirements — Rabbit…

大家副业都在做什么?csgo搬砖靠谱的副业推荐给你

从来没想过&#xff0c;以前只会玩CSGO的男孩子&#xff0c;现在居然能借助游戏赚到钱了&#xff01;甚至不需要什么专业的技巧&#xff0c;简简单单 在steam平台选择有利润的道具后&#xff0c;再上架到国内网易BUFF平台&#xff0c;赚取“信息差”差价而已&#xff01; 谁大…

itop-3568开发板驱动学习笔记(19)内核工作队列

《【北京迅为】itop-3568开发板驱动开发指南.pdf》 学习笔记 文章目录 工作队列简介共享工作队列工作结构体初始化 work_struct调度工作队列函数共享工作队列实验 自定义工作队列创建工作队列函数调度和取消调度工作队列刷新工作队列函数删除工作队列函数 内核延时工作队列延时…

成功上岸字节35K,技术4面+HR面,耗时20天,真是不容易

这次字节的面试&#xff0c;给我的感触很深&#xff0c;意识到基础的重要性。一共经历了五轮面试&#xff1a;技术4面&#xff0b;HR面。 下面看正文 本人自动专业毕业&#xff0c;压抑了五个多月&#xff0c;终于鼓起勇气&#xff0c;去字节面试&#xff0c;下面是我的面试过…

kali利用airgeddon破解WiFi (详细安装和使用教程)

目录 前言 一&#xff0c;软件&硬件环境 二&#xff0c;前期配置 Airgeddon安装和调试 #自带 #安装方法一 #安装方法二 #注意 网卡的配置 #打开服务 #加载网卡 三&#xff0c;运行操作 #检查 #主菜单 #打开监听模式 #查看周围可以攻击的网络 #截取…

vue - - - - - vue3全局配置挂载axios

vue3配置axios 1. 安装axios2. 配置拦截器3. vue.config.js代理配置4. 将axios全局挂载4. 文件内使用 1. 安装axios yarn add axios 2. 配置拦截器 创建文件 /src/utils/request.js "use strict";import Vue from "vue"; import axios from "axios&…