当前位置: 首页 > news >正文

中间件 - 分布式协调服务Zookeeper

目录

一. 前言

二. 树状结构

2.1. ZNode

2.1.1. stat

2.1.2. ACL

三. NameService命名服务

四. Configuration 配置管理

五. GroupMembers 集群管理

六. 集群三个角色及状态

七. 选举算法

八. Watcher

九. 设计目的

十. 典型使用场景


一. 前言

    Zookeeper是一个分布式的,开放源码的分布式应用程序协调服务,是Google的Chubby一个开源的实现,是Hadoop和Hbase的重要组件。它是一个为分布式应用提供一致性服务的软件,提供的功能包括:配置维护、命名服务、分布式同步、组服务等。  

 Zookeeper 作为一个分布式的服务框架,主要用来解决分布式集群中应用系统的一致性问题,它能提供基于类似于文件系统的目录节点树方式的数据存储, Zookeeper 作用主要是用来维护和监控存储的数据的状态变化,通过监控这些数据状态的变化,从而达到基于数据的集群管理。

 简单的说,Zookeeper=文件系统+通知机制。

二. 树状结构

/zookeeper节点和/controller_epoch节点是zookeeper自带的默认节点。

2.1. ZNode

Zookeeper有四种类型的znode:
1). PERSISTENT-持久化目录节点:客户端与zookeeper断开连接后, 该节点依旧存在。
2). PERSISTENT_SEQUENTIAL-持久化顺序编号目录节点:客户端与zookeeper断开连接后,该节点依旧存在,只是Zookeeper给该节点名称进行顺序编号。
3). EPHEMERAL-临时目录节点:客户端与zookeeper断开连接后,该节点被删除。
4). EPHEMERAL_SEQUENTIAL-临时顺序编号目录节点:客户端与zookeeper断开连接后,该节点被删除,只是Zookeeper给该节点名称进行顺序编号。

顺序编号:共有10位长的数字,从0000000000开始,每增加一个节点,末位加1。

每一个ZNode都由三部分组成:
data:与该ZNode关联的数据。
stat:状态信息, 描述此ZNode的版本时间权限等信息。
children:该ZNode下的子节点。

2.1.1. stat

cZxid:这是导致创建znode更改的事务ID。
mZxid:这是最后修改znode更改的事务ID。
pZxid:这是用于添加或删除子节点的znode更改的事务ID。
ctime:表示从1970-01-01T00:00:00Z开始以毫秒为单位的znode创建时间。
mtime:表示从1970-01-01T00:00:00Z开始以毫秒为单位的znode最近修改时间。
dataVersion:表示对该znode的数据所做的更改次数。
cversion:这表示对此znode的子节点进行的更改次数。
aclVersion:表示对此znode的ACL进行更改的次数。
ephemeralOwner:如果znode是ephemeral类型节点,则这是znode所有者的 session ID。 如果znode不是ephemeral节点,则该字段设置为零。
dataLength:这是znode数据字段的长度。
numChildren:这表示znode的子节点的数量。

2.1.2. ACL

    概述:传统的文件系统中,ACL分为两个维度,一个是属组,一个是权限,子目录/文件默认继承父目录的ACL。而在Zookeeper中,node的ACL是没有继承关系的,是独立控制的。Zookeeper的ACL,可以从三个维度来理解:一是scheme;二是user;三是permission,通常表示为scheme:id:permissions, 下面从这三个方面分别来介绍:
1). scheme: scheme对应于采用哪种方案来进行权限管理,zookeeper实现了一个pluggable的ACL方案,可以通过扩展scheme,来扩展ACL的机制。

zookeeper-3.4.4缺省支持下面几种scheme:
world: 它下面只有一个id, 叫anyone, world:anyone代表任何人,zookeeper中对所有人有权限的结点就是属于world:anyone的
auth: 它不需要id, 只要是通过authentication的user都有权限(zookeeper支持通过kerberos来进行authencation, 也支持username/password形式的authentication)
digest: 它对应的id为username:BASE64(SHA1(password)),它需要先通过username:password形式的authentication
ip: 它对应的id为客户机的IP地址,设置的时候可以设置一个ip段,比如ip:192.168.1.0/16, 表示匹配前16个bit的IP段
super: 在这种scheme情况下,对应的id拥有超级权限,可以做任何事情(cdrwa)。


