网络文学网站开发/seo优化方式包括

网络文学网站开发,seo优化方式包括,php做网站首页的代码,爬虫网站开发zookeeper最初设计的初衷就是为了保证分布式系统的一致性。本文将讲解如何利用zookeeper的临时顺序结点,实现分布式锁。 目录 1. 理论分析 1.1 结点类型 1.2 监听器 1.3 实现原理 2. 手写实现简易zookeeper分布式锁 1.1 依赖 1.2 常量定义 1.3 实现zookeeper分布式…

        zookeeper最初设计的初衷就是为了保证分布式系统的一致性。本文将讲解如何利用zookeeper的临时顺序结点,实现分布式锁。

目录

1. 理论分析

        1.1 结点类型

        1.2 监听器

        1.3 实现原理

2. 手写实现简易zookeeper分布式锁

        1.1 依赖

         1.2 常量定义

        1.3 实现zookeeper分布式锁

        1.4 使用方式

3. 引入Curator框架实现zookeeper分布式锁

        2.1 框架依赖

        2.2 使用方式


1. 理论分析

        zookeeper 和Linux一样,采用目录树的方式管理结点,目录层级间以 / 区分

        每个数据节点在 ZooKeeper 中被称为 znode,它是 ZooKeeper 中数据的最小单元。由于ZooKeeper 主要用于协调服务,出于性能和一致性考虑,每个节点的存放数据上限为1M

     

        1.1 结点类型

        znode有四种类型:

        1.持久化结点  (PERSISTENT): 创建节点后一直存在

        2. 持久化有序结点(PERSISTENT_SEQUENTIAL):在持久化结点的基础上,zookeeper会自动根据创建顺序,在结点名称后面加上一串序号

        3. 临时结点(EPHEMERAL):在zookeeper与客户端失去连接后自动删除

        4. 临时有序结点(EPHEMERAL_SEQUENTIAL):在临时结点的基础上,zookeeper会自动根据创建顺序,在结点名称后面加上一串序号

        1.2 监听器

                Watcher 监听机制是 Zookeeper 中非常重要的特性。结点可以绑定监听事件,当监听事件发生的时候,Zookeeper会向客户端发送通知事件,执行监听器的回调方法。

        

        1.3 实现原理

        我们首先新建一个"/locks"的持久化结点,用来管理表示锁的子节点。(实际场景使用可以根据不同锁对象划分成更细致的持久化结点,比如"/locks/bilibili/comment/publish")

        当用户尝试获取锁的时候,在"locks"结点下新建一个临时有序结点,例如"seq-00001"

        新建结点成功后,系统进行检查,建立的结点是否是当前所有子节点中序号最小的一个

        如果是最小的一个,说明用户是当前锁的持有者,往下执行业务逻辑,执行完成后摧毁临时结点

        ​​​​​​​

        如果不是最小的一个,为了避免不断地自旋检查空耗性能,一般采用注册监听器的方式减少性能消耗:监听前一个结点的摧毁事件。如果用户持有的结点前面还有其他结点,说明用户不是持有的人,不能执行业务逻辑,应当阻塞等待;直到用户前一个结点被摧毁,说明轮到用户持有锁了,可以继续往下执行业务逻辑。

        

2. 手写实现简易zookeeper分布式锁

        1.1 依赖

        <dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>RELEASE</version><scope>test</scope></dependency><!--日志--><dependency><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-core</artifactId><version>2.8.2</version></dependency><!--zookeeper--><dependency><groupId>org.apache.zookeeper</groupId><artifactId>zookeeper</artifactId><version>3.5.6</version></dependency><dependency><groupId>org.junit.jupiter</groupId><artifactId>junit-jupiter</artifactId><version>RELEASE</version><scope>compile</scope></dependency>

         1.2 常量定义

public interface ZkConstants {//连接地址String connectString = "127.0.0.1:2181";// 连接超时时间int sessionTimeout = 2000;
}

        1.3 实现zookeeper分布式锁

