从零开始手写RPC框架(3)——ZooKeeper入门

目录

  • ZooKeeper简介
    • ZooKeeper中的一些概念
  • ZooKeeper安装与常用命令
    • 常用命令
  • ZooKeeper Java客户端 Curator入门

ZooKeeper简介

是什么?

ZooKeeper 是一个开源的分布式协调服务,本身就是一个分布式程序(只要半数以上节点存活,ZooKeeper 就能正常服务)。
它的设计目标是将那些复杂且容易出错的分布式一致性服务封装起来,构成一个高效可靠的原语集,并以一系列简单易用的接口提供给用户使用。
ZooKeeper 底层其实只提供了两个功能:1、管理(存储、读取)用户程序提交的数据;2、 为用户程序提供数据节点监听服务。
ZooKeeper 将数据保存在内存中,性能是不错的。 在“读”多于“写”的应用程序中尤其地高性能,因为“写”会导致所有的服务器间同步状态。(“读”多于“写”是协调服务的典型场景)。
ZooKeeper 为我们提供了高可用、高性能、稳定的分布式数据一致性解决方案,通常被用于实现诸如数据发布/订阅、负载均衡、命名服务、分布式协调/通知、集群管理、Master 选举、分布式锁和分布式队列等功能。
这些功能的实现主要依赖于 ZooKeeper 提供的 数据存储+事件监听 功能。

特点

顺序一致性: 从同一客户端发起的事务请求,最终将会严格地按照顺序被应用到 ZooKeeper 中去。
原子性: 所有事务请求的处理结果在整个集群中所有机器上的应用情况是一致的,也就是说,要么整个集群中所有的机器都成功应用了某一个事务,要么都没有应用。
单一系统映像: 无论客户端连到哪一个 ZooKeeper 服务器上,其看到的服务端数据模型都是一致的。
可靠性: 一旦一次更改请求被应用,更改的结果就会被持久化,直到被下一次更改覆盖。
实时性: 每个客户端的系统视图都是最新的。


ZooKeeper中的一些概念

数据模型

ZooKeeper 数据模型采用层次化的多叉树形结构,每个节点上都可以存储数据,这些数据可以是数字、字符串或者是二进制序列。并且。每个节点还可以拥有 N 个子节点,最上层是根节点以“/”来代表。
每个数据节点在 ZooKeeper 中被称为`znode`,它是 ZooKeeper 中数据的最小单元。并且,每个 znode 都有一个唯一的路径标识。

在这里插入图片描述

ZooKeeper 主要是用来协调服务的,而不是用来存储业务数据的,所以不要放比较大的数据在 znode 上,ZooKeeper 给出的每个节点的数据大小上限是 1M 。


znode

znode 分为 4 大类:

持久(PERSISTENT)节点:一旦创建就一直存在即使 ZooKeeper 集群宕机,直到将其删除。
临时(EPHEMERAL)节点:临时节点的生命周期是与 客户端会话(session) 绑定的,会话消失则节点消失。并且,临时节点只能做叶子节点 ,不能创建子节点。
持久顺序(PERSISTENT_SEQUENTIAL)节点:除了具有持久(PERSISTENT)节点的特性之外, 子节点的名称还具有顺序性。比如 /node1/app0000000001、/node1/app0000000002 。
临时顺序(EPHEMERAL_SEQUENTIAL)节点:除了具备临时(EPHEMERAL)节点的特性之外,子节点的名称还具有顺序性

每个 znode 由 2 部分组成:

stat:状态信息
data:节点存放的数据的具体内容

stat:状态信息

下面通过 get 命令来获取 根目录下的 dubbo 节点的内容,来学习一下stat的各种状态信息。