另外,zookeeper-3.4.4的代码中还提供了对sasl的支持,不过缺省是没有开启的,需要配置才能启用。sasl: sasl的对应的id,是一个通过sasl authentication用户的id,zookeeper-3.4.4中的sasl authentication是通过kerberos来实现的,也就是说用户只有通过了kerberos认证,才能访问它有权限的node。

2). id: id与scheme是紧密相关的,具体的情况在上面介绍scheme的过程都已介绍,这里不再赘述。

3). permission: zookeeper目前支持下面一些权限:
CREATE(c): 创建权限,可以在在当前node下创建child node
DELETE(d): 删除权限,可以删除当前的node
READ(r): 读权限,可以获取当前node的数据,可以list当前node所有的child nodes
WRITE(w): 写权限,可以向当前node写数据
ADMIN(a): 管理权限,可以设置当前node的permission

三. NameService命名服务

    这个最简单,在Zookeeper的文件系统里创建一个目录,即有唯一的path,在我们无法确定上游程序的部署机器时即可与下游程序约定好path,通过path即能互相探索发现。

    这个主要是作为分布式命名服务,通过调用Zookeeper的create node api,能够很容易创建一个全局唯一的path,这个path就可以作为一个名称。

四. Configuration 配置管理

    把需要增加的配置全部放到Zookeeper上去,保存在 Zookeeper的某个目录节点中,然后所有相关应用程序对这个目录节点进行监听,一旦配置信息发生变化,每个应用程序就会收到 Zookeeper 的通知,然后从 Zookeeper 获取新的配置信息应用到系统中就完成了配置管理。

五. GroupMembers 集群管理

    所谓集群管理无外乎两点:是否有机器加入和退出、选举master。
    对于第一点,所有机器约定在父目录GroupMembers下创建临时目录节点,然后监听父目录节点的子节点变化消息。一旦有机器挂掉,该机器与 zookeeper的连接断开,其所创建的临时目录节点被删除,所有其他机器都收到通知:某个兄弟目录被删除,于是,所有人都知道了。新机器加入也是类似,所有机器收到通知:新兄弟目录加入,highcount又有了。
    对于第二点,所有机器创建临时顺序编号目录节点,通过master选举算法选举出来。

六. 集群三个角色及状态

1. Leader
 Leader服务器是整个zookeeper集群工作机制中的核心,其主要工作有以下两个:
          a. 事物请求的唯一调度和处理者,保证集群事务处理的顺序性。
          b. 集群内部各个服务器的调度者。

2. Follower
 从角色名字可以看出,Follower服务器是zookeeper集群状态的跟随者,其主要工作有以下三个:
 a. 处理客户端非事物请求,转发事物请求给Leader服务器。
 b. 参与事务请求Proposal的投票。
 c. 参与Leader选举投票。

3. Observer
 和Follower唯一的区别在于,Observer不参与任何形式的投票,包括事物请求Proposal的投票和Leader选举投票。
 简单地讲,Observer服务器只提供非事物服务,通常用于在不影响集群事务处理能力的前提下提升集群的非事物处理能力。
  
 节点状态

 Zookeeper节点有四种状态:Looking、Following、Leading、Observing
 Looking:寻找Leader状态,当Server处于该状态时,此Server会认为当前集群中没有Leader,需要进入Leader选举状态。
 Following: 跟随者状态,表明该Server角色为Follower。
 Leading: 领导者状态,表明当前服务器角色是Leader。
 Observing: 观察者状态,表明当前服务器角色是Observer。

