96SEO 2026-02-20 05:09 17
来对节点进行监听操作可以典型业务场景需要使用可考虑但一般情况不推荐使用。

ExponentialBackoffRetry(3000,10);
CuratorFrameworkFactory.builder().connectString(192.168.58.100:2181).sessionTimeoutMs(60*1000).connectionTimeoutMs(15*1000).retryPolicy(retryPolicy).namespace(mashibing)
client.getData().usingWatcher(new
watchedEvent);}}).forPath(/test);
监听事件并且返回当前节点的内容。
后面进行两次数据变更实际上第二次变更时监听已经失效无法再次获得节点变动事件了。
测试中控制台输出的信息如下
原生支持通过注册Watcher来进行事件监听但是其使用并不是特别方便需要开发人员自己反复注册Watcher比较繁琐。
可以监控整个树上的所有节点类似于PathChildrenCache和NodeCache的组合
注册监听nodeCache.getListenable().addListener(new
{System.out.println(节点变化了。
。
。
。
。
。
);
nodeCache.getCurrentData().getData();System.out.println(new
设置为true开启监听nodeCache.start(true);
NodeCache不仅可以监听节点内容变化还可以监听指定节点是否存在。
如果原本节点不存在那么Cache就会在节点被创建时触发监听事件如果该节点被删除就无法再触发监听事件。
(第三个参数表示缓存每次节点更新后的数据)PathChildrenCache
//2.绑定监听器pathChildrenCache.getListenable().addListener(new
{System.out.println(子节点发生变化了。
。
。
。
。
。
);System.out.println(pathChildrenCacheEvent);
if(PathChildrenCacheEvent.Type.CHILD_UPDATED
pathChildrenCacheEvent.getType()){//更新子节点System.out.println(子节点更新了);//在一个getData中有很多数据我们只拿data部分byte[]
pathChildrenCacheEvent.getData().getData();System.out.println(更新后的值为
if(PathChildrenCacheEvent.Type.CHILD_ADDED
pathChildrenCacheEvent.getType()){//添加子节点System.out.println(添加子节点);String
pathChildrenCacheEvent.getData().getPath();System.out.println(子节点路径为
if(PathChildrenCacheEvent.Type.CHILD_REMOVED
pathChildrenCacheEvent.getType()){//删除子节点System.out.println(删除了子节点);String
pathChildrenCacheEvent.getData().getPath();System.out.println(子节点路径为
PathChildrenCacheEvent{typeCHILD_UPDATED,
stat164,166,1670114647087,1670114698259,1,0,0,0,3,0,164,
PathChildrenCache只监听子结点的结合版即监听当前和子结点。
//2.绑定监听器treeCache.getListenable().addListener(new
{System.out.println(节点变化了);System.out.println(treeCacheEvent);
if(TreeCacheEvent.Type.NODE_UPDATED
treeCacheEvent.getType()){//更新节点System.out.println(节点更新了);//在一个getData中有很多数据我们只拿data部分byte[]
treeCacheEvent.getData().getData();System.out.println(更新后的值为
if(TreeCacheEvent.Type.NODE_ADDED
treeCacheEvent.getType()){//添加子节点System.out.println(添加节点);String
treeCacheEvent.getData().getPath();System.out.println(子节点路径为
if(TreeCacheEvent.Type.NODE_REMOVED
treeCacheEvent.getType()){//删除子节点System.out.println(删除节点);String
treeCacheEvent.getData().getPath();System.out.println(删除节点路径为
client.transactionOp().create().forPath(/app3,
app1-data.getBytes());CuratorOp
client.transactionOp().setData().forPath(/app2,
app2-data.getBytes());CuratorOp
client.transactionOp().delete().forPath(/app2);
添加事务操CollectionCuratorTransactionResult
client.transaction().forOperations(createOp,
{System.out.println(result.getForPath()
CuratorEvent里面包含事件类型、响应码和节点的详细信息。
client.getChildren();builder.inBackground(new
curatorEvent.getChildren());}}).forPath(/);
Zookeeper作为一个分布式协调框架内部存储了一些分布式系统运行时的状态的数据比如master选举、比如分布式锁。
对这些数据的操作会直接影响到分布式系统的运行状态。
因此为了保证zookeeper中的数据的安全性避免误操作带来的影响。
Zookeeper提供了一套ACL权限控制机制来保证数据的安全。
ZooKeeper的权限控制是基于每个znode节点的需要对每个节点设置权限每个znode支持设置多种权限控制方案和多个权限子节点不会继承父节点的权限客户端无权访问某节点但可能可以访问它的子节点。
Zookeeper提供以下权限模式所谓权限模式就是使用什么样的方式来进行授权。
digest即用户名:密码这种方式认证这也是业务系统中最常用的。
ip:192.168.1.1/24此时addr中的有效位与客户端addr中的有效位进行比对。
指权限赋予的用户或一个指定的实体不同的权限模式下授权对象不同。
权限模式(Schema)和授权对象主要用来确认权限验证过程中使用的验证策略
比如ip地址、digest:username:password匹配到验证策略并验证成功后再根据权限操作类型来决定当前客户端的访问权限。
digest,spike:pPeKgz2N9Xc8Um6wwnzFUMteLxk
MessageDigest.getInstance(SHA1).digest(up.getBytes());String
Base64.getEncoder().encodeToString(digest);System.out.println(encodeStr);}
digest:msb:5FAC7McRhLdx0QUWsfEbK8pqwxc:cdrwa[zk:
digest,msb:5FAC7McRhLdx0QUWsfEbK8pqwxc
接下来我们使用Curator简单演示一下ACL权限的访问操作。
MessageDigest.getInstance(SHA1).digest(up.getBytes());String
Base64.getEncoder().encodeToString(digest);System.out.println(encodeStr);}//1.创建连接Beforepublic
CuratorFrameworkFactory.builder().connectString(192.168.58.100:2181).sessionTimeoutMs(5000).connectionTimeoutMs(20000).retryPolicy(new
3)).namespace(msbAcl).build();client.start();}Testpublic
DigestAu***nticationProvider.generateDigest(msb:msb));//为ID对象指定权限ListACL
ACL(ZooDefs.Perms.ALL,id));//创建节点
client.create().creatingParentsIfNeeded().withMode(CreateMode.PERSISTENT)
设置节点类型是持久节点.withACL(acls,false)
//设置节点的ACL权限.forPath(/auth,hello.getBytes());
//设置节点的路径和数据System.out.println(成功创建带权限的节点
client.getData().forPath(node);System.out.println(获取数据结果
真实的集群是需要部署在不同的服务器上的但是在我们测试时同时启动很多个虚拟机内存会吃不消所以我们通常会搭建伪集群也就是把所有的服务都搭建在一台虚拟机上用端口进行区分。
Leader处理集群的所有事务请求增删改集群中只有一个Leader。
Observer只能处理读请求提升集群读的性能但不能参与Leader选举。
建立/usr/local/zookeeper-cluster。
/usr/local/zookeeper-cluster[rootlocalhost
/usr/local/zookeeper-cluster/zookeeper-1[rootlocalhost
/usr/local/zookeeper-cluster/zookeeper-2[rootlocalhost
/usr/local/zookeeper-cluster/zookeeper-3
/usr/local/zookeeper-cluster/zookeeper-1/data
/usr/local/zookeeper-cluster/zookeeper-2/data
/usr/local/zookeeper-cluster/zookeeper-3/datamv
/usr/local/zookeeper-cluster/zookeeper-1/conf/zoo_sample.cfg
/usr/local/zookeeper-cluster/zookeeper-1/conf/zoo.cfg
/usr/local/zookeeper-cluster/zookeeper-2/conf/zoo_sample.cfg
/usr/local/zookeeper-cluster/zookeeper-2/conf/zoo.cfg
/usr/local/zookeeper-cluster/zookeeper-3/conf/zoo_sample.cfg
/usr/local/zookeeper-cluster/zookeeper-3/conf/zoo.cfg
修改/usr/local/zookeeper-cluster/zookeeper-1/conf/zoo.cfg
/usr/local/zookeeper-cluster/zookeeper-1/conf/zoo.cfgclientPort2181
dataDir/usr/local/zookeeper-cluster/zookeeper-1/data
修改/usr/local/zookeeper-cluster/zookeeper-2/conf/zoo.cfg
/usr/local/zookeeper-cluster/zookeeper-2/conf/zoo.cfgclientPort2182
dataDir/usr/local/zookeeper-cluster/zookeeper-2/data
修改/usr/local/zookeeper-cluster/zookeeper-3/conf/zoo.cfg
/usr/local/zookeeper-cluster/zookeeper-3/conf/zoo.cfgclientPort2183
dataDir/usr/local/zookeeper-cluster/zookeeper-3/data
/usr/local/zookeeper-cluster/zookeeper-1/data/myid
/usr/local/zookeeper-cluster/zookeeper-2/data/myid
/usr/local/zookeeper-cluster/zookeeper-3/data/myid
zoo.cfg配置客户端访问端口clientPort和集群服务器IP列表。
/usr/local/zookeeper-cluster/zookeeper-1/conf/zoo.cfg
/usr/local/zookeeper-cluster/zookeeper-2/conf/zoo.cfg
/usr/local/zookeeper-cluster/zookeeper-3/conf/zoo.cfgserver.1192.168.58.200:2881:3881
server.2192.168.58.200:2882:3882
server.3192.168.58.200:2883:3883
解释server.服务器ID服务器IP地址服务器之间通信端口服务器之间投票选举端口
/usr/local/zookeeper-cluster/zookeeper-1/bin/zkServer.sh
/usr/local/zookeeper-cluster/zookeeper-2/bin/zkServer.sh
/usr/local/zookeeper-cluster/zookeeper-3/bin/zkServer.sh
/usr/local/zookeeper-cluster/zookeeper-1/bin/zkServer.sh
/usr/local/zookeeper-cluster/zookeeper-2/bin/zkServer.sh
/usr/local/zookeeper-cluster/zookeeper-3/bin/zkServer.sh
的命令QuorumPeerMain是zookeeper集群的启动入口类
192.168.58.200:2181,192.168.58.200:2182,192.168.58.200:2183
如果只连接单个客户端如果当前连接的服务器挂掉当前客户端连接也会挂掉连接失败。
如果是连接所有客户端的形式则允许集群中半数以下的服务挂掉当半数以上服务挂掉才会停止服务可用性更高一点
集群中的节点信息被存放在每一个节点/zookeeper/config/目录下
/usr/local/zookeeper-cluster/zookeeper-3/bin/zkServer.sh
stop/usr/local/zookeeper-cluster/zookeeper-1/bin/zkServer.sh
/usr/local/zookeeper-cluster/zookeeper-2/bin/zkServer.sh
2我们再把1号服务器从服务器也停掉查看2号主服务器的状态发现已经停止运行了。
/usr/local/zookeeper-cluster/zookeeper-1/bin/zkServer.sh
stop/usr/local/zookeeper-cluster/zookeeper-2/bin/zkServer.sh
由此得出结论3个节点的集群2个从服务器都挂掉主服务器也无法运行。
因为可运行的机器没有超过集群总数量的半数。
3我们再次把1号服务器启动起来发现2号服务器又开始正常工作了。
而且依然是领导者。
4我们把3号服务器也启动起来把2号服务器停掉,停掉后观察1号和3号的状态。
/usr/local/zookeeper-cluster/zookeeper-3/bin/zkServer.sh
/usr/local/zookeeper-cluster/zookeeper-2/bin/zkServer.sh
stop/usr/local/zookeeper-cluster/zookeeper-1/bin/zkServer.sh
/usr/local/zookeeper-cluster/zookeeper-3/bin/zkServer.sh
由此我们得出结论当集群中的主服务器挂了集群中的其他服务器会自动进行选举状态然后产生新得leader
5我们再次测试当我们把2号服务器重新启动起来启动后会发生什么2号服务器会再次成为新的领导吗我们看结果
/usr/local/zookeeper-cluster/zookeeper-2/bin/zkServer.sh
start/usr/local/zookeeper-cluster/zookeeper-2/bin/zkServer.sh
/usr/local/zookeeper-cluster/zookeeper-3/bin/zkServer.sh
我们会发现2号服务器启动后依然是跟随者从服务器3号服务器依然是领导者主服务器没有撼动3号服务器的领导地位。
由此我们得出结论当领导者产生后再次有新服务器加入集群不会影响到现任领导者。
192.168.58.200:2181,192.168.58.200:2182,192.168.58.200:2183;//session超时时间private
ExponentialBackoffRetry(3000,10);//
CuratorFrameworkFactory.builder().connectString(getClusterConnect()).sessionTimeoutMs(60*1000).connectionTimeoutMs(15*1000).retryPolicy(retryPolicy).namespace(mashibing)
添加监听器client.getConnectionStateListenable().addListener(new
{System.out.println(连接成功);}});client.start();}//创建节点public
client.checkExists().forPath(path);if(stat
client.create().forPath(path);System.out.println(创建节点
client.getData().forPath(/test);System.out.println(new
String(data));TimeUnit.SECONDS.sleep(5);}}
192.168.58.200:2181,192.168.58.200:2182,192.168.58.200:2183(CONNECTED)
作为专业的SEO优化服务提供商,我们致力于通过科学、系统的搜索引擎优化策略,帮助企业在百度、Google等搜索引擎中获得更高的排名和流量。我们的服务涵盖网站结构优化、内容优化、技术SEO和链接建设等多个维度。
| 服务项目 | 基础套餐 | 标准套餐 | 高级定制 |
|---|---|---|---|
| 关键词优化数量 | 10-20个核心词 | 30-50个核心词+长尾词 | 80-150个全方位覆盖 |
| 内容优化 | 基础页面优化 | 全站内容优化+每月5篇原创 | 个性化内容策略+每月15篇原创 |
| 技术SEO | 基本技术检查 | 全面技术优化+移动适配 | 深度技术重构+性能优化 |
| 外链建设 | 每月5-10条 | 每月20-30条高质量外链 | 每月50+条多渠道外链 |
| 数据报告 | 月度基础报告 | 双周详细报告+分析 | 每周深度报告+策略调整 |
| 效果保障 | 3-6个月见效 | 2-4个月见效 | 1-3个月快速见效 |
我们的SEO优化服务遵循科学严谨的流程,确保每一步都基于数据分析和行业最佳实践:
全面检测网站技术问题、内容质量、竞争对手情况,制定个性化优化方案。
基于用户搜索意图和商业目标,制定全面的关键词矩阵和布局策略。
解决网站技术问题,优化网站结构,提升页面速度和移动端体验。
创作高质量原创内容,优化现有页面,建立内容更新机制。
获取高质量外部链接,建立品牌在线影响力,提升网站权威度。
持续监控排名、流量和转化数据,根据效果调整优化策略。
基于我们服务的客户数据统计,平均优化效果如下:
我们坚信,真正的SEO优化不仅仅是追求排名,而是通过提供优质内容、优化用户体验、建立网站权威,最终实现可持续的业务增长。我们的目标是与客户建立长期合作关系,共同成长。
Demand feedback