当前位置:   article > 正文

ZooKeeper(一)_xshell连接zookeeper

xshell连接zookeeper

目录

一:Zookeeper介绍

有状态服务与无状态服务的区别:

Zookeeper的应用场景:

二:搭建Zookeeper服务器的操作命令

三:Zookeeper内部的数据模型

1.zk是如何保存数据的

XShell远程操作虚拟机连接zookeeper服务器以及进行相关的数据存储

2.zk中的znode是什么样的结构

3.zk中节点znode的类型

持久节点和持久序号节点的演示:

临时节点演示:

zookeeper可以实现服务的注册与发现:

其他节点演示:

4.zk的数据持久化

四:Zookeeper客户端(zkCli)的使用

1.多节点类型创建

详细步骤演示:

2.查询节点

3.删除节点

普通删除:

乐观锁删除:

分析乐观锁与悲观锁:

悲观锁与乐观锁对比:

4.权限设定

五:Curator客户端的使用

其实Curator就是基于使用Java代码进行操作Zookeeper服务器对应的数据的客户端:

代码演示:

代码演示细节记录:


一:Zookeeper介绍

有状态服务与无状态服务的区别:

无状态服务对单次请求的处理,不依赖其他请求,也就是说,处理一次请求所需的全部信息,要么都包含在这个请求里,要么可以从外部获取到(比如说:数据

库),服务器本身不会进行存储任何信息

有状态服务则相反,它会在自身保存一些数据,先后的请求是有关联的

Zookeeper的应用场景:

1.分布式协调组件

2.分布式锁

3.无状态化的实现

二:搭建Zookeeper服务器的操作命令

1.搭建过程省略

2.Zookeeper的相关操作:

三:Zookeeper内部的数据模型

1.zk是如何保存数据的

我们通过Zookeeper的介绍可知:当有请求令牌时,我们是把登录的信息存储到Zookeeper这个注册中心的。那么就说明Zookeeper是可以进行存储数据的

那么它就一定具有数据模型。

XShell远程操作虚拟机连接zookeeper服务器以及进行相关的数据存储

1.第一步:进行连接到zookeeper服务器

2.进行数据存储

2.zk中的znode是什么样的结构

查询出来的都是属于当前节点znode的元数据

3.zk中节点znode的类型

持久节点和持久序号节点的演示:

临时节点演示:

1.

2.

3.进行关闭第一个创建临时test5节点的会话

4.继续演示第二个会话:

zookeeper可以实现服务的注册与发现:

其他节点演示:

创建临时序号节点:

创建容器节点:

过了一会,发现容器节点被删除了 !:

TTL节点是新出的,目前还吧稳定,了解即可。

4.zk的数据持久化

四:Zookeeper客户端(zkCli)的使用

1.多节点类型创建

详细步骤演示:

1.开启虚拟机,并且使用XShell进行远程连接虚拟机

2.

3.创建节点

2.查询节点

演示:

3.删除节点

普通删除:

乐观锁删除:

如图:

分析乐观锁与悲观锁:

所谓乐观锁删除,其实就是我们乐观的认为并发的请求数不多从而不上锁的方案 但说是不上锁 其实也会有一种锁的方式。这种锁的方式就是使用zookeeper节点

的版本号cversion,可以允许你有多个线程并发进来请求一个节点上的数据,但是不允许删除。

如何控制不允许删除?当多个并发线程进行请求获取一个节点上的数据之后,获取到的版本号cverion的值是一致的,但是当其中一个线程进行set操作进行修改节

点对应的值时,此时这个节点对应的版本号cverion的值就会+1.那么此时其他并发的线程使用版本号进行删除的时候,就会删除失败。(redis中的乐观锁同理,也

是给定一个version版本号)

与之对应的就是悲观锁,悲观锁其实就是悲观的认为并发请求数过大,我们必须进行上锁,这样的话,只有当获取到锁的线程才可以进行执行请求到资源,其他的

线程必须进行等待。

悲观锁与乐观锁对比:

悲观锁上锁之后,性能降低。乐观锁恰恰的保留的性能。

4.权限设定

开启两个会话进行演示权限的操作

五:Curator客户端的使用

其实Curator就是基于使用Java代码进行操作Zookeeper服务器对应的数据的客户端:

代码演示:

1.导入依赖

<properties>
  <java.version>1.8</java.version>
  <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
  <spring-boot.version>2.3.7.RELEASE</spring-boot.version>
</properties>
​
<dependencies>
​
  <dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
  </dependency>
​
  <dependency>
    <groupId>org.apache.zookeeper</groupId>
    <artifactId>zookeeper</artifactId>
    <version>3.4.14</version>
    <exclusions>
      <exclusion>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
      </exclusion>
      <exclusion>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-log4j12</artifactId>
      </exclusion>
      <exclusion>
        <groupId>log4j</groupId>
        <artifactId>log4j</artifactId>
      </exclusion>
    </exclusions>
  </dependency>