七. 选举算法

    Zookeeper中有三种选举算法,分别是LeaderElection(基于basic paxos实现),FastLeaderElectionAuthLeaderElection

  FastLeaderElection和AuthLeaderElection(都是基于fast paxos实现)是类似的选举算法,唯一区别是后者加入了认证信息,FastLeaderElection比LeaderElection更高效。

  basic paxos流程:

  1 .选举线程由当前Server发起选举的线程担任,其主要功能是对投票结果进行统计,并选出推荐的Server;
  2 .选举线程首先向所有Server发起一次询问(包括自己);
  3 .选举线程收到回复后,验证是否是自己发起的询问(验证zxid是否一致),然后获取对方的id(myid),并存储到当前询问对象列表中,最后获取对方提议的leader相关信息(id,zxid),并将这些信息存储到当次选举的投票记录表中;
  4. 收到所有Server回复以后,就计算出zxid最大的那个Server,并将这个Server相关信息设置成下一次要投票的Server;
  5. 线程将当前zxid最大的Server设置为当前Server要推荐的Leader,如果此时获胜的Server获得n/2 + 1的Server票数, 设置当前推荐的leader为获胜的Server,将根据获胜的Server相关信息设置自己的状态,否则,继续这个过程,直到leader被选举出来。
  通过流程分析我们可以得出:要使Leader获得多数Server的支持,则Server总数必须是奇数2n+1,且存活的Server的数目不得少于n+1。


  fast paxos流程:

  在选举过程中,某Server首先向所有Server提议自己要成为leader,当其它Server收到提议以后,解决epoch和 zxid的冲突,并接受对方的提议,然后向对方发送接受提议完成的消息,重复这个流程,最后一定能选举出Leader。

八. Watcher

    Watcher是Zookeeper用来实现distribute lock, distribute configure, distribute queue等应用的主要手段。要监控data_tree上的任何节点的变化(节点本身的增加,删除,数据修改,以及子节点的变化)都可以在获取该数据时注册一个Watcher,这有很像Listener模式。一旦该节点数据变化,Follower会发送一个notification response,client收到notification响应,则会查找对应的Watcher并回调他们。

 Client可以在某个ZNode上设置一个Watcher,来Watch该ZNode上的变化。如果该ZNode上有相应的变化,就会触发这个Watcher,把相应的事件通知给设置Watcher的Client。需要注意的是,ZooKeeper中的Watcher是一次性的,即触发一次就会被取消,如果想继续Watch的话,需要客户端重新设置Watcher。

 atomic broadcasts原子广播
 Zookeeper的核心是原子广播,这个机制保证了各个Server之间的同步。实现这个机制的协议叫做Zab协议。Zab协议有两种模式,它们分 别是恢复模式(选主)和广播模式(同步)。当服务启动或者在领导者崩溃后,Zab就进入了恢复模式,当领导者被选举出来,且大多数Server完成了和 leader的状态同步以后,恢复模式就结束了。状态同步保证了leader和Server具有相同的系统状态。

Watcher 特性总结
    1. 注册只能确保一次消费
    无论是服务端还是客户端,一旦一个 Watcher 被触发,ZooKeeper 都会将其从相应的存储中移除。因此,开发人员在 Watcher 的使用上要记住的一点是需要反复注册。这样的设计有效地减轻了服务端的压力。如果注册一个 Watcher 之后一直有效,那么针对那些更新非常频繁的节点,服务端会不断地向客户端发送事件通知,这无论对于网络还是服务端性能的影响都非常大。

    2. 客户端串行执行
    客户端 Watcher 回调的过程是一个串行同步的过程,这为我们保证了顺序,同时,需要开发人员注意的一点是,千万不要因为一个 Watcher 的处理逻辑影响了整个客户端的 Watcher 回调。

    3. 轻量级设计
    WatchedEvent 是 Zookeeper 整个 Watcher 通知机制的最小通知单元,这个数据结构中只包含三部分的内容:通知状态、事件类型和节点路径。也就是说,Watcher 通知非常简单,只会告诉客户端发生了事件,而不会说明事件的具体内容。例如针对 NodeDataChanged 事件,ZooKeeper 的 Watcher 只会通知客户指定数据节点的数据内容发生了变更,而对于原始数据以及变更后的新数据都无法从这个事件中直接获取到,而是需要客户端主动重新去获取数据,这也是 ZooKeeper 的 Watcher 机制的一个非常重要的特性。

九. 设计目的

