系统协调 zookeeper golang入门
官网:https://zookeeper.apache.org/
godoc文档:https://godoc.org/github.com/samuel/go-zookeeper/zk#Conn.GetW
参考文章:https://www.cnblogs.com/zhichaoma/p/12640064.html
在上篇博文中说了kafka,它依赖于zookeeper,尽管在最新版中,kafka尽量在弱化zookeeper,但还是无法脱离zookeeper,可见zookeeper的强大。
<h1>简介</h1>ZooKeeper是一项集中式服务,用于维护配置信息,命名,提供分布式同步和提供组服务。所有这些类型的服务都以某种形式被分布式应用程序使用。每次实施它们时,都会进行很多工作来修复不可避免的错误和竞争条件。由于难以实现这类服务,因此应用程序最初通常会跳过它们,这会使它们在存在更改的情况下变得脆弱并且难以管理。即使部署正确,这些服务的不同实现也会导致管理复杂。
<h3>安装</h3>依然是docker安装,方法见上篇博文:https://blog.csdn.net/qq_25490573/article/details/107229554
<h1>简单栗子</h1>比较尴尬的一点是,zk只出了java和c的包,golang需要依赖第三方包。
<h3>下载工具包</h3>文档地址:https://godoc.org/github.com/samuel/go-zookeeper/zk
<pre><code class="lang-go hljs"><span class="token keyword">go</span> get github<span class="token punctuation">.</span>com<span class="token operator">/</span>samuel<span class="token operator">/</span><span class="token keyword">go</span><span class="token operator">-</span>zookeeper </code></pre> <h3>封装操作方法</h3> <pre><code class="lang-go hljs"><span class="token keyword">type</span> ZKManage <span class="token keyword">struct</span> <span class="token punctuation">{</span> Conn <span class="token operator">*</span> zk<span class="token punctuation">.</span>Conn Event <span class="token operator"><-</span><span class="token keyword">chan</span> zk<span class="token punctuation">.</span>Event <span class="token punctuation">}</span> <span class="token keyword">func</span> <span class="token function">NewZKManage</span><span class="token punctuation">(</span>addr <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token builtin">string</span><span class="token punctuation">)</span><span class="token operator">*</span>ZKManage<span class="token punctuation">{</span> conn<span class="token punctuation">,</span>eventchan<span class="token punctuation">,</span>err <span class="token operator">:=</span> zk<span class="token punctuation">.</span><span class="token function">Connect</span><span class="token punctuation">(</span>addr<span class="token punctuation">,</span>time<span class="token punctuation">.</span>Second<span class="token operator">*</span><span class="token number">5</span><span class="token punctuation">)</span> <span class="token keyword">if</span> err<span class="token operator">!=</span><span class="token boolean">nil</span><span class="token punctuation">{</span> <span class="token function">panic</span><span class="token punctuation">(</span>err<span class="token punctuation">)</span> <span class="token punctuation">}</span> zkm <span class="token operator">:=</span> <span class="token function">new</span><span class="token punctuation">(</span>ZKManage<span class="token punctuation">)</span> zkm<span class="token punctuation">.</span>Conn <span class="token operator">=</span> conn zkm<span class="token punctuation">.</span>Event <span class="token operator">=</span> eventchan <span class="token keyword">return</span> zkm <span class="token punctuation">}</span> <span class="token keyword">func</span><span class="token punctuation">(</span>z <span class="token operator">*</span>ZKManage<span class="token punctuation">)</span><span class="token function">Insert</span><span class="token punctuation">(</span>path<span class="token punctuation">,</span>value <span class="token builtin">string</span><span class="token punctuation">)</span><span class="token builtin">error</span><span class="token punctuation">{</span> acls <span class="token operator">:=</span> zk<span class="token punctuation">.</span><span class="token function">WorldACL</span><span class="token punctuation">(</span>zk<span class="token punctuation">.</span>PermAll<span class="token punctuation">)</span> <span class="token comment">// 0:永久,除非手动删除</span> <span class="token comment">// zk.FlagEphemeral = 1:短暂,session断开则该节点也被删除</span> <span class="token comment">// zk.FlagSequence = 2:会自动在节点后面添加序号</span> <span class="token comment">// 3:Ephemeral和Sequence,即,短暂且自动添加序号</span> res<span class="token punctuation">,</span>err <span class="token operator">:=</span> z<span class="token punctuation">.</span>Conn<span class="token punctuation">.</span><span class="token function">Create</span><span class="token punctuation">(</span>path<span class="token punctuation">,</span><span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token function">byte</span><span class="token punctuation">(</span>value<span class="token punctuation">)</span><span class="token punctuation">,</span><span class="token number">0</span><span class="token punctuation">,</span>acls<span class="token punctuation">)</span> <span class="token keyword">if</span> err<span class="token operator">!=</span><span class="token boolean">nil</span><span class="token punctuation">{</span> <span class="token keyword">return</span> err <span class="token punctuation">}</span> fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span><span class="token string">"Insert:"</span><span class="token punctuation">,</span>res<span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token boolean">nil</span> <span class="token punctuation">}</span> <span class="token keyword">func</span><span class="token punctuation">(</span>z <span class="token operator">*</span>ZKManage<span class="token punctuation">)</span><span class="token function">Delete</span><span class="token punctuation">(</span>path <span class="token builtin">string</span><span class="token punctuation">)</span><span class="token builtin">error</span><span class="token punctuation">{</span> <span class="token boolean">_</span><span class="token punctuation">,</span>stat<span class="token punctuation">,</span><span class="token boolean">_</span> <span class="token operator">:=</span> z<span class="token punctuation">.</span>Conn<span class="token punctuation">.</span><span class="token function">Get</span><span class="token punctuation">(</span>path<span class="token punctuation">)</span> <span class="token comment">// 删改与增不同在于其函数中的version参数,其中version是用于 CAS支持</span> <span class="token comment">// 可以通过此种方式保证原子性</span> <span class="token keyword">return</span> z<span class="token punctuation">.</span>Conn<span class="token punctuation">.</span><span class="token function">Delete</span><span class="token punctuation">(</span>path<span class="token punctuation">,</span>stat<span class="token punctuation">.</span>Version<span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token keyword">func</span><span class="token punctuation">(</span>z <span class="token operator">*</span>ZKManage<span class="token punctuation">)</span><span class="token function">Update</span><span class="token punctuation">(</span>path<span class="token punctuation">,</span>value <span class="token builtin">string</span><span class="token punctuation">)</span><span class="token builtin">error</span><span class="token punctuation">{</span> <span class="token boolean">_</span><span class="token punctuation">,</span>stat<span class="token punctuation">,</span><span class="token boolean">_</span> <span class="token operator">:=</span> z<span class="token punctuation">.</span>Conn<span class="token punctuation">.</span><span class="token function">Get</span><span class="token punctuation">(</span>path<span class="token punctuation">)</span> <span class="token boolean">_</span><span class="token punctuation">,</span> err <span class="token operator">:=</span>z<span class="token punctuation">.</span>Conn<span class="token punctuation">.</span><span class="token function">Set</span><span class="token punctuation">(</span>path<span class="token punctuation">,</span><span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token function">byte</span><span class="token punctuation">(</span>value<span class="token punctuation">)</span><span class="token punctuation">,</span>stat<span class="token punctuation">.</span>Version<span class="token punctuation">)</span> <span class="token keyword">return</span> err <span class="token punctuation">}</span> <span class="token keyword">func</span><span class="token punctuation">(</span>z <span class="token operator">*</span>ZKManage<span class="token punctuation">)</span><span class="token function">Select</span><span class="token punctuation">(</span>path <span class="token builtin">string</span><span class="token punctuation">)</span><span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token builtin">byte</span><span class="token punctuation">{</span> data<span class="token punctuation">,</span><span class="token boolean">_</span><span class="token punctuation">,</span><span class="token boolean">_</span> <span class="token operator">:=</span> z<span class="token punctuation">.</span>Conn<span class="token punctuation">.</span><span class="token function">Get</span><span class="token punctuation">(</span>path<span class="token punctuation">)</span> <span class="token keyword">return</span> data <span class="token punctuation">}</span> </code></pre> <h3>测试</h3> <pre><code class="lang-go hljs"><span class="token keyword">func</span> <span class="token function">InitZookeeper</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">{</span> zkm <span class="token operator">:=</span> <span class="token function">NewZKManage</span><span class="token punctuation">(</span><span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token builtin">string</span><span class="token punctuation">{</span><span class="token string">"192.168.254.172:2181"</span><span class="token punctuation">}</span><span class="token punctuation">)</span> <span class="token keyword">defer</span> zkm<span class="token punctuation">.</span>Conn<span class="token punctuation">.</span><span class="token function">Close</span><span class="token punctuation">(</span><span class="token punctuation">)</span> path <span class="token operator">:=</span> <span class="token string">"/test"</span> <span class="token keyword">if</span> err <span class="token operator">:=</span> zkm<span class="token punctuation">.</span><span class="token function">Insert</span><span class="token punctuation">(</span>path<span class="token punctuation">,</span><span class="token string">"this is a test data"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>err <span class="token operator">!=</span><span class="token boolean">nil</span><span class="token punctuation">{</span> fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span>err<span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token punctuation">}</span><span class="token keyword">else</span> <span class="token punctuation">{</span> fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span><span class="token string">"insert success"</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span><span class="token string">"select:"</span><span class="token punctuation">,</span><span class="token function">string</span><span class="token punctuation">(</span>zkm<span class="token punctuation">.</span><span class="token function">Select</span><span class="token punctuation">(</span>path<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token keyword">if</span> err <span class="token operator">:=</span> zkm<span class="token punctuation">.</span><span class="token function">Update</span><span class="token punctuation">(</span>path<span class="token punctuation">,</span><span class="token string">"this is a update data"</span><span class="token punctuation">)</span><span class="token punctuation">;</span>err <span class="token operator">!=</span><span class="token boolean">nil</span><span class="token punctuation">{</span> fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span>err<span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token punctuation">}</span><span class="token keyword">else</span> <span class="token punctuation">{</span> fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span><span class="token string">"update success"</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token keyword">if</span> err <span class="token operator">:=</span> zkm<span class="token punctuation">.</span><span class="token function">Delete</span><span class="token punctuation">(</span>path<span class="token punctuation">)</span><span class="token punctuation">;</span>err<span class="token operator">!=</span><span class="token boolean">nil</span><span class="token punctuation">{</span> fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span>err<span class="token punctuation">)</span> <span class="token punctuation">}</span><span class="token keyword">else</span> <span class="token punctuation">{</span> fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span><span class="token string">"delete success"</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> </code></pre>测试截图
首先声明一个回调函数
<pre><code class="lang-go hljs"><span class="token keyword">func</span> <span class="token function">CallBlack</span><span class="token punctuation">(</span>event zk<span class="token punctuation">.</span>Event<span class="token punctuation">)</span><span class="token punctuation">{</span> fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span><span class="token string">"-----------event call black--------------"</span><span class="token punctuation">)</span> fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span><span class="token string">"path: "</span><span class="token punctuation">,</span> event<span class="token punctuation">.</span>Path<span class="token punctuation">)</span> fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span><span class="token string">"type: "</span><span class="token punctuation">,</span> event<span class="token punctuation">.</span>Type<span class="token punctuation">.</span><span class="token function">String</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span><span class="token string">"state: "</span><span class="token punctuation">,</span> event<span class="token punctuation">.</span>State<span class="token punctuation">.</span><span class="token function">String</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span><span class="token string">"-----------------------------------------"</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> </code></pre>然后修改NewZKManage函数
<ul><li>在进行连接的时候声明回调函数zk.WithEventCallback(CallBlack)</li><li>ExistsW 方法注册观察那个path创建</li><li>注意:当监听的path添加时只调用一次回调函数,一次后失效,想重新观察需要重新执行ExistsW</li><li>GetW和ExistsW特性类似,用于监听get</li></ul><pre><code class="lang-go hljs"><span class="token keyword">func</span> <span class="token function">NewZKManage</span><span class="token punctuation">(</span>addr <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token builtin">string</span><span class="token punctuation">,</span>path <span class="token builtin">string</span><span class="token punctuation">)</span><span class="token operator">*</span>ZKManage<span class="token punctuation">{</span> conn<span class="token punctuation">,</span>eventchan<span class="token punctuation">,</span>err <span class="token operator">:=</span> zk<span class="token punctuation">.</span><span class="token function">Connect</span><span class="token punctuation">(</span>addr<span class="token punctuation">,</span>time<span class="token punctuation">.</span>Second<span class="token operator">*</span><span class="token number">5</span><span class="token punctuation">,</span>zk<span class="token punctuation">.</span><span class="token function">WithEventCallback</span><span class="token punctuation">(</span>CallBlack<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token keyword">if</span> err<span class="token operator">!=</span><span class="token boolean">nil</span><span class="token punctuation">{</span> <span class="token function">panic</span><span class="token punctuation">(</span>err<span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token comment">//ExistsW 一次触发后不再触发</span> <span class="token boolean">_</span><span class="token punctuation">,</span><span class="token boolean">_</span><span class="token punctuation">,</span><span class="token boolean">_</span><span class="token punctuation">,</span>err <span class="token operator">=</span> conn<span class="token punctuation">.</span><span class="token function">ExistsW</span><span class="token punctuation">(</span>path<span class="token punctuation">)</span> <span class="token keyword">if</span> err<span class="token operator">!=</span><span class="token boolean">nil</span><span class="token punctuation">{</span> <span class="token function">panic</span><span class="token punctuation">(</span>err<span class="token punctuation">)</span> <span class="token punctuation">}</span> zkm <span class="token operator">:=</span> <span class="token function">new</span><span class="token punctuation">(</span>ZKManage<span class="token punctuation">)</span> zkm<span class="token punctuation">.</span>Conn <span class="token operator">=</span> conn zkm<span class="token punctuation">.</span>Event <span class="token operator">=</span> eventchan <span class="token keyword">return</span> zkm <span class="token punctuation">}</span> </code></pre> <h3>全局监听</h3>声明全局监听函数
<pre><code class="lang-go hljs"><span class="token comment">//全局监听</span> <span class="token keyword">func</span> <span class="token function">WatchZkEvent</span><span class="token punctuation">(</span>e <span class="token operator"><-</span><span class="token keyword">chan</span> zk<span class="token punctuation">.</span>Event<span class="token punctuation">)</span> <span class="token punctuation">{</span> event <span class="token operator">:=</span> <span class="token operator"><-</span>e fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span><span class="token string">"-----------------全局监听-----------------"</span><span class="token punctuation">)</span> fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span><span class="token string">"path: "</span><span class="token punctuation">,</span> event<span class="token punctuation">.</span>Path<span class="token punctuation">)</span> fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span><span class="token string">"type: "</span><span class="token punctuation">,</span> event<span class="token punctuation">.</span>Type<span class="token punctuation">.</span><span class="token function">String</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span><span class="token string">"state: "</span><span class="token punctuation">,</span> event<span class="token punctuation">.</span>State<span class="token punctuation">.</span><span class="token function">String</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span> fmt<span class="token punctuation">.</span><span class="token function">Println</span><span class="token punctuation">(</span><span class="token string">"-----------------------------------------"</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> </code></pre>修改创建函数,在连接时去掉回调函数设置,全局监听也只触发一次
<pre><code class="lang-go hljs"><span class="token keyword">func</span> <span class="token function">NewZKManage</span><span class="token punctuation">(</span>addr <span class="token punctuation">[</span><span class="token punctuation">]</span><span class="token builtin">string</span><span class="token punctuation">,</span>path <span class="token builtin">string</span><span class="token punctuation">)</span><span class="token operator">*</span>ZKManage<span class="token punctuation">{</span> conn<span class="token punctuation">,</span>eventchan<span class="token punctuation">,</span>err <span class="token operator">:=</span> zk<span class="token punctuation">.</span><span class="token function">Connect</span><span class="token punctuation">(</span>addr<span class="token punctuation">,</span>time<span class="token punctuation">.</span>Second<span class="token operator">*</span><span class="token number">5</span><span class="token punctuation">)</span> <span class="token keyword">if</span> err<span class="token operator">!=</span><span class="token boolean">nil</span><span class="token punctuation">{</span> <span class="token function">panic</span><span class="token punctuation">(</span>err<span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token comment">//ExistsW 一次触发后不再触发</span> <span class="token boolean">_</span><span class="token punctuation">,</span><span class="token boolean">_</span><span class="token punctuation">,</span>event<span class="token punctuation">,</span>err <span class="token operator">:=</span> conn<span class="token punctuation">.</span><span class="token function">ExistsW</span><span class="token punctuation">(</span>path<span class="token punctuation">)</span> <span class="token keyword">if</span> err<span class="token operator">!=</span><span class="token boolean">nil</span><span class="token punctuation">{</span> <span class="token function">panic</span><span class="token punctuation">(</span>err<span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token keyword">go</span> <span class="token function">WatchZkEvent</span><span class="token punctuation">(</span>event<span class="token punctuation">)</span> zkm <span class="token operator">:=</span> <span class="token function">new</span><span class="token punctuation">(</span>ZKManage<span class="token punctuation">)</span> zkm<span class="token punctuation">.</span>Conn <span class="token operator">=</span> conn zkm<span class="token punctuation">.</span>Event <span class="token operator">=</span> eventchan <span class="token keyword">return</span> zkm <span class="token punctuation">}</span> </code></pre>注意:
<ul><li>如果即设置了全局监听又设置了部分监听,那么最终是都会触发的,并且全局监听在先执行</li><li>如果设置了监听子节点,那么事件的触发是先子节点后父节点</li></ul>未完待续。。。
到此这篇关于“系统协调 zookeeper golang入门”的文章就介绍到这了,更多文章或继续浏览下面的相关文章,希望大家以后多多支持JQ教程网!您可能感兴趣的文章:
Golang之微服务为什么发现不了
php nodeJs thrift协议,实现zookeeper节点数据自动发现
为什么要学 Go
系统协调 zookeeper golang入门
zookeeper跨集群数据拷贝的例子
VSCode配置golang开发环境
go 协程
Golang 介绍
golang的协程原理
Golang协程原理(一)