public class DistributedLock {// zk客户端连接private ZooKeeper zkClient;// 连接成功等待private CountDownLatch connectLatch = new CountDownLatch(1);// 前一个结点(锁)private String waitPath;// 结点删除等待private CountDownLatch waitLatch = new CountDownLatch(1);// 当前创建的结点(锁)private String createNode;/*** 构造方法:初始化客户端连接** @throws IOException* @throws InterruptedException* @throws KeeperException*/public DistributedLock() throws IOException, InterruptedException, KeeperException {//获取连接zkClient = new ZooKeeper(ZkConstants.connectString, ZkConstants.sessionTimeout, new Watcher() {@Overridepublic void process(WatchedEvent watchedEvent) {//连接成功,释放countDownLatchif (watchedEvent.getState() == Event.KeeperState.SyncConnected) {connectLatch.countDown();}//前一个结点删除if (watchedEvent.getType() == Event.EventType.NodeDeleted && watchedEvent.getPath().equals(waitPath)) {//解锁下一个结点waitLatch.countDown();}}});//等待zk正常连接后,再往下执行connectLatch.await();//判断根节点/locks是否存在Stat exists = zkClient.exists("/locks", false);if (exists == null) {//创建根节点 -- 持久结点zkClient.create("/locks", "locks".getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);}}/*** 加锁** @throws InterruptedException* @throws KeeperException*/public void zkLock() throws InterruptedException, KeeperException {//创建对应的临时带序号结点createNode = zkClient.create("/locks/" + "seq-", null, ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL_SEQUENTIAL);//判断创建节点是否是序号最小的结点List<String> children = zkClient.getChildren("/locks", false);if (children.size() == 1) {return;} else {//排序结点以得到当前创建结点的序号(等待锁的序位)Collections.sort(children);//获取生成的临时结点序号String thisNode = createNode.substring("/locks/".length());//获得排序int index = children.indexOf(thisNode);if (index == -1) {System.out.println("数据异常");} else if (index == 0) {//最小序号结点,直接获取锁return;} else {//监听序号前一个结点waitPath = "/locks/" + children.get(index - 1);//true代表使用创建zkClient时初始化的监听器zkClient.getData(waitPath, true, null);waitLatch.await();}}}/*** 解锁** @throws InterruptedException* @throws KeeperException*/public void zkUnLock() throws InterruptedException, KeeperException {//删除临时带序号结点zkClient.delete(createNode, -1);}}

        1.4 使用方式

public class DistributedLockTest {public static void main(String[] args) throws IOException, InterruptedException, KeeperException {ExecutorService executorService = Executors.newFixedThreadPool(2);DistributedLock lock1 = new DistributedLock();DistributedLock lock2 = new DistributedLock();//多线程获取锁1CompletableFuture.supplyAsync(() -> {try {lock1.zkLock();System.out.println("线程" + Thread.currentThread().getName() + "获取到锁......");Thread.sleep(5000);lock1.zkUnLock();System.out.println("线程" + Thread.currentThread().getName() + "释放锁......");} catch (InterruptedException e) {throw new RuntimeException(e);} catch (KeeperException e) {throw new RuntimeException(e);}return true;}, executorService);//多线程获取锁2CompletableFuture.supplyAsync(() -> {try {lock2.zkLock();System.out.println("线程" + Thread.currentThread().getName() + "获取到锁......");Thread.sleep(5000);lock2.zkUnLock();System.out.println("线程" + Thread.currentThread().getName() + "释放锁......");} catch (InterruptedException e) {throw new RuntimeException(e);} catch (KeeperException e) {throw new RuntimeException(e);}return true;}, executorService);executorService.shutdown();}
}

3. 引入Curator框架实现zookeeper分布式锁

        实际生产环境下,自然不可能手写这么多代码处理分布式锁,且不提很多地方的代码可复用,CountDownLatch反复处理带来的代码复杂性高,并且一些可重入锁、异常处理等逻辑上文也并没有完善。

        生产场景中被广泛使用的zookeeper分布式锁的框架便是Curator

        2.1 框架依赖

        /..省略../<!--Curator--><dependency><groupId>org.apache.curator</groupId><artifactId>curator-framework</artifactId><version>4.3.0</version></dependency><dependency><groupId>org.apache.curator</groupId><artifactId>curator-recipes</artifactId><version>4.3.0</version></dependency><dependency><groupId>org.apache.curator</groupId><artifactId>curator-client</artifactId><version>4.3.0</version></dependency>