[zk: 127.0.0.1:2181(CONNECTED) 6] get /dubbo
# 该数据节点关联的数据内容为空
null
# 下面是该数据节点的一些状态信息,其实就是 Stat 对象的格式化输出
cZxid = 0x2 #create ZXID,即该数据节点被创建时的事务 id
ctime = Tue Nov 27 11:05:34 CST 2018 #create time,即该节点的创建时间
mZxid = 0x2 #modified ZXID,即该节点最终一次更新时的事务 id
mtime = Tue Nov 27 11:05:34 CST 2018 #modified time,即该节点最后一次的更新时间
pZxid = 0x3 #该节点的子节点列表最后一次修改时的事务 id,只有子节点列表变更才会更新 pZxid,子节点内容变更不会更新
cversion = 1 #子节点版本号,当前节点的子节点每次变化时值增加 1
dataVersion = 0 #数据节点内容版本号,节点创建时为 0,每更新一次节点内容(不管内容有无变化)该版本号的值增加 1
aclVersion = 0 #节点的 ACL(权限控制)版本号,表示该节点 ACL 信息变更次数
ephemeralOwner = 0x0 #创建该临时节点的会话的 sessionId;如果当前节点为持久节点,则 ephemeralOwner=0
dataLength = 0 #数据节点内容长度
numChildren = 1 #当前节点的子节点个数
对于znode 操作的权限,ZooKeeper 提供了以下 5 种:CREATE : 能创建子节点 READ:能获取节点数据和列出其子节点 WRITE : 能设置/更新节点数据 DELETE : 能删除子节点 ADMIN : 能设置节点 ACL 的权限
对于身份认证,提供了以下几种方式:world:默认方式,所有用户都可无条件访问。auth :不使用任何 id,代表任何已认证的用户。digest :用户名:密码认证方式:username:password 。ip : 对指定 ip 进行限制。

Watcher(事件监听器)

Watcher(事件监听器)是 ZooKeeper 中的一个很重要的特性

ZooKeeper 允许用户在指定节点上注册一些 Watcher,并且在一些特定事件触发的时候,ZooKeeper 服务端会将事件通知到感兴趣的客户端上去,该机制是 ZooKeeper 实现分布式协调服务的重要特性。

在这里插入图片描述


Session sessionTimeout sessionID

Session 是 ZooKeeper 服务器与客户端之间的长连接。通过这个连接,客户端可以保持有效的会话、发送请求并接收响应,还能接收来自服务器的 Watcher 事件通知。
会话有一个属性叫做 sessionTimeout,代表会话的超时时间。如果客户端连接断开,只要在规定的时间内重新连接上集群中的任意一台服务器,之前创建的会话仍然有效。
在为客户端创建会话之前,服务端会为每个客户端分配一个全局唯一的 sessionID,作为会话的标识。

ZooKeeper 集群

ZooKeeper 是一种分布式协调服务,为了保证高可用性,通常以集群形式部署。由 3 台服务器即可组成ZooKeeper 集群。这些服务器在内存中维护当前状态,并通过 ZAB 协议(ZooKeeper Atomic Broadcast)保持数据一致性。常见的集群模式是 Master/Slave,其中 Master 服务器提供写服务,而 Slave 服务器通过异步复制获取最新数据并提供读服务。ZooKeeper 中不再使用传统的 Master/Slave 概念,而是引入了三种角色:Leader、Follower 和 Observer。
ZooKeeper 集群中的所有机器通过 Leader 选举 来选定一台称为“Leader”的机器。Leader 既可以为客户端提供写服务,又能提供读服务。除了 Leader 外,Follower 和 Observer 都只能提供读服务。Follower 和 Observer 唯一的区别在于 Observer 机器不参与 Leader 的选举过程,也不参与写操作的“过半写成功”策略,因此可以在不影响写性能的情况下提升集群的读性能。
当 Leader 服务器出现网络中断、崩溃退出与重启等异常情况时,就会进入 Leader 选举过程,这个过程会选举产生新的 Leader 服务器。ZooKeeper 集群中的服务器状态有下面几种:LOOKING:寻找 Leader。LEADING:Leader 状态,对应的节点为 Leader。FOLLOWING:Follower 状态,对应的节点为 Follower。OBSERVING:Observer 状态,对应节点为 Observer,该节点不参与 Leader 选举。
由于在选举时一个结点得到超半的票数才能成为Leader,所以ZooKeeper 集群在宕掉几个 ZooKeeper 服务器之后,如果剩下的 ZooKeeper 服务器个数大于宕掉的个数的话整个 ZooKeeper 才依然可用。所以ZooKeeper 集群最好是奇数台,因为2n 和 2n-1 的容忍度是一样的,何必增加那一个不必要的 ZooKeeper 呢。
对于一个集群,通常多台机器会部署在不同机房,来提高这个集群的可用性。保证可用性的同时,会发生一种机房间网络线路故障,导致机房间网络不通,而集群被割裂成几个小集群。这时候子集群各自选主导致“脑裂”的情况。ZooKeeper 的过半机制导致不可能产生 2 个 leader,因为少于等于一半是不可能产生 leader 的,这就使得不论机房的机器如何分配都不可能发生脑裂。
Paxos 算法应该可以说是 ZooKeeper 的灵魂了。但是,ZooKeeper 并没有完全采用 Paxos 算法 ,而是使用 ZAB 协议作为其保证数据一致性的核心算法。ZAB(ZooKeeper Atomic Broadcast 原子广播) 协议是为分布式协调服务 ZooKeeper 专门设计的一种支持崩溃恢复的原子广播协议。 在 ZooKeeper 中,主要依赖 ZAB 协议来实现分布式数据一致性,基于该协议,ZooKeeper 实现了一种主备模式的系统架构来保持集群中各个副本之间的数据一致性。
ZAB 协议包括两种基本的模式,分别是崩溃恢复:当整个服务框架在启动过程中,或是当 Leader 服务器出现网络中断、崩溃退出与重启等异常情况时,ZAB 协议就会进入恢复模式并选举产生新的 Leader 服务器。当选举产生了新的 Leader 服务器,同时集群中已经有过半的机器与该 Leader 服务器完成了状态同步之后,ZAB 协议就会退出恢复模式。消息广播:当集群中已经有过半的 Follower 服务器完成了和 Leader 服务器的状态同步,那么整个服务框架就可以进入消息广播模式了。

