<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
    <channel>
        <title>NotionNext BLOG</title>
        <link>https://antonyzhang.cn/</link>
        <description>这是一个由NotionNext生成的站点</description>
        <lastBuildDate>Mon, 18 Nov 2024 04:26:36 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <language>zh-CN</language>
        <copyright>All rights reserved 2024, Antony_Zhang</copyright>
        <item>
            <title><![CDATA[《云计算平台与技术》｜大作业]]></title>
            <link>https://antonyzhang.cn/article/cloudcrouse-final</link>
            <guid>https://antonyzhang.cn/article/cloudcrouse-final</guid>
            <pubDate>Mon, 18 Nov 2024 00:00:00 GMT</pubDate>
            <description><![CDATA[被Docker镜像折磨的时光]]></description>
            <content:encoded><![CDATA[被Docker镜像折磨的时光]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[《云计算平台与技术》｜实验二：Zookeeper Curator]]></title>
            <link>https://antonyzhang.cn/article/cloudcrouse-2</link>
            <guid>https://antonyzhang.cn/article/cloudcrouse-2</guid>
            <pubDate>Mon, 18 Nov 2024 00:00:00 GMT</pubDate>
            <content:encoded><![CDATA[<div id="notion-article" class="mx-auto overflow-hidden "><main class="notion light-mode notion-page notion-block-1429f73cea45809fa21be3b11ecc6cf8"><div class="notion-viewport"></div><div class="notion-collection-page-properties"></div><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-1429f73cea458045b778cbc6727a147e" data-id="1429f73cea458045b778cbc6727a147e"><span><div id="1429f73cea458045b778cbc6727a147e" class="notion-header-anchor"></div><a class="notion-hash-link" href="#1429f73cea458045b778cbc6727a147e" title="题目一：Zookeeper Curator实现生产者消费者模型"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">题目一：Zookeeper Curator实现生产者消费者模型</span></span></h3><blockquote class="notion-quote notion-block-1429f73cea45807d8138eab2c2f19bb0"><div>[!cite]- 题目
在分布式系统中，生产者消费者模型是一种常用的设计模式，其中生产者生成数据并放入缓冲区，消费者从缓冲区取出数据进行处理。在一个多线程或者多进程的环境中，同步和互斥是保证数据一致性的关键。请使用Apache Curator框架中提供的高级API来实现这个模型，并使用Zookeeper来完成同步和互斥。</div><ul class="notion-list notion-list-disc notion-block-1429f73cea4580ef86fbe779eb1fba8a"><li>题目要求</li><ul class="notion-list notion-list-disc notion-block-1429f73cea4580ef86fbe779eb1fba8a"><li>使用Java语言编写程序。</li><li>通过Zookeeper Curator的InterProcessMutex实现互斥，确保生产者和消费者在访问共享资源时的同步。</li><li>共享资源可以是一个在Zookeeper中维护的计数器，代表缓冲区中的项目数量。</li><li>生产者应当在缓冲区不满时添加项目，并更新计数器。</li><li>消费者应当在缓冲区不空时消费项目，并更新计数器。</li><li>请处理好异常情况，如Zookeeper连接中断等。</li></ul></ul><ul class="notion-list notion-list-disc notion-block-1429f73cea45800890a4db2c23dbd840"><li>预期输出（控制台输出包含本人的标识信息，比如学号或姓名等）</li></ul><ul class="notion-list notion-list-disc notion-block-1429f73cea45803aa2dee9775b8c199b"><li>程序应当能够在多线程或多进程环境下无误地运行。</li><ul class="notion-list notion-list-disc notion-block-1429f73cea45803aa2dee9775b8c199b"><li>当生产者生产数据时，消费者能够正确消费数据，且整个过程中共享资源的访问应该是同步的。</li></ul></ul></blockquote><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-1429f73cea45805e8efbd375e661879e" data-id="1429f73cea45805e8efbd375e661879e"><span><div id="1429f73cea45805e8efbd375e661879e" class="notion-header-anchor"></div><a class="notion-hash-link" href="#1429f73cea45805e8efbd375e661879e" title="1 环境配置"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">1 环境配置</span></span></h4><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-1429f73cea458046992ed31b45d52559" data-id="1429f73cea458046992ed31b45d52559"><span><div id="1429f73cea458046992ed31b45d52559" class="notion-header-anchor"></div><a class="notion-hash-link" href="#1429f73cea458046992ed31b45d52559" title="1.1 安装ZooKeeper"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">1.1 安装ZooKeeper</span></span></h4><div class="notion-text notion-block-1429f73cea4580f8bc84ca15880a26df"><a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://zhuanlan.zhihu.com/p/466902641">知乎｜mac（m1版）环境下zookeeper安装使用</a></div><div class="notion-text notion-block-1429f73cea4580b19f5fc7c03a2efad0">在官网(<a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://zookeeper.apache.org/releases.html">https://zookeeper.apache.org/releases.html</a>) 下载3.8.4的压缩包，解压后移动到<code class="notion-inline-code">/usr/local</code>文件夹下。</div><div class="notion-text notion-block-1429f73cea4580af8177e8d7b4febdac">进入目录<code class="notion-inline-code">/usr/local/apache-zookeeper-3.8.4-bin/conf</code>，将文件<code class="notion-inline-code">zoo_sample.cfg</code>改名为<code class="notion-inline-code">zoo.cfg</code>。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-1429f73cea4580dab6dbfee4bc96347f" data-id="1429f73cea4580dab6dbfee4bc96347f"><span><div id="1429f73cea4580dab6dbfee4bc96347f" class="notion-header-anchor"></div><a class="notion-hash-link" href="#1429f73cea4580dab6dbfee4bc96347f" title="1.2 安装Maven+配置VSCode"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">1.2 安装Maven+配置VSCode</span></span></h4><div class="notion-text notion-block-1429f73cea45802abde4ebf142aa90f6">官网下载Maven二进制压缩包<code class="notion-inline-code">apache-maven-3.9.6</code>，解压并移动到<code class="notion-inline-code">/usr/local/</code>目录。</div><div class="notion-text notion-block-1429f73cea458077bca6d1d2be722416">配置环境变量，执行<code class="notion-inline-code">vim ~/.bash_profile</code>并在末尾加入：</div><div class="notion-text notion-block-1429f73cea4580e987c3c7865819467e">保存退出后执行<code class="notion-inline-code">source ~/.bash_profile</code>更新配置。</div><div class="notion-text notion-block-1429f73cea45807795b3dcd75e37d19a">之后参考<a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://blog.csdn.net/szm1234/article/details/129559888">CSDN｜使用VSCode实现Java项目管理 Maven相关插件及配置（Maven换源）</a>，将仓库地址更改为<code class="notion-inline-code">/usr/local/apache-maven-repository/repository</code>，并配置VSCode插件“Maven for Java”。</div><div class="notion-text notion-block-1429f73cea458003a1e2cb5d0b01a83b">在VSCode主页，点击左栏“新建JAVA项目”，使用Maven创建一个初始项目“<b>producer-consumer</b>”。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-1429f73cea4580b5b5e7f2684e8015e7" data-id="1429f73cea4580b5b5e7f2684e8015e7"><span><div id="1429f73cea4580b5b5e7f2684e8015e7" class="notion-header-anchor"></div><a class="notion-hash-link" href="#1429f73cea4580b5b5e7f2684e8015e7" title="1.3 导入Curator"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">1.3 导入Curator</span></span></h4><div class="notion-text notion-block-1429f73cea458059afd9d9753fd5d8f6"><a target="_blank" rel="noopener noreferrer" class="notion-link" href="https://blog.csdn.net/smilehappiness/article/details/105938058">CSDN｜Zookeeper客户端ZkClient、Curator的使用，史上最详细的教程来啦~</a></div><div class="notion-text notion-block-1429f73cea4580838889e3020b307b16">修改VSCode项目中的<code class="notion-inline-code">pom.xml</code>文件，加入依赖：</div><div class="notion-text notion-block-1429f73cea45804a8c83c4f4f2dc455c">之后终端进入项目“<b>producer-consumer</b>”根目录，更新依赖项：</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-1429f73cea4580e79270ead563ec6dd5" data-id="1429f73cea4580e79270ead563ec6dd5"><span><div id="1429f73cea4580e79270ead563ec6dd5" class="notion-header-anchor"></div><a class="notion-hash-link" href="#1429f73cea4580e79270ead563ec6dd5" title="2 运行"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">2 运行</span></span></h4><div class="notion-text notion-block-1429f73cea458083bd36f9c3186291f6">在项目“<b>producer-consumer</b>”中完成代码编写后，打开终端启动zookeeper服务：</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-1429f73cea4580d1a05ef7ac1f4fff51"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2F3aee0da3-5022-4762-b657-ee960b3be54c%2Fac6ae522-6e42-4877-bb16-318a75992b8d%2Fzookeeper%25E8%25BF%2590%25E8%25A1%258C%25E6%2588%25AA%25E5%259B%25BE.png?table=block&amp;id=1429f73c-ea45-80d1-a05e-f7ac1f4fff51&amp;t=1429f73c-ea45-80d1-a05e-f7ac1f4fff51" alt="notion image" loading="lazy" decoding="async"/></div></figure><div class="notion-text notion-block-1429f73cea45805e8337ee60bfc5c1c1">可知本地zookeeper服务端的端口为<code class="notion-inline-code">localhost:2181</code></div><div class="notion-text notion-block-1429f73cea4580739521c9d7dae10d63">运行项目“<b>producer-consumer</b>”，并手动开关zookeeper服务，终端输出如下：</div><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-1429f73cea4580028816e19046acd8bb"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:100%;max-width:100%;flex-direction:column;height:100%"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2F3aee0da3-5022-4762-b657-ee960b3be54c%2F5a2dfab9-2010-48b4-8786-a83b1106cc43%2F%25E6%2589%258B%25E5%258A%25A8%25E5%25BC%2580%25E5%2585%25B3zookeeper.png?table=block&amp;id=1429f73c-ea45-8002-8816-e19046acd8bb&amp;t=1429f73c-ea45-8002-8816-e19046acd8bb" alt="手动开关zookeeper" loading="lazy" decoding="async"/><figcaption class="notion-asset-caption">手动开关zookeeper</figcaption></div></figure><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-1429f73cea4580da8382fb460f9d0e72"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:288px;max-width:100%;flex-direction:column"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2F3aee0da3-5022-4762-b657-ee960b3be54c%2F30acccd8-cd78-48fd-82d6-11ad4b3b866f%2Fzookeeper%25E5%25AE%25A2%25E6%2588%25B7%25E7%25AB%25AF%25E6%2598%25BE%25E7%25A4%25BA%25E8%258A%2582%25E7%2582%25B9.png?table=block&amp;id=1429f73c-ea45-80da-8382-fb460f9d0e72&amp;t=1429f73c-ea45-80da-8382-fb460f9d0e72" alt="zookeeper客户端显示节点" loading="lazy" decoding="async"/><figcaption class="notion-asset-caption">zookeeper客户端显示节点</figcaption></div></figure><figure class="notion-asset-wrapper notion-asset-wrapper-image notion-block-1429f73cea458042aad6cd14924f20b5"><div style="position:relative;display:flex;justify-content:center;align-self:center;width:192px;max-width:100%;flex-direction:column"><img style="object-fit:cover" src="https://www.notion.so/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2F3aee0da3-5022-4762-b657-ee960b3be54c%2Fadea918c-9b9e-47b5-a185-926f36784130%2Fjava%25E9%25A1%25B9%25E7%259B%25AE%25E7%25BB%2588%25E7%25AB%25AF%25E6%2588%25AA%25E5%259B%25BE%25EF%25BC%2588zookeeper%25E7%2594%259F%25E4%25BA%25A7%25E8%2580%2585%25E6%25B6%2588%25E8%25B4%25B9%25E8%2580%2585%25EF%25BC%2589.png?table=block&amp;id=1429f73c-ea45-8042-aad6-cd14924f20b5&amp;t=1429f73c-ea45-8042-aad6-cd14924f20b5" alt="java项目终端截图（zookeeper生产者消费者）" loading="lazy" decoding="async"/><figcaption class="notion-asset-caption">java项目终端截图（zookeeper生产者消费者）</figcaption></div></figure><h3 class="notion-h notion-h2 notion-h-indent-0 notion-block-1429f73cea4580ab8e26e1adaec5e3ba" data-id="1429f73cea4580ab8e26e1adaec5e3ba"><span><div id="1429f73cea4580ab8e26e1adaec5e3ba" class="notion-header-anchor"></div><a class="notion-hash-link" href="#1429f73cea4580ab8e26e1adaec5e3ba" title="题目二：Curator Recipes数据结构和锁的使用"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">题目二：Curator Recipes数据结构和锁的使用</span></span></h3><blockquote class="notion-quote notion-block-1429f73cea458095a9ebe4865dc537ed"><div>[!cite]- 题目
Apache Curator是一个Zookeeper的客户端库，它包含了一系列简化Zookeeper使用的recipes。请描述以下至少三个Curator提供的锁或者其他数据结构，它们的原理以及在实际场景中的使用。</div><ul class="notion-list notion-list-disc notion-block-1429f73cea45807ba12ec050762b9e73"><li>题目要求</li><ul class="notion-list notion-list-disc notion-block-1429f73cea45807ba12ec050762b9e73"><li>选择并描述Curator Recipes中的queue或者barriers中的一种。</li><li>说明选定数据结构的工作原理。</li><li>提供实际的使用场景例子。</li><li>简述在这些场景中，这些数据结构如何使用。</li></ul></ul></blockquote><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-1429f73cea4580a4aad1c819c3596f1b" data-id="1429f73cea4580a4aad1c819c3596f1b"><span><div id="1429f73cea4580a4aad1c819c3596f1b" class="notion-header-anchor"></div><a class="notion-hash-link" href="#1429f73cea4580a4aad1c819c3596f1b" title="2.1 Queue: DistributedQueue"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">2.1 Queue: DistributedQueue</span></span></h4><div class="notion-text notion-block-1429f73cea4580c5a28aebc4e2ddfe0f">Curator实现的一种分布式队列数据结构</div><blockquote class="notion-quote notion-block-1429f73cea4580d796c9f43d304492dd"><div>注意，官方建议不使用Zookeeper来创建队列，因为zk的每个节点都有1MB的大小限制，但实际使用的队列中往往存放很多消息；而如果一个节点下有上千个子节点，也会严重降低运行性能</div></blockquote><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-1429f73cea4580cd951bfd6aa00193ca" data-id="1429f73cea4580cd951bfd6aa00193ca"><span><div id="1429f73cea4580cd951bfd6aa00193ca" class="notion-header-anchor"></div><a class="notion-hash-link" href="#1429f73cea4580cd951bfd6aa00193ca" title="数据结构"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">数据结构</span></span></h4><div class="notion-text notion-block-1429f73cea4580778a50d03825f31cbd">根据Apache Curator官方文档，通过构建器QueueBuilder构建Distributed Queue实例，参数成员如下——</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-1429f73cea45801ca5dac843e605e39f" data-id="1429f73cea45801ca5dac843e605e39f"><span><div id="1429f73cea45801ca5dac843e605e39f" class="notion-header-anchor"></div><a class="notion-hash-link" href="#1429f73cea45801ca5dac843e605e39f" title="工作原理"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">工作原理</span></span></h4><div class="notion-text notion-block-1429f73cea4580d3aed4c3c726b5679a"><code class="notion-inline-code">DistributedQueue</code>将队列的元素存储在Zookeeper的<b>有序临时节点</b>中，使用ZooKeeper的<b>Watch</b>机制监听队列的变化，并且维护一个特殊的<code class="notion-inline-code">ều</code>持久节点来标识队列状态，确保队列路径非空而防止队列被强制删除。</div><div class="notion-text notion-block-1429f73cea458039b52aeb8608f11187">对于每个新创建的有序临时节点，Zookeeper都会通过递增的计数器值为其分配节点名，因此<em>节点序号能够表示队列元素的先后顺序</em>（最小编号的节点对应队列头部的元素,而最大编号的节点对应队列尾部的元素）。如此，便可以利用有序节点的特性来模拟队列的入队、出队操作。</div><div class="notion-text notion-block-1429f73cea458068b51bf00f58ece3c6">入队时，会先在路径下创建一个新的临时节点，将新元素的内容序列化并存储在这个新节点的数据中。</div><div class="notion-text notion-block-1429f73cea45807fa761f305af33ae8f">出队时，会先获取路径下所有现有子节点的列表，按照节点序号从小到大排列，并取出最小序号的节点（即队首），读取其中的元素数据（即反序列化），并将这个节点删除。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-1429f73cea458006a78de2ca747b3015" data-id="1429f73cea458006a78de2ca747b3015"><span><div id="1429f73cea458006a78de2ca747b3015" class="notion-header-anchor"></div><a class="notion-hash-link" href="#1429f73cea458006a78de2ca747b3015" title="示例：分布式任务调度"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">示例：分布式任务调度</span></span></h4><div class="notion-text notion-block-1429f73cea458048b228d01a63bc839c">假设有一个分布式的任务调度系统，有一个负责任务接收和分发的调度节点（Scheduler）和多个负责执行和结果报告的工作节点（Worker）。</div><div class="notion-text notion-block-1429f73cea458007a3b6c0294e5a61e5">Scheduler创建一个<code class="notion-inline-code">DistributedQueue</code>实例并维护，每当接收新任务，就调用<code class="notion-inline-code">queue.put()</code>将任务入队，<code class="notion-inline-code">DistributedQueue</code>会创建新的有序临时节点，以存储任务内容。</div><div class="notion-text notion-block-1429f73cea4580288dd4e35062326b70">每次Worker调用<code class="notion-inline-code">queue.remove()</code>将一个任务出队，<code class="notion-inline-code">DistributedQueue</code>获取最小编号节点即首节点，将其中的任务内容返回Worker，并删除该节点。若当前队列为空，则Worker阻塞等待，直到有新的任务加进来。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-1429f73cea4580e4b7d3ec553aa83ebd" data-id="1429f73cea4580e4b7d3ec553aa83ebd"><span><div id="1429f73cea4580e4b7d3ec553aa83ebd" class="notion-header-anchor"></div><a class="notion-hash-link" href="#1429f73cea4580e4b7d3ec553aa83ebd" title="2.2 Barrier: DistributedBarrier"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">2.2 Barrier: DistributedBarrier</span></span></h4><div class="notion-text notion-block-1429f73cea4580f79a31fc9d3fa33a97">Curator实现的一种分布式同步机制（屏障），用于阻止一系列进程的执行过程，直到某个条件得到满足。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-1429f73cea4580608bc1d659d75c9011" data-id="1429f73cea4580608bc1d659d75c9011"><span><div id="1429f73cea4580608bc1d659d75c9011" class="notion-header-anchor"></div><a class="notion-hash-link" href="#1429f73cea4580608bc1d659d75c9011" title="数据结构"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">数据结构</span></span></h4><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-1429f73cea4580d29718cd4bf175f9aa" data-id="1429f73cea4580d29718cd4bf175f9aa"><span><div id="1429f73cea4580d29718cd4bf175f9aa" class="notion-header-anchor"></div><a class="notion-hash-link" href="#1429f73cea4580d29718cd4bf175f9aa" title="工作原理"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">工作原理</span></span></h4><div class="notion-text notion-block-1429f73cea4580f0aa64d9d3d0491d75"><code class="notion-inline-code">DistributedBarrier</code>通过Zookeeper的<b>有序临时节点</b>来计数屏障中的等待进程，也同样使用ZooKeeper的<b>Watch</b>机制监听队列的变化。</div><div class="notion-text notion-block-1429f73cea4580c282d5c75b353ce6d2">首先，在指定路径下创建一个持久节点作为barrier的根路径节点，并指定大小参数N（需要等待的进程数）。</div><div class="notion-text notion-block-1429f73cea4580798eacf38f852c42fd">当某进程想要加入屏障时，调用<code class="notion-inline-code">enter()</code>在指定路径下创建一个有序临时节点，写入屏障大小N并在根节点注册一个监听器Watcher，以监听其他进程改变子节点的情况。之后检查子节点数，若总数未达到N，则阻塞等待。</div><div class="notion-text notion-block-1429f73cea45806c850bd6e6a6335ffe">当最后一个进程加入屏障，子节点总数达到N，会触发所有在根节点上注册的Watcher，所有收到消息的进程同时调用<code class="notion-inline-code">leave()</code>离开屏障，删除临时节点以重置屏障，并继续执行后续任务。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-1429f73cea4580a08ae9cc37f0e97c4c" data-id="1429f73cea4580a08ae9cc37f0e97c4c"><span><div id="1429f73cea4580a08ae9cc37f0e97c4c" class="notion-header-anchor"></div><a class="notion-hash-link" href="#1429f73cea4580a08ae9cc37f0e97c4c" title="示例：分布式系统初始化"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">示例：分布式系统初始化</span></span></h4><div class="notion-text notion-block-1429f73cea4580d59f97c96550e485df">假设有一个分布式系统，其中包含1个配置节点和2个应用节点，且应用节点应当在配置节点启动后才启动。</div><div class="notion-text notion-block-1429f73cea4580e49e38de8958556828">首先创建一个<code class="notion-inline-code">DistributedBarrier</code>实例，并将屏障大小设置为3，在路径下创建根节点；</div><div class="notion-text notion-block-1429f73cea45804f8440f8c049ef6513">配置节点在启动后调用<code class="notion-inline-code">barrier.enter()</code>进入屏障，<code class="notion-inline-code">DistributedBarrier</code>在根节点下创建一个有序临时节点。此时子节点总数不足3，因此配置节点阻塞等待；</div><div class="notion-text notion-block-1429f73cea4580d1b073ce33c5d204ef">两个应用节点加入屏障，根节点下创建两个临时节点。此时子节点总数达到3，Zookeeper触发所有节点的Watcher，所有节点调用<code class="notion-inline-code">barrier.leave()</code>离开屏障，于是系统正常启动。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-1429f73cea4580d8a150e6fc43353418" data-id="1429f73cea4580d8a150e6fc43353418"><span><div id="1429f73cea4580d8a150e6fc43353418" class="notion-header-anchor"></div><a class="notion-hash-link" href="#1429f73cea4580d8a150e6fc43353418" title="2.3 Lock: InterProcessSemaphoreV2"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">2.3 Lock: InterProcessSemaphoreV2</span></span></h4><div class="notion-text notion-block-1429f73cea4580229935d106969e6e45">Curator实现的一种分布式信号量，用于控制能同时访问某个资源的并发进程数量。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-1429f73cea4580d6b365ddf9c6ea9195" data-id="1429f73cea4580d6b365ddf9c6ea9195"><span><div id="1429f73cea4580d6b365ddf9c6ea9195" class="notion-header-anchor"></div><a class="notion-hash-link" href="#1429f73cea4580d6b365ddf9c6ea9195" title="数据结构"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">数据结构</span></span></h4><div class="notion-text notion-block-1429f73cea458098ba91c51a1359c6cd">其中后者更灵活</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-1429f73cea458096aaa8d4f3b640c926" data-id="1429f73cea458096aaa8d4f3b640c926"><span><div id="1429f73cea458096aaa8d4f3b640c926" class="notion-header-anchor"></div><a class="notion-hash-link" href="#1429f73cea458096aaa8d4f3b640c926" title="工作原理"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">工作原理</span></span></h4><div class="notion-text notion-block-1429f73cea4580639ee6f7bf06511b2e"><code class="notion-inline-code">InterProcessSemaphoreV2</code>同样基于Zookeeper的<b>有序临时节点</b>和<b>Watch</b>监听机制。</div><div class="notion-text notion-block-1429f73cea4580559ec1f6980b5593f3">首先，在指定路径下创建一个持久节点作为根路径节点，用于存储该信号量的信息，如允许的最大并发数N等；</div><div class="notion-text notion-block-1429f73cea45808e88dddd0ae1a9d280">当某进程希望获取信号量以访问共享资源，调用<code class="notion-inline-code">acquire()</code>请求一个信号量，在根路径下创建一个新的有序临时节点表示该请求。之后计算当前持有信号量的子节点数，若未达最大并发数N，则该请求成功获取信号量并立即返回；若当前持有信号量的子节点数已达到N，则当前请求阻塞等待，并在根路径注册一个Watcher监听是否有信号量被释放。</div><div class="notion-text notion-block-1429f73cea4580019495f46f0e2cd0ce">当某进程希望释放信号量，调用<code class="notion-inline-code">returnLease()</code>，删除之前创建的临时子节点，以触发所有阻塞的Watcher，而这些阻塞的进程会按照拟定的先后顺序重新尝试获取信号量，并由其中的一个进程获得信号量并成功执行，其他进程继续阻塞。</div><h4 class="notion-h notion-h3 notion-h-indent-1 notion-block-1429f73cea458035aa20e5ed160d4fc1" data-id="1429f73cea458035aa20e5ed160d4fc1"><span><div id="1429f73cea458035aa20e5ed160d4fc1" class="notion-header-anchor"></div><a class="notion-hash-link" href="#1429f73cea458035aa20e5ed160d4fc1" title="示例：审批并发流程"><svg viewBox="0 0 16 16" width="16" height="16"><path fill-rule="evenodd" d="M7.775 3.275a.75.75 0 001.06 1.06l1.25-1.25a2 2 0 112.83 2.83l-2.5 2.5a2 2 0 01-2.83 0 .75.75 0 00-1.06 1.06 3.5 3.5 0 004.95 0l2.5-2.5a3.5 3.5 0 00-4.95-4.95l-1.25 1.25zm-4.69 9.64a2 2 0 010-2.83l2.5-2.5a2 2 0 012.83 0 .75.75 0 001.06-1.06 3.5 3.5 0 00-4.95 0l-2.5 2.5a3.5 3.5 0 004.95 4.95l1.25-1.25a.75.75 0 00-1.06-1.06l-1.25 1.25a2 2 0 01-2.83 0z"></path></svg></a><span class="notion-h-title">示例：审批并发流程</span></span></h4><div class="notion-text notion-block-1429f73cea45806bb2a4caf8556944db">假设有一个审批系统，可能有多个工作人员同时处理用户请求，需要限制同时处理的请求数，以确保人员工作的负载均衡。</div><div class="notion-text notion-block-1429f73cea45804cbb80e7dfcb098a83">首先创建一个<code class="notion-inline-code">InterProcessSemaphoreV2</code>实例，并设置允许的最大并发数N，在路径下创建持久根节点；</div><div class="notion-text notion-block-1429f73cea4580e790b1ed10dfb5591e">当某工作人员希望处理用户请求，调用<code class="notion-inline-code">acquire()</code>请求一个信号量，在根路径下创建一个新的有序临时节点。若此时信号量计数器未达最大值N，则获取成功，工作人员可以开始处理用户请求；否则，该请求会阻塞等待，并监听其他人员释放信号量的情况。</div><div class="notion-text notion-block-1429f73cea4580e19208dffe38eef976">当某工作人员希望完成处理，调用<code class="notion-inline-code">returnLease()</code>归还信号量，删除之前创建的临时子节点，并通知正在阻塞的所有工作人员，按照先后顺序优先分配，其他的工作人员继续阻塞。</div></main></div>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[《云计算平台与技术》｜实验一：华为云云上应用高可用部署实验]]></title>
            <link>https://antonyzhang.cn/article/cloudcrouse-1</link>
            <guid>https://antonyzhang.cn/article/cloudcrouse-1</guid>
            <pubDate>Mon, 18 Nov 2024 00:00:00 GMT</pubDate>
        </item>
        <item>
            <title><![CDATA[CSAPP｜Attack Lab]]></title>
            <link>https://antonyzhang.cn/article/csapp-attacklab</link>
            <guid>https://antonyzhang.cn/article/csapp-attacklab</guid>
            <pubDate>Sat, 09 Dec 2023 00:00:00 GMT</pubDate>
            <description><![CDATA[CSAPP第三次实验任务，转守为攻🗡️]]></description>
            <content:encoded><![CDATA[CSAPP第三次实验任务，转守为攻🗡️]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[CSAPP｜Bomb Lab]]></title>
            <link>https://antonyzhang.cn/article/csapp-bomblab</link>
            <guid>https://antonyzhang.cn/article/csapp-bomblab</guid>
            <pubDate>Wed, 29 Nov 2023 00:00:00 GMT</pubDate>
            <description><![CDATA[CSAPP第二次实验任务，拆炸弹💣]]></description>
            <content:encoded><![CDATA[CSAPP第二次实验任务，拆炸弹💣]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[CSAPP｜Data Lab]]></title>
            <link>https://antonyzhang.cn/article/csapp-datalab</link>
            <guid>https://antonyzhang.cn/article/csapp-datalab</guid>
            <pubDate>Thu, 26 Oct 2023 00:00:00 GMT</pubDate>
            <description><![CDATA[CSAPP第一次实验任务]]></description>
            <content:encoded><![CDATA[CSAPP第一次实验任务]]></content:encoded>
        </item>
    </channel>
</rss>