        2.2 使用方式

public class CuratorLockTest {public static void main(String[] args) {//创建分布式锁1InterProcessLock lock1 = new InterProcessMutex(getCuratorFramework(), "/locks");InterProcessLock lock2 = new InterProcessMutex(getCuratorFramework(), "/locks");ExecutorService executorService = Executors.newFixedThreadPool(2);executorService.execute(() -> {try {lock1.acquire();System.out.println("线程1获取到锁");//curator支持可重入锁lock1.acquire();System.out.println("线程1 再次获取到锁");Thread.sleep(5000);lock1.release();System.out.println("线程1 释放锁");lock1.release();System.out.println("线程1 再次释放锁");} catch (Exception e) {throw new RuntimeException(e);}});executorService.execute(() -> {try {lock2.acquire();System.out.println("线程2获取到锁");lock2.acquire();System.out.println("线程2 再次获取到锁");Thread.sleep(5000);lock2.release();System.out.println("线程2 释放锁");lock2.release();System.out.println("线程2 再次释放锁");} catch (Exception e) {throw new RuntimeException(e);}});executorService.shutdown();}public static CuratorFramework getCuratorFramework() {//4秒超时,重试3次ExponentialBackoffRetry exponentialBackoffRetry = new ExponentialBackoffRetry(4000, 3);CuratorFramework client = CuratorFrameworkFactory.builder().connectString(ZkConstants.connectString).connectionTimeoutMs(ZkConstants.sessionTimeout).sessionTimeoutMs(ZkConstants.sessionTimeout).retryPolicy(exponentialBackoffRetry).build();client.start();System.out.println("zookeeper 启动成功...");return client;}
}