在这里插入图片描述





ZooKeeper安装与常用命令

使用Docker安装zookeeper(Dokcer入门可以参考这篇博客)

docker pull zookeeper:3.5.8

运行 ZooKeeper容器

docker run -d --name zookeeper -p 2181:2181 zookeeper:3.5.8

进入容器,然后再进入bin目录

docker exec -it zookeeper bash
cd bin/

连接ZooKeeper服务

./zkCli.sh -server 127.0.0.1:2181

请添加图片描述

安装演示完毕,下面演示常用命令。



常用命令

可以通过help查看常用命令。

创建节点(create 命令)

使用 create 命令可以在指定路径下创建一个 Znode。标志参数指定了创建的 Znode 是临时、持久还是顺序的。默认情况下,所有 Znodes 都是持久的。
临时 Znodes(标志:-e)在会话过期或客户端断开连接时会自动删除。
顺序 Znodes 确保 Znode 路径是唯一的,并在路径后添加序列号。例如,路径 /myapp 可能会被转换为 /myapp0000000001。

示例:

创建持久 Znode:create /FirstZnode "Myfirstzookeeper-app"
创建顺序 Znode:create -s /FirstZnode "second-data"
创建临时 Znode:create -e /SecondZnode "Ephemeral-data"

通过create 命令在根目录创建了 node1 节点,与它关联的字符串是"node1"

[zk: 127.0.0.1:2181(CONNECTED) 5] create /node1 "node1"

通过 create 命令在node1 节点下创建了 node1.1 节点,与它关联的内容是数字 123

[zk: 127.0.0.1:2181(CONNECTED) 18] get -s /node1/node1.1
123
cZxid = 0x3
ctime = Sat Mar 02 12:04:01 UTC 2024
mZxid = 0x3
mtime = Sat Mar 02 12:04:01 UTC 2024
pZxid = 0x3
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 3
numChildren = 0

获取节点数据(get 命令)

使用 get 命令可以获取指定 Znode 的关联数据和元数据。
默认情况下,get 命令只返回节点的名称,而不包含数据。
要获取节点的数据,请使用 -s 标志。
示例:
获取节点名称:get /myapp
获取节点数据:get -s /myapp

监事节点变化(get -w命令)

使用 get 命令并设置 watch 标志,可以监视指定 Znode 的变化。例如:get -w /myapp:监视 /myapp 的变化。

更新节点数据内容(set 命令)

更新node1结点数据内容为字符串"set node1"

[zk: 127.0.0.1:2181(CONNECTED) 11] set /node1 "set node1"

查看某个目录下的子节点(ls 命令)

通过 ls 命令查看 node1 目录下的节点