​
  <dependency>
    <groupId>org.apache.curator</groupId>
    <artifactId>curator-framework</artifactId>
    <version>2.12.0</version>
    <exclusions>
      <exclusion>
        <groupId>org.apache.zookeeper</groupId>
        <artifactId>zookeeper</artifactId>
      </exclusion>
      <exclusion>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
      </exclusion>
    </exclusions>
  </dependency>
  <dependency>
    <groupId>org.apache.curator</groupId>
    <artifactId>curator-recipes</artifactId>
    <version>2.12.0</version>
  </dependency>
  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
  </dependency>
​
  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
    <exclusions>
      <exclusion>
        <groupId>org.junit.vintage</groupId>
        <artifactId>junit-vintage-engine</artifactId>
      </exclusion>
    </exclusions>
  </dependency>
</dependencies>
​
<dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-dependencies</artifactId>
      <version>${spring-boot.version}</version>
      <type>pom</type>
      <scope>import</scope>
    </dependency>
  </dependencies>
</dependencyManagement>
​
<build>
  <plugins>
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-compiler-plugin</artifactId>
      <version>3.8.1</version>
      <configuration>
        <source>1.8</source>
        <target>1.8</target>
        <encoding>UTF-8</encoding>
      </configuration>
    </plugin>
    <plugin>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-maven-plugin</artifactId>
      <version>2.3.7.RELEASE</version>
      <configuration>
        <mainClass>com.qf.bootzkclient.BootZkClientApplication</mainClass>
      </configuration>
      <executions>
        <execution>
          <id>repackage</id>
          <goals>
            <goal>repackage</goal>
          </goals>
        </execution>
      </executions>
    </plugin>
  </plugins>
</build>

2.

3.进行配置配置类,注入到IOC容器中:

@Configuration
public class CuratorConfig {
​
​
    @Autowired
    WrapperZK wrapperZk;
​
    @Bean(initMethod = "start")
    public CuratorFramework curatorFramework() {
      return CuratorFrameworkFactory.newClient(
        wrapperZk.getConnectString(),
        wrapperZk.getSessionTimeoutMs(),
        wrapperZk.getConnectionTimeoutMs(),
        new RetryNTimes(wrapperZk.getRetryCount(), wrapperZk.getElapsedTimeMs()));
    }
    
}

4.Curator客户端对象注入到IOC容器中:

@Data
@Component
@ConfigurationProperties(prefix = "curator")
public class WrapperZK {
​
  private int retryCount;
​
  private int elapsedTimeMs;
​
  private String connectString;
​
  private int sessionTimeoutMs;
​
  private int connectionTimeoutMs;
}

对象的封装使用到了配置文件中的资源:

5.

6.对应测试操作:

@Slf4j
@SpringBootTest
class BootZkClientApplicationTests {
​
  @Autowired
  CuratorFramework curatorFramework;
​
//创建持久化节点
  @Test
  void createNode() throws Exception {
​
    //添加持久节点
    String path = curatorFramework.create().forPath("/curator-node");
    //添加临时序号节点
    String path1 = curatorFramework.create().withMode(CreateMode.EPHEMERAL_SEQUENTIAL).forPath("/curator-node", "some-data".getBytes());
    System.out.println(String.format("curator create node :%s  successfully.",path));
​
    System.in.read();
​
  }
//获取节点数据
  @Test
  public void testGetData() throws Exception {
    byte[] bytes = curatorFramework.getData().forPath("/curator-node");
    System.out.println(new String(bytes));
  }
//设置修改节点数据
  @Test
  public void testSetData() throws Exception {
    curatorFramework.setData().forPath("/curator-node","changed!".getBytes());
    byte[] bytes = curatorFramework.getData().forPath("/curator-node");
    System.out.println(new String(bytes));
  }
//
  @Test
  public void testCreateWithParent() throws Exception {
    String pathWithParent="/node-parent/sub-node-1";
    String path = curatorFramework.create().creatingParentsIfNeeded().forPath(pathWithParent);
    System.out.println(String.format("curator create node :%s  successfully.",path));
  }
//删除节点
  @Test
  public void testDelete() throws Exception {
    String pathWithParent="/node-parent";
    curatorFramework.delete().guaranteed().deletingChildrenIfNeeded().forPath(pathWithParent);
  }
​
  @Test
  public void addNodeListener() throws Exception {
​
    NodeCache nodeCache = new NodeCache(curatorFramework, "/curator-node");
    nodeCache.getListenable().addListener(new NodeCacheListener() {
      @Override
      public void nodeChanged() throws Exception {
        log.info("{} path nodeChanged: ","/curator-node");
        printNodeData();
      }
    });
​
    nodeCache.start();
​
    System.in.read();
​
  }
​
  public void printNodeData() throws Exception {
    byte[] bytes = curatorFramework.getData().forPath("/curator-node");
    log.info("data: {}",new String(bytes));
  }
​
​
​
}

代码演示细节记录:

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/blog/article/detail/54027
推荐阅读
相关标签
  

闽ICP备14008679号