1. 最终一致性:client不论连接到哪个Server,展示给它都是同一个视图,这是zookeeper最重要的性能。
2. 可靠性:具有简单、健壮、良好的性能,如果消息m被到一台服务器接受,那么它将被所有的服务器接受。
3. 实时性:Zookeeper保证客户端将在一个时间间隔范围内获得服务器的更新信息,或者服务器失效的信息。但由于网络延时等原因,Zookeeper不能保证两个客户端能同时得到刚更新的数据,如果需要最新数据,应该在读数据之前调用sync()接口。
4. 等待无关(wait-free):慢的或者失效的client不得干预快速的client的请求,使得每个client都能有效的等待。
5. 原子性:更新只能成功或者失败,没有中间状态。
6. 顺序性:包括全局有序和偏序两种:全局有序是指如果在一台服务器上消息a在消息b前发布,则在所有Server上消息a都将在消息b前被发布;偏序是指如果一个消息b在消息a后被同一个发送者发布,a必将排在b前面

十. 典型使用场景

    Zookeeper是一个高可用的分布式数据管理与系统协调框架。基于对Paxos算法的实现,使该框架保证了分布式环境中数据的强一致性,也正是基于这样的特性,使得zookeeper能够应用于很多场景。

1. 数据发布与订阅
    发布与订阅即所谓的配置管理,顾名思义就是将数据发布到zk节点上,供订阅者动态获取数据,实现配置信息的集中式管理和动态更新。例如全局的配置信息,地址列表等就非常适合使用。
   1>. 索引信息和集群中机器节点状态存放在zk的一些指定节点,供各个客户端订阅使用。
 2>. 系统日志(经过处理后的)存储,这些日志通常2-3天后被清除。
 3>. 应用中用到的一些配置信息集中管理,在应用启动的时候主动来获取一次,并且在节点上注册一个Watcher,以后每次配置有更新,实时通知到应用,获取最新配置信息。
 4>. 业务逻辑中需要用到的一些全局变量,比如一些消息中间件的消息队列通常有个offset,这个offset存放在zk上,这样集群中每个发送者都能知道当前的发送进度。
 5>. 系统中有些信息需要动态获取,并且还会存在人工手动去修改这个信息。以前通常是暴露出接口,例如JMX接口,有了zk后,只要将这些信息存放到zk节点上即可。

2. 分布通知/协调
 Zookeeper 中特有watcher注册与异步通知机制,能够很好的实现分布式环境下不同系统之间的通知与协调,实现对数据变更的实时处理。使用方法通常是不同系统都对 ZK上同一个znode进行注册,监听znode的变化(包括znode本身内容及子节点的),其中一个系统update了znode,那么另一个系统能 够收到通知,并作出相应处理。
 1>. 另一种心跳检测机制:检测系统和被检测系统之间并不直接关联起来,而是通过zk上某个节点关联,大大减少系统耦合。
 2>. 另一种系统调度模式:某系统有控制台和推送系统两部分组成,控制台的职责是控制推送系统进行相应的推送工作。管理人员在控制台作的一些操作,实际上是修改 了ZK上某些节点的状态,而zk就把这些变化通知给他们注册Watcher的客户端,即推送系统,于是,作出相应的推送任务。
 3>. 另一种工作汇报模式:一些类似于任务分发系统,子任务启动后,到zk来注册一个临时节点,并且定时将自己的进度进行汇报(将进度写回这个临时节点),这样任务管理者就能够实时知道任务进度。
 总之,使用zookeeper来进行分布式通知和协调能够大大降低系统之间的耦合。

3. 分布式锁
 分布式锁:这个主要得益于ZooKeeper为我们保证了数据的强一致性,即用户只要完全相信每时每刻,zk集群中任意节点(一个zk server)上的相同znode的数据是一定是相同的。锁服务可以分为两类,一个是保持独占,另一个是控制时序。
 保持独占:就是所有试图来获取这个锁的客户端,最终只有一个可以成功获得这把锁。通常的做法是把zk上的一个znode看作是一把锁,通过create znode的方式来实现。所有客户端都去创建 /distribute_lock 节点,最终成功创建的那个客户端也即拥有了这把锁。
 控制时序:就是所有视图来获取这个锁的客户端,最终都是会被安排执行,只是有个全局时序了。做法和上面基本类似,只是这里 /distribute_lock 已经预先存在,客户端在它下面创建临时有序节点(这个可以通过节点的属性控制:CreateMode.EPHEMERAL_SEQUENTIAL来指定)。Zk的父节点(/distribute_lock)维持一份sequence,保证子节点创建的时序性,从而也形成了每个客户端的全局时序。