[zk: 127.0.0.1:2181(CONNECTED) 12] ls /node1
[node1.1]

查看节点状态(stat 命令)

[zk: 127.0.0.1:2181(CONNECTED) 19] stat /node1
cZxid = 0x2
ctime = Sat Mar 02 12:03:26 UTC 2024
mZxid = 0x2
mtime = Sat Mar 02 12:03:26 UTC 2024
pZxid = 0x3
cversion = 1
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 5
numChildren = 1

查看节点信息和状态(ls2 或ls -s命令)

ls2 命令更像是 ls 命令和stat 命令的结合。ls2 命令返回的信息包括 2 部分:1. 子节点列表 2. 当前节点的 stat 信息。

[zk: 127.0.0.1:2181(CONNECTED) 20] ls2 /node1
‘ls2’ has been deprecated. Please use ‘ls [-s] path’ instead.
[node1.1]
cZxid = 0x2
ctime = Sat Mar 02 12:03:26 UTC 2024
mZxid = 0x2
mtime = Sat Mar 02 12:03:26 UTC 2024
pZxid = 0x3
cversion = 1
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 5
numChildren = 1

删除节点(delete 命令)

如果你要删除某一个节点,那么这个节点必须无子节点才行。

[zk: 127.0.0.1:2181(CONNECTED) 3] delete /node1/node1.1




ZooKeeper Java客户端 Curator入门

Curator 是Netflix公司开源的一套 ZooKeeper Java客户端框架,相比于 Zookeeper 自带的客户端zookeeper 来说,Curator 的封装更加完善,各种 API 都可以比较方便地使用。

Curator4.0+版本对ZooKeeper 3.5.x支持比较好。开始之前将下面的依赖添加进项目。

<dependency>
	<groupId>org.apache.curator</groupId>
	<artifactId>curator-framework</artifactId>
	<version>4.2.0</version>
</dependency>
<dependency>
	<groupId>org.apache.curator</groupId>
	<artifactId>curator-recipes</artifactId>
	<version>4.2.0</version>
</dependency>

连接 ZooKeeper 客户端

通过CuratorFrameworkFactory 创建CuratorFramework 对象,然后再调用 CuratorFramework 对象的 start() 方法即可

private static final int BASE_SLEEP_TIME = 1000; //重试之间等待的初始时间
private static final int MAX_RETRIES = 3; //最大重试次数

// Retry strategy. Retry 3 times, and will increase the sleep time between
retries.
// 创建一个重试策略,使用指数退避重试,这意味着每次重试之间的等待时间会逐渐增加
RetryPolicy retryPolicy = new ExponentialBackoffRetry(BASE_SLEEP_TIME,
MAX_RETRIES);

// 创建一个ZooKeeper客户端
CuratorFramework zkClient = CuratorFrameworkFactory.builder()
	// the server to connect to (can be a server list)
	.connectString("127.0.0.1:2181") //要连接的服务器列表
	.retryPolicy(retryPolicy) //重试策略
	.build();
zkClient.start();//启动一个ZooKeeper客户端,建立与ZooKeeper服务器的连接。



数据节点的增删改查

我们前面介绍通常是将 znode 分为 4 大类:

持久(PERSISTENT)节点:一旦创建就一直存在即使 ZooKeeper 集群宕机,直到将其删除。
临时(EPHEMERAL)节点:临时节点的生命周期是与 客户端会话(session) 绑定的,会话消失则节点消失。并且,临时节点只能做叶子节点 ,不能创建子节点。
持久顺序(PERSISTENT_SEQUENTIAL)节点:除了具有持久(PERSISTENT)节点的特性之外, 子节点的名称还具有顺序性。比如 /node1/app0000000001、/node1/app0000000002 。
临时顺序(EPHEMERAL_SEQUENTIAL)节点:除了具备临时(EPHEMERAL)节点的特性之外,子节点的名称还具有顺序性

在使用的 ZooKeeper 的时候,会发现 CreateMode 类中实际有 7种 znode 类型 ,但是用的最多的还是上面介绍的 4 种。

创建节点

a.创建持久化节点

zkClient.create().forPath("/node1/00001");
zkClient.create().withMode(CreateMode.PERSISTENT).forPath("/node1/00002");