        希望能对大家理解zookeeper分布式锁有所帮助

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

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

相关文章

Git是什么

简单介绍&#xff1a; Git是一个分布式版本控制系统&#xff0c;用于跟踪文件的更改&#xff0c;特别是在多人协作开发的环境中。 Key: 分布式 版本控制 系统 最常用于软件开发&#xff0c;但也可以用于管理任何类型的文件和文件夹。 Git帮助团队跟踪和管理文件的历史版本&a…

Pycharm 2024在解释器提供的python控制台中运行py文件

2024版的界面发生了变化, run with python console搬到了这里:

【分布式理论12】事务协调者高可用:分布式选举算法

文章目录 一、分布式系统中事务协调的问题二、分布式选举算法1. Bully算法2. Raft算法3. ZAB算法 三、小结与比较 一、分布式系统中事务协调的问题 在分布式系统中&#xff0c;常常有多个节点&#xff08;应用&#xff09;共同处理不同的事务和资源。前文 【分布式理论9】分布式…

免费deepseek的API获取教程及将API接入word或WPS中

免费deepseek的API获取教程: 1 https://cloud.siliconflow.cn/中注册时填写邀请码&#xff1a;GAejkK6X即可获取2000 万 Tokens; 2 按照图中步骤进行操作 将API接入word或WPS中 1 打开一个word&#xff0c;文件-选项-自定义功能区-勾选开发工具-左侧的信任中心-信任中心设置…

【SFRA】笔记

GK_SFRA_INJECT(x) SFRA小信号注入函数,向控制环路注入一个小信号。如下图所示,当前程序,小信号注入是在固定占空比的基础叠加小信号,得到新的占空比,使用该占空比控制环路。 1.2 GK_SFRA_COLLECT(x, y) SFRA数据收集函数,将小信号注入环路后,该函数收集环路的数据,以…

论文笔记-WSDM2024-LLMRec

论文笔记-WSDM2024-LLMRec: Large Language Models with Graph Augmentation for Recommendation LLMRec: 基于图增强的大模型推荐摘要1.引言2.前言2.1使用图嵌入推荐2.2使用辅助信息推荐2.3使用数据增强推荐 3.方法3.1LLM作为隐式反馈增强器3.2基于LLM的辅助信息增强3.2.1用户…

Ubuntu 系统 cuda12.2 安装 MMDetection3D

DataBall 助力快速掌握数据集的信息和使用方式&#xff0c;会员享有 百种数据集&#xff0c;持续增加中。 需要更多数据资源和技术解决方案&#xff0c;知识星球&#xff1a; “DataBall - X 数据球(free)” 贵在坚持&#xff01; ---------------------------------------…

华为昇腾 910B 部署 DeepSeek-R1 蒸馏系列模型详细指南

本文记录 在 华为昇腾 910B(65GB) * 8 上 部署 DeepSeekR1 蒸馏系列模型&#xff08;14B、32B&#xff09;全过程与测试结果。 NPU&#xff1a;910B3 (65GB) * 8 &#xff08;910B 有三个版本 910B1、2、3&#xff09; 模型&#xff1a;DeepSeek-R1-Distill-Qwen-14B、DeepSeek…

【前端】Vue组件库之Element: 一个现代化的 UI 组件库

文章目录 前言一、官网1、官网主页2、设计原则3、导航4、组件 二、核心功能&#xff1a;开箱即用的组件生态1、丰富的组件体系2、特色功能亮点 三、快速上手&#xff1a;三步开启组件化开发1、安装&#xff08;使用Vue 3&#xff09;2、全局引入3、按需导入&#xff08;推荐&am…

关于uniApp的面试题及其答案解析

我的血液里流淌着战意&#xff01;力量与智慧指引着我&#xff01; 文章目录 1. 什么是uniApp&#xff1f;2. uniApp与原生小程序开发有什么区别&#xff1f;3. 如何使用uniApp实现条件编译&#xff1f;4. uniApp支持哪些平台&#xff0c;各有什么特点&#xff1f;5. 在uniApp中…

力扣 最长递增子序列

动态规划&#xff0c;二分查找。 题目 由题&#xff0c;从数组中找一个最长子序列&#xff0c;不难想到&#xff0c;当这个子序列递增子序列的数越接近时是越容易拉长的。从dp上看&#xff0c;当遍历到这个数&#xff0c;会从前面的dp选一个最大的数加上当前数&#xff0c;注意…

Linux | 进程控制(进程终止与进程等待)

文章目录 Linux | 进程控制 — 进程终止 & 进程等待1、进程终止进程常见退出方法1.1退出码基本概念获取退出码的方式常见退出码约定使用场景 1.2 strerror函数 & errno宏1.3 _exit函数1.4_exit和exit的区别1.4.1 所属头文件与函数原型1.4.2 执行过程差异**结合现象分析…

DeepSeek应用——与PyCharm的配套使用

目录 一、配置方法 二、使用方法 三、注意事项 1、插件市场无continue插件 2、无结果返回&#xff0c;且在本地模型报错 记录自己学习应用DeepSeek的过程&#xff0c;使用的是自己电脑本地部署的私有化蒸馏模型...... &#xff08;举一反三&#xff0c;这个不单单是可以用…

2025最新智能优化算法:改进型雪雁算法(Improved Snow Geese Algorithm, ISGA)求解23个经典函数测试集,MATLAB

一、改进型雪雁算法 雪雁算法&#xff08;Snow Geese Algorithm&#xff0c;SGA&#xff09;是2024年提出的一种新型元启发式算法&#xff0c;其灵感来源于雪雁的迁徙行为&#xff0c;特别是它们在迁徙过程中形成的独特“人字形”和“直线”飞行模式。该算法通过模拟雪雁的飞行…

MySQL 主从复制原理及其工作过程

一、MySQL主从复制原理 MySQL 主从复制是一种将数据从一个 MySQL 数据库服务器&#xff08;主服务器&#xff0c;Master&#xff09;复制到一个或多个 MySQL 数据库服务器&#xff08;从服务器&#xff0c;Slave&#xff09;的技术。以下简述其原理&#xff0c;主要包含三个核…

【赵渝强老师】Spark RDD的缓存机制

Spark RDD通过persist方法或cache方法可以将计算结果的缓存&#xff0c;但是并不是这两个方法被调用时立即缓存&#xff0c;而是触发后面的action时&#xff0c;该RDD才会被缓存在计算节点的内存中并供后面重用。下面是persist方法或cache方法的函数定义&#xff1a; def pers…

ShenNiusModularity项目源码学习(9:项目结构)

ShenNiusModularity源码主要有11个project&#xff08;其实还有officialweb、test两个文件夹&#xff0c;大致有4、5个project&#xff0c;但看着跟主要项目代码没太大关系&#xff0c;暂时不管&#xff09;&#xff0c;这11个project的依赖关系如下图所示&#xff0c;其中最下…

Docker 部署 ollama + DeepSeek

拉取并运行 Ollama Docker 镜像 使用以下命令从 Docker Hub 拉取 Ollama 镜像并运行容器&#xff1a; docker run -d -p 11434:11434 --name ollama ollama/ollama -d&#xff1a;以守护进程模式运行容器&#xff0c;即让容器在后台运行。-p 11434:11434&#xff1a;将容器内…

解决DeepSeek服务器繁忙的有效方法

全球42%的企业遭遇过AI工具服务器过载导致内容生产中断&#xff08;数据来源&#xff1a;Gartner 2025&#xff09;。当竞品在凌晨3点自动发布「智能家居安装指南」时&#xff0c;你的团队可能正因DeepSeek服务器繁忙错失「净水器保养教程」的流量黄金期⏳。147SEO智能调度系统…

【有啥问啥】DeepSeek 技术原理详解

DeepSeek 技术原理详解 DeepSeek 是一款具有突破性技术的大型语言模型&#xff0c;其背后的技术原理涵盖了多个方面&#xff0c;以下是对其主要技术原理的详细介绍&#xff1a; 架构创新 多头潜在注意力机制&#xff08;MLA&#xff09; 传送门链接: DeepSeek V3中的Multi-…