4. 集群管理
 1>. 集群机器监控:这通常用于那种对集群中机器状态,机器在线率有较高要求的场景,能够快速对集群中机器变化作出响应。这样的场景中,往往有一个监控系统,实时检测集群机器是否存活。过去的做法通常是:监控系统通过某种手段(比如ping)定时检测每个机器,或者每个机器自己定时向监控系统汇报“我还活着”。 这种做法可行,但是存在两个比较明显的问题:1. 集群中机器有变动的时候,牵连修改的东西比较多。2. 有一定的延时。
 利用ZooKeeper有两个特性,就可以实时另一种集群机器存活性监控系统:a. 客户端在节点 x 上注册一个Watcher,那么如果 x 的子节点变化了,会通知该客户端。b. 创建EPHEMERAL类型的节点,一旦客户端和服务器的会话结束或过期,那么该节点就会消失。

 2>. Master选举则是zookeeper中最为经典的使用场景了。
在分布式环境中,相同的业务应用分布在不同的机器上,有些业务逻辑(例如一些耗时的计算,网络I/O处理),往往只需要让整个集群中的某一台机器进行执行, 其余机器可以共享这个结果,这样可以大大减少重复劳动,提高性能,于是这个master选举便是这种场景下的碰到的主要问题。
 利用ZooKeeper的强一致性,能够保证在分布式高并发情况下节点创建的全局唯一性,即:同时有多个客户端请求创建 /currentMaster 节点,最终一定只有一个客户端请求能够创建成功。

相关文章:

中间件 - 分布式协调服务Zookeeper

目录 一. 前言 二. 树状结构 2.1. ZNode 2.1.1. stat 2.1.2. ACL 三. NameService命名服务 四. Configuration 配置管理 五. GroupMembers 集群管理 六. 集群三个角色及状态 七. 选举算法 八. Watcher 九. 设计目的 十. 典型使用场景 一. 前言 Zookeeper是一个分布…...

golang的实用工具

golang的实用工具 Go 语言提供了许多实用的工具,以下是其中一些常用的工具: 1. go run:用于直接运行 Go 源代码文件,无需显式编译。 2. go build:用于将 Go 代码编译成可执行文件或库。 3. go test:用于…...

图层混合模式(三)