//父节点node1还未创建时运行上面代码会报错,或者可以选择下面的代码,父节点node1不存在时自动创建

zkClient.create().creatingParentsIfNeeded().withMode(CreateMode.PERSISTENT).forPath("/node1/00001");

b.创建临时节点

zkClient.create().creatingParentsIfNeeded().withMode(CreateMode.EPHEMERAL).forPath("/node1/00001");

c.创建节点并指定数据内容

zkClient.create().creatingParentsIfNeeded().withMode(CreateMode.PERSISTENT).forPath("/node1/00001", "java".getBytes());
byte[] dataStr = zkClient.getData().forPath("/node1/00001");//获取节点的数据内容并输出,获取到的是byte数组
System.out.println(new String(dataStr)); //获取节点的数据内容并转换为字符串

d.检测节点是否存在

if (zkClient.checkExists().forPath("/node1/00001") != null) {
    System.out.println("节点存在");
} else {
    System.out.println("节点不存在");
}
//不为null的话会返回一个Stat对象,Stat对象包含了节点的元数据,如版本号、创建时间等,说明刚刚节点创建成功了,


删除节点

a.删除一个子节点

zkClient.delete().forPath("/node1/00001");

b.删除一个节点以及其下的所有子节点

zkClient.delete().deletingChildrenIfNeeded().forPath("/node1");


获取/更新节点数据内容

zkClient.create().creatingParentsIfNeeded().withMode(CreateMode.EPHEMERAL).forPath("/node1/00001","java".getBytes());
zkClient.getData().forPath("/node1/00001");//获取节点的数据内容
zkClient.setData().forPath("/node1/00001","c++".getBytes());//更新节点数据内容

获取某个节点的所有子节点路径

List<String> childrenPaths = zkClient.getChildren().forPath("/node1");




监听器

下面通过一个案例演示监听器的用法,下面是给某个节点注册子节点监听器 。注册了监听器之后,这个节点的子节点发生变化比如增加、减少或者更新的时候,你可以自定义回调操作。

String path = "/node1";
// 创建一个PathChildrenCache,它用于监听ZNode的子节点的变化
PathChildrenCache pathChildrenCache = new PathChildrenCache(zkClient, path,true);//true代表节点的数据内容也会被获取并存储在ChildData对象中
        
// 创建一个监听器
PathChildrenCacheListener pathChildrenCacheListener = (curatorFramework,
                                                       pathChildrenCacheEvent) -> {
    // do something 这里是当监听到子节点变化时要执行的代码
};
// 将监听器添加到PathChildrenCache
pathChildrenCache.getListenable().addListener(pathChildrenCacheListener);
// 启动PathChildrenCache
pathChildrenCache.start();

PathChildrenCacheListener的适用范围确实比较广,它可以用来监听ZooKeeper中任何ZNode的子节点的变化。然而,如果你想要监听ZNode本身的变化(例如,ZNode被删除或者ZNode的数据被改变),那么你需要使用NodeCache和NodeCacheListener。同样,如果你想要监听ZooKeeper的状态变化(例如,从连接状态变为断开状态),那么你需要使用ConnectionStateListener。

对于NodeCacheListener和ConnectionStateListener,它们的使用方式和PathChildrenCacheListener类似,但是需要使用NodeCache和CuratorFramework来注册。具体来说:

  • NodeCacheListener需要使用NodeCache来注册,NodeCache用于监听一个ZNode本身的变化。
  • ConnectionStateListener需要使用CuratorFramework来注册,CuratorFramework用于监听ZooKeeper的连接状态变化。

如果你要获取节点事件类型的话,可以通过:

pathChildrenCacheEvent.getType()

一共有下面几种类型:

public static enum Type {
	CHILD_ADDED,//子节点增加
	CHILD_UPDATED,//子节点更新
	CHILD_REMOVED,//子节点被删除
	CONNECTION_SUSPENDED,// 连接暂停,可能是因为网络问题
	CONNECTION_RECONNECTED,// 连接重新建立,之前的问题可能已经解决
	CONNECTION_LOST,// 连接丢失,可能是服务器端关闭了连接
	INITIALIZED;// PathChildrenCache已经初始化完成
	private Type() {
	}
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

django-admin登录窗口添加验证码功能-(替换原有的login.html)captcha插件

需求&#xff1a; 1&#xff1a;更改django框架的admin登录窗口标题 2&#xff1a;在admin登录窗口中添加验证码功能 3&#xff1a;验证码允许点击更换 步骤如下&#xff1a; 1:安装插件以及在安装列表中添加插件 2:自定义表单forms.py 3:创建login.html文件(复制django内置的l…

中国电子学会2020年6月份青少年软件编程Sc ratch图形化等级考试试卷四级真题。

第 1 题 【 单选题 】 1.执行下面程序&#xff0c;输入4和7后&#xff0c;角色说出的内容是&#xff1f; A&#xff1a;4&#xff0c;7 B&#xff1a;7&#xff0c;7 C&#xff1a;7&#xff0c;4 D&#xff1a;4&#xff0c;4 2.执行下面程序&#xff0c;输出是&#xff…

备战蓝桥杯Day22 - 计数排序

计数排序问题描述 对列表进行排序&#xff0c;已知列表中的数范围都在0-100之间。设计时间复杂度为O(n)的算法。 比如列表中有一串数字&#xff0c;2 5 3 1 6 3 2 1 &#xff0c;需要将他们按照从小到大的次序排列&#xff0c;得到1 1 2 2 3 3 5 6 的结果。那么此时计数排序是…

每天一道leetcode:14.最长公共前缀(简单)

⭐今日份题目 编写一个函数来查找字符串数组中的最长公共前缀。 如果不存在公共前缀&#xff0c;返回空字符串 ""。 示例1 输入&#xff1a;strs ["flower","flow","flight"] 输出&#xff1a;"fl" 示例2 输入&#…

制作镜像与配置推送阿里云仓库

一、制作jdk镜像 1.1、Alpine linux简介 Alpine Linux是一个轻量级的Linux发行版&#xff0c;专注于安全、简洁和高效。它采用了musl libc和BusyBox&#xff0c;使得系统资源占用较少&#xff0c;启动速度较快。 Alpine Linux也提供了一个简单的包管理工具APK&#xff0c;(注…

MySQL:索引的优化方法

索引是帮助存储引擎快速获取数据的一种数据结构&#xff0c;形象的说就是索引是数据的目录。 索引创建的时机&#xff1a; 索引并不是越多越好的&#xff0c;虽然他再查询时会提高效率&#xff0c;但是保存索引和维护索引也需要一定的空间和时间成本的。 不创建索引&#xff1a…

消防主机报故障时发出故障及原因及解决办法!

本文以青鸟消防JBF-11SF为例。 其他型号或品牌的消防主机也可参考。 开机前&#xff0c;必须先测量系统接线的绝缘电阻&#xff0c;确保各绝缘电阻满足以下要求&#xff1a; 1&#xff09;空载时各电路信号线之间的绝缘值应大于5K欧姆。 2&#xff09;正常天气条件下&#x…

10 计算机结构

冯诺依曼体系结构 冯诺依曼体系结构&#xff0c;也被称为普林斯顿结构&#xff0c;是一种计算机架构&#xff0c;其核心特点包括将程序指令存储和数据存储合并在一起的存储器结构&#xff0c;程序指令和数据的宽度相同&#xff0c;通常都是16位或32位 我们常见的计算机,笔记本…

C语言第三十四弹---动态内存管理(下)

✨个人主页&#xff1a; 熬夜学编程的小林 &#x1f497;系列专栏&#xff1a; 【C语言详解】 【数据结构详解】 动态内存管理 1、动态内存经典笔试题分析 1.1、题目1 1.2、题目2 1.3、题目3 1.4、题目4 2、柔性数组 2.1、柔性数组的特点 2.2、柔性数组的使用 2.3、…

68-解构赋值,迭代器,生成器函数,Symbol

1.解构赋值(针对数组array&#xff0c;字符串String及对象object以) 结构赋值是一种特殊的语法&#xff0c;通过将各种结构中的元素复制到变量中达到"解构"的目的&#xff0c;但是数组本身没有改变 1.1解构单层数组 <script>let arr [1,2,3,4,5];//获取数组…

【微服务】微服务中常用认证加密方案总结

目录 一、前言 二、登录认证安全问题 3.1 认证方式选择 三、常用的加密方案 3.1 MD5加密算法 3.1.1 md5特点 3.1.2 md5原理 3.1.3 md5使用场景 3.2 AES加密算法 3.2.1 AES简介 3.2.2 AES加解原理 3.2.3 AES算法优缺点 3.2.4 AES算法使用场景 3.3 RSA加密算法 3.3…

【每日一题】找到字符串中所有字母异位词

目录 题目&#xff1a;思路&#xff1a;暴力枚举&#xff1a;滑动窗口&#xff1a; 代码实现&#xff1a;一些优化&#xff1a;代码实现&#xff1a; 题目&#xff1a; 找到字符串中所有字母异位词 思路&#xff1a; 暴力枚举&#xff1a; 对于有关子串的题目我们使用暴力枚…

1.2 在卷积神经网络中,如何计算各层感受野的大小

1.2 在卷积神经网络中&#xff0c;如何计算各层感受野的大小 分析与解答&#xff1a; 在卷积神经网络中&#xff0c;由于卷积的局部连接性&#xff0c;输出特征图上的每个节点的取值&#xff0c;是由卷积核在输入特征图对应位置的局部区域内进行卷积而得到的&#xff0c;因此这…

Sora惊艳出世,AI能否给人类带来新的“视界”?

2月16日&#xff0c;OpenAI公司公布了其首个文生视频大模型Sora&#xff0c;同时展示了多个由Sora生成的最长时间达一分钟的视频&#xff0c;引起科技圈震动。 钢铁侠马斯克对其发出“人类愿赌服输”的感叹&#xff0c;360董事长周鸿祎也作出“Sora意味着AGI实现将从10年缩短到…

【探索Linux】—— 强大的命令行工具 P.24(网络基础)

阅读导航 引言一、计算机网络背景1. 网络发展历史 二、认识 "协议"1. 网络协议概念2. 网络协议初识&#xff08;1&#xff09;协议分层&#xff08;2&#xff09;OSI参考模型&#xff08;Open Systems Interconnection Reference Model&#xff09;&#xff08;3&…

k8s-kubeapps图形化管理 21

结合harbor仓库 由于kubeapps不读取hosts解析&#xff0c;因此需要添加本地仓库域名解析&#xff08;dns解析&#xff09; 更改context为全局模式 添加repo仓库 复制ca证书 添加成功 图形化部署 更新部署应用版本 再次进行部署 上传nginx 每隔十分钟会自动进行刷新 在本地仓库…

基于YOLOv8/YOLOv7/YOLOv6/YOLOv5的教室人员检测与计数(Python+PySide6界面+训练代码)

摘要&#xff1a;开发教室人员检测与计数系统对于优化教学资源和提升教学效率具有重要意义。本篇博客详细介绍了如何利用深度学习构建此系统&#xff0c;并提供了完整的实现代码。该系统基于强大的YOLOv8算法&#xff0c;并对比了YOLOv7、YOLOv6、YOLOv5的性能&#xff0c;展示…

vue2本地开发环境正常,生产环境下this.$router.push({ name: ‘login‘ })不跳转

如果在Vue.js 2中在本地开发环境下正常运行,但在生产环境下使用​​this.$router.push({ name: login })​​不起作用,可能有几个原因需要检查和解决: 路由配置问题: 确保你的路由配置正确,特别是确保在生产环境中,路由的配置和本地开发环境一致。检查是否正确设置了name…

以目标检测和分类任务为例理解One-Hot Code

在目标检测和分类任务中&#xff0c;每一个类别都需要一个编码来表示&#xff0c;同时&#xff0c;这个编码会用来计算网络的loss。比如有猫&#xff0c;狗&#xff0c;猪三种动物&#xff0c;这三种动物相互独立&#xff0c;在分类中&#xff0c;将其中任意一种分类为其他都同…

【大数据Hive】hive 多字段分隔符使用详解

目录 一、前言 二、hive默认分隔符规则以及限制 2.1 正常示例&#xff1a;单字节分隔符数据加载示例 2.2 特殊格式的文本数据&#xff0c;分隔符为特殊字符 2.2.1 文本数据的字段中包含了分隔符 三、突破默认限制规则约束 3.1 数据加载不匹配情况 1 3.2 数据加载不匹配…