差值模式 差值模式:查看每个通道的数值,用基色减去混合色或用混合色减去基色。具体取决于混合色与基色那个通道的数值更大。白色与任何颜色混合得到反相色,黑色与任何颜色混合颜色不变。 计算公式:结果色 绝对值(混合…...

蓝牙核心规范(V5.4)10.6-BLE 入门笔记之L2CAP

蓝牙篇之蓝牙核心规范(V5.4)深入详解汇总 1.概述 L2CAP负责协议复用、流量控制、服务数据单元(SDU)的分段和重组。它使用通道的概念来分隔在堆栈层之间传递的数据包序列。固定通道不需要设置,立即可用,并与特定的上层协议相关联。通道也可以通过指定的协议服务多路复用器…...

【计算机网络】DNS原理介绍

文章目录 DNS提供的服务DNS的工作机理DNS查询过程DNS缓存 DNS记录和报文DNS记录DNS报文针对DNS服务的攻击 DNS提供的服务 DNS,即域名系统(Domain Name System) 提供的服务 一种实现从主机名到IP地址转换的目录服务,为Internet上的用户应用程序以及其他…...

Docker的基础命令

目录 一、镜像操作 1、搜索镜像 2、下载镜像 3、查看镜像 3.1 查看下载到本地的所有镜像 3.2 查看单个镜像的详细信息 4、为镜像添加新的标签 5、镜像导出和导入到本地 5.1 镜像导出到本地 5.2 导入镜像 6、删除镜像 7、批量删除镜像 8、上传镜像 8.1 官网注册登录…...

提取项目依赖包的licenses

skywalking-eyes工具可以快速提取出licenses...

Vue项目自动转换px为rem-高保真还原设计图

前端开发中还原设计图的重要性毋庸置疑,目前来说应用最多的应该也还是使用rem。然而很多人依然还是处于刀耕火种的时代,要么自己去计算rem值,要么依靠编辑器安装插件转换。 而本文的目标就是通过一系列的配置后,在开发中可以直接使…...

rman备份到远程服务器

rman备份到远程服务器磁盘 原因 业务数据量较大,数据库服务器上无足够地空间存放rman备份,磁盘扩容申请不批。无奈采取nfs远程备份 环境信息 ip操作系统备份目录远程备份服务器192.168.3.130Centos7.9rmanbak数据库服务器192.168.3.132:1521Centos7.…...

数据结构与算法

目录 数据结构与算法 为什么要学习数据结构和算法? 常见的数据结构 常用算法 插入排序 一、概念及其介绍 二、适用说明 三、过程图示 希尔排序 一、概念及其介绍 二、适用说明 三、过程图示 归并排序 一、概念及其介绍 二、适用说明 三、过程图示 …...

【Web3】DAO相关的基础知识

这里写目录标题 DAO 的基础概念为什么需要 DAO?DAO 的种类 DAO 的运作方式知名 DAO 的介绍Bankless DAOSeeDAO DAO 的生态全景图分类治理框架DAO 的工具 DAO 众筹平台介绍 - JuiceBoxDAO 投票治理介绍 - SnapshotDAO 贡献 & 激励 - POAPDAO 信息管理 - NotionDA…...

一文教你学会ArcGIS Pro地图设计与制图系列全流程(3)

ArcGIS Pro做的成果图及系列文章目录: 系列文章全集: 《一文教你学会ArcGIS Pro地图设计与制图系列全流程(1)》《一文教你学会ArcGIS Pro地图设计与制图系列全流程(2)》《一文教你学会ArcGIS Pro地图设计与…...

用于大规模 MIMO 检测的近似消息传递 (AMP)(Matlab代码实现)

💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…...

复杂SQL解析

文章目录 背景表SQL关键字分析具体Sql注意点补充:select的字段,也可以带有计算逻辑 背景表 1、sale_log as result: 主表,大部分字段都是取自这个表 2、sale_num as sale:需要从这个表获取真实销量sale_num字段 3、schedule as…...

js中哪些地方会用到window?

前言 Window 对象是JavaScript中的顶层对象,它代表了浏览器中打开的窗口或者标签页。浏览器中打开的每一个窗口/标签页都会有一个对应的 Window 对象。在浏览器中,全局作用域的 this 就是指向 Window 对象。 正文 在 JavaScript 中,window 对…...

KITTI raw_data数据集百度云下载

1. 百度云链接 链接:https://pan.baidu.com/s/1YNzfDoJomKOZhlVUr2eEOA?pwdtfh3 提取码:tfh3 –来自百度网盘超级会员V6的分享 2. 资料来源 https://www.cvlibs.net/datasets/kitti/raw_data.php 命令行执行./raw_data_downloader.sh #!/bin/bashfiles(2011_…...

(3) OpenCV图像处理kNN近邻算法

目录 一、介绍 1、类通过Matplotlib显示 2、Matplotlib显示效果 二、通过KNN近邻对新成员进行分类例程...

手撸RPC【gw-rpc】

文章目录 基于 Netty 的简易版 RPC需求分析简易RPC框架的整体实现协议模块 📖自定义协议 🆕序列化方式 🔢 服务工厂 🏭服务调用方 ❓前置知识——动态代理🕳️Proxy类InvocationHandler 接口 RPC服务代理类内嵌Netty客…...

【Linux】:Kafka组件介绍

目录 环境简介 一、消息 二、主题 三、分区 四、副本 五、生产者 六、消费者 七、消费者组 八、offsets【偏移量】 环境简介 Linux内核:Centos7 Kafka版本:3.5.1 执行命令的目录位置:Kafka安装目录的bin目录下:/usr/loca…...

Redis〔篇〕

redis怎么做到双写一致性呢? 这个是要分情况的 业务要是对一致性要求不是很高的话可以使用延时双删,要强一致的话需要双写一致性。 Redis数据持久化? redis是有两种数据持久化方式的,一种RDB一种AOF rdb是redis数据快照&#x…...

龙芯2K1000核心板在智能座舱行业产品方案-迅为电子

迅为2K1000核心板是一款高性能的处理器,适用于智能座舱行业。它具备多核CPU、高级图像处理和丰富的接口选项,可用于开发先进的智能座舱解决方案,提高乘坐体验、安全性和便捷性。以下是2K1000处理器在智能座舱行业中的产品方案。 高清晰度显…...

2023/9/20 -- C++/QT

时钟: widget.h: #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QPainter> #include <QPaintEvent> #include <QDateTime> #include <QLabel> #include <QTimer> #include <QDebug>QT_BEGIN_NAMESPACE namespac…...

WordPress主题DUX v8.2源码下载

新增产品分类左侧多级分类折叠显示 新增网站默认字体对 MiSans 和 HarmonyOS Sans 的支持 新增顶部左上角显示登录注册的模块开关&#xff0c;且支持原生登录方式 新增手机端导航菜单的关闭按钮 新增文章内容中标题二的强化展示 新增全站禁止复制、右键和选择的操作 新增文章内…...

c++图像的边缘检测

图像的边缘检测 cv::Canny 是 OpenCV 中用于进行边缘检测的函数&#xff0c;特别是用于检测图像中的边缘。Canny 边缘检测是一种广泛使用的技术&#xff0c;它能够识别图像中的边缘&#xff0c;这些边缘通常表示对象之间的边界或图像中的显著特征 void cv::Canny(const cv::M…...

C++ Primer 类和对象(3)

类和结构体是比较相似&#xff0c;而传统的C的结构体中都是一些数据的类型&#xff0c;类除了有数据之外还有函数。所以可以把类想象成一个具有既有数据又有函数的复合数据类型。 类是一种将抽象转换为用户定义类型的C工具&#xff0c;它将数据表示和操纵数据的方法组合成一个整…...

IntelliJ IDEA 介绍、安装、配置优化与快捷键大全

一、简介 IDEA全称 IntelliJ IDEA&#xff0c;是Java编程语言的集成开发环境。IntelliJ在业界被公认为最好的Java开发工具&#xff0c;尤其在智能代码助手、代码自动提示、重构、JavaEE支持、各类版本工具(git、svn等)、JUnit、CVS整合、代码分析、 创新的GUI设计等方面的功能…...

css 语法笔记

.abc {margin-left:20px; } .xyz {margin-left:20px; } 等同于 .abc, .xyz {margin-left: 20px; } 参考 CSS - 选择器_css最后一个元素选择器_伏城之外的博客-CSDN博客 CSS Selectors Reference...

【初阶数据结构】二叉树全面知识总结

二叉树详解 树的概念及其结构树的概念树的相关概念树的表示方法孩纸兄弟表示法双亲表示法&#xff08;并查集&#xff09; 树的实际应用 二叉树二叉树的概念二叉树的种类二叉树的性质二叉树的存储结构 二叉树顺序结构的实现堆的概念及结构堆向上、向下调整法堆的插入堆的删除堆…...

CMD命令终端快捷键学习

很多环境需要安装并且指定环境变量才可用终端访问 比如一些数据库、一些环境、例如&#xff1a;nodejs Oracle、mysql 在一个文件夹按住shift鼠标右键可以快速在当前目录运行终端&#xff01;免去cd 目录的烦恼 快捷键 当你学习和使用命令终端&#xff08;如 Windows 的 CMD&…...

Leetcode198. 打家劫舍

https://leetcode.cn/problems/house-robber/description/ 你是一个专业的小偷&#xff0c;计划偷窃沿街的房屋。每间房内都藏有一定的现金&#xff0c;影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统&#xff0c;如果两间相邻的房屋在同一晚上被小偷闯入&…...