Java经典框架之Zookeeper

Zookeeper

Java 是第一大编程语言和开发平台。它有助于企业降低成本、缩短开发周期、推动创新以及改善应用服务。如今全球有数百万开发人员运行着超过 51 亿个 Java 虚拟机,Java 仍是企业和开发人员的首选开发平台。
   

课程内容的介绍

1. Zookeeper的介绍和安装
2. Zookeeper客户端使用
3. ZookeeperJavaAPI使用
  

一、Zookeeper的介绍和安装

1. 为什么要使用Zookeeper
我们为了学习Dubbo,而在dubbo中需要一个注册中心,而Zookeeper是我们在使用Dubbo是官方推荐的注册中心,所以我们先来介绍Zookeeper。

     

  
2. Zookeeper介绍

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

    
2.2 Zookeeper的集群机制
Zookeeper是为其他分布式程序提供服务的,所以本身自己不能随便就挂了,所以zookeeper自身的集群机制就很重要。zookeeper的集群机制采用的是半数存活机制,也就是整个集群节点中有半数以上的节点存活,那么整个集群环境可用。这也就是说们的集群节点最好是奇数个节点。
  
Zookeeper集群节点的角色
Leader
Leader服务器是Zookeeper集群工作的核心,其主要工作如下
1. 事务请求的唯一调度和处理者,保证集群事务处理的顺序性。
2. 集群内部各服务器的调度者。
  
Follower
Follower是Zookeeper集群的跟随者,其主要工作如下
1. 处理客户端非事务性请求(读取数据),转发事务请求给Leader服务器。
2. 参与事务请求Proposal的投票。
3. 参与Leader选举投票。
  
Observer
Observer充当观察者角色,观察Zookeeper集群的最新状态变化并将这些状态同步过来,其对于非事务请求可以进行独立处理,对于事务请求,则会转发给Leader服务器进行处理。Observer不会参与任何形式的投票,包括事务请求Proposal的投票和Leader选举投票。
  
3. 集群环境准备
通过上面的介绍我们了解到zookeeper的集群环境应该配置奇数个节点,所以我们在本文中搭建的zookeeper环境准备在3个节点上搭建。接下来我们介绍下需要准备的环境。
  
3.1 准备3个节点
准备3个centos7.0的虚拟机节点,并且安装配置好JDK版本最好是8.不清楚的可参考此地址Linux之jdk安装,并配置好相关的网络配置。

  
通过VMware的克隆或者直接复制文件夹的方式来创建另外两个新的节点。
  
3.2 网络配置
修改ifcfg-ens33配置文件。

  
重启网络服务
service network restart
  
ping测试

  
三个节点的网络配置都ok的化我们就可以通过XShell来连接了。
  
3.3 节点的映射关系
每个节点设置相应的ip和主机名的映射关系,方便集群环境的部署。
修改hosts配置文件中的信息。

    
3.4 配置免密登录
生成公钥和私钥
ssh-keygen
  
输入命令后根据提示,四次回车即可。

  
发送公钥给需要免密登录的节点。
ssh-copy-id bobo01
ssh-copy-id bobo02
ssh-copy-id bobo03
  

  
节点和节点发送文件通过scp命令实现。
scp -r b.txt bobo01:/root/
  

  
3.5 关闭防火墙
查看防火墙状态
firewall-cmd --state
  
停止防火墙
systemctl stop firewall.service
  
禁止开机启动
systemctl disable firewall.service
  
4. Zookeeper集群环境搭建
4.1 获取安装文件
下载地址:https://mirrors.bfsu.edu.cn/apache/zookeeper/
通过wget命令将安装文件下载到opt目录下
注意:
apache-zookeeper-3.5.9-bin.tar.gz和apache-zookeeper-3.5.9.tar.gz的区别 -bin是编译后的文件 我们用这个。
wget https://mirrors.bfsu.edu.cn/apache/zookeeper/zookeeper-3.5.9/apache-zookeeper-3.5.9-bin.tar.gz
  

  
解压缩文件。

  
进入Zookeeper目录

   
4.2 修改配置
修改zoo.cfg文件,系统默认的名称是 zoo_smple.cfg我们需要重命名为zoo.cfg。

  
修改cfg的内容
修改了两块:
1是Zookeeper中存储数据的文件夹,还有就是Zookeeper集群环境节点信息。

  
配置myid文件
我们需要在Zookeeper的数据存储的目录中创建一个myid文件,文件中的内容只有一行信息,即表示我们集群几点的标识,范围是1-255,每个节点的myid的数字和我们在zoo.cfg中配置的server.数字是对应的。
1
   
4.3 分发文件
当我们配置好了一个Zookeeper节点后,我们就可以将Zookeeper文件夹分发给其他几个节点了。
scp -r zookeeper bobo02:`pwd`
scp -r zookeeper bobo03:`pwd`
  
分发成功后我们需要修改各个节点中的myid的信息为配置文件中对应的数字。
  
4.4 启动测试
整个集群环境都配置好了之后我们就可以测试启动了。
启动命令
./bin/zkServer.sh start
  
当我们仅仅启动一个节点的时候,因为半数存活机制,3个节点只启动一个节点是没有效果的。

  
当我们启动第二个节点后发现集群环境可以使用了。

  
然后第一个节点的状态也改变了。

  
然后再把第三个节点也启动起来。

  
5. Zookeeper的选举机制
为什么要进行Leader选举?
Leader 主要作用是保证分布式数据一致性,即每个节点的存储的数据同步。遇到以下两种情况需要进行。
Leader选举
服务器初始化启动。
服务器运行期间无法和Leader保持连接,Leader节点崩溃,逻辑时钟崩溃。
  
5.1 服务器初始化时Leader选举
Zookeeper由于其自身的性质,一般建议选取奇数个节点进行搭建分布式服务器集群。以3个节点组成的服务器集群为例,说明服务器初始化时的选举过程。启动第一台安装Zookeeper的节点时,无法单独进行选举,启动第二台时,两节点之间进行通信,开始选举Leader。
1. 每个Server投出一票。他们两都选自己为Leader,投票的内容为(SID,ZXID)。SID即Server的id,安装zookeeper时配置文件中所配置的myid;ZXID,事务id,为节点的更新程度,ZXID越大,代表Server对Znode的操作越新。由于服务器初始化,每个Sever上的Znode为0,所以Server1投的票为(1,0),Server2为(2,0)。两Server将各自投票发给集群中其他机器。
2. 每个Server接收来自其他Server的投票。集群中的每个Server先判断投票有效性,如检查是不是本轮的投票,是不是来Looking状态的服务器投的票。
3. 对投票结果进行处理。先了解下处理规则
首先对比ZXID。ZXID大的服务器优先作为Leader ,若ZXID相同,比如初始化的时候,每个Server的ZXID都为0,就会比较myid,myid大的选出来做Leader。
对于Server而言,他接受到的投票为(2,0),因为自身的票为(1,0),所以此时它会选举 Server2为Leader,将自己的更新为(2,0)。而Server2收到的投票为Server1的(1,0)由于比他自己小,Server2的投票不变。Server1和Server2再次将票投出,投出的票都为(2,0)。
4. 统计投票。每次投票之后,服务器都会统计投票信息,如果判定某个Server有过半的票数投它,那么该Server将会作为Leader。对于Server1和Server2而言,统计出已经有两台机器接收了(2,0)的投票信息,此时认为选出了Leader。
5. 改变服务器状态。当确定了Leader之后,每个Server更新自己的状态,Leader将状态更新为Leading,Follower将状态更新为Following。

    
5.2 服务器运行期间的Leader选举
Zookeeper运行期间,如果有新的Server加入,或者非Leader的Server宕机,那么Leader将会同步数据到新Server或者寻找其他备用Server替代宕机的Server。若Leader宕机,此时集群暂停对外服务,开始在内部选举新的Leader。假设当前集群中有Server1、Server2、Server3三台服务器,Server2为当前集群的Leader,由于意外情况,Server2宕机了,便开始进入选举状态。过程如下。
1. 变更状态。其他的非Observer服务器将自己的状态改变为Looking,开始进入Leader选举。
2. 每个Server发出一个投票(myid,ZXID),由于此集群已经运行过,所以每个Server上的ZXID可能不同。
假设Server1的ZXID为145,Server3的为122,第一轮投票中,Server1和Server3都投自己,票分别为(1,145)、(3,122),将自己的票发送给集群中所有机器。
3. 每个Server接收接收来自其他Server的投票,接下来的步骤与初始化时相同。
  

二、Zookeeper客户端使用

1. 配置Zookeeper的环境变量
为了简化我们每次操作Zookeeper而不用进入到Zookeeper的安装目录,我们可以将Zookeeper的安装信息配置到系统的环境变量中。
vim /etc/profile
  
添加的内容
export ZOOKEPPER_HOME=/opt/zookeeper
export PATH=$PATH:$ZOOKEEPER_HOME/bin
  
执行source命令
source /etc/profile
  
我们就可以在节点的任意位置操作Zookeeper了。
通过scp命令将profile文件发送到其他几个节点上。
scp /etc/profile bobo02:/etc/
  
2.客户端连接
通过bin目录下的zkCli.sh 命令连接即可。
zkCli.sh
  

   
zkCli.sh默认连接的是当前节点的Zookeeper节点,如果我们要连接其他节点执行如下命令即可。
zkCli.sh -timeout 5000 -server bobo02:2181
  

  
3.数据操作
3.1 Zookeeper的数据结构
1. 层次化的目录结构,命名符合常规文件系统规范。
2. 每个节点在Zookeeper中叫做znode,并且有一个唯一的路径标识。
3. 节点znode可以包含数据和子节点(但是EPHEMERAL类型的节点不能有子节点)。
4. 客户端应用可以在节点上设置监听器。

    
3.2 节点类型
1).znode有两种类型:
短暂性(ephemeral)(断开连接自己删除)
持久性(persistent)(断开连接不删除)
  
2).znode有四种形式的目录节点(默认是persistent)如下

  
创建znode时设置顺序标识,znode名称后会附加一个值,顺序号是一个单调递增的计数器,有父节点维护。
在分布式系统中,顺序号可以被用于为所有的事件进行全局排序,这样客户端可以通过顺序号推断事件的顺序。
  
3.3 常用命令
Zookeeper作为Dubbo的注册中心用来保存我们各个服务的节点信息,显示Zookeeper是可以实现输出的存储操作的,我们来看下Zookeeper中存储操作的基本命令。

  
ls
ls用来查看某个节点下的子节点信息。

  
增强的命令,查看节点下的子节点及当前节点的属性信息 ls2或者 ls -s 命令。

  
create
创建节点信息

  
get
get命令用来查看节点的数据。

  
如果要查看节点的属性信息那么我们可以通过get -s 来实现。

  
delete
delete只能删除没有子节点的节点要删除非空节点可以通过 rmr 或者 deleteall 命令实现。

  
set
set命令可以用来修改节点的内容。

  
3.4 事件监听
3.4.1 数据改变的监听
监听某个节点的数据内容变化,通过get命令 带 -w 参数即可,在3.4版本的Zookeeper中是通过 get path watch 来说实现监控的。

  
然后我们在其他节点上修改app1节点的数据,会触监听事件。

  

  
注意监听一次节点只会触发一次,如果要实现多次监听,那么可以在触发事件的处理函数中再次追加对节点的监听操作。
  
3.4.2 子节点的改变
监听节点下面的子节点的改变。
[zk: localhost:2181(CONNECTED) 14] ls -w /app1
[]
  
触发

  

  

三、Zookeeper Java API使用

介绍如何通过Java代码来操作Zookeeper中的数据。
在Zookeeper的安装目录下是提供的有相关的Jar依赖的。

  
但是我们对于Maven构建项目已经习惯而且是主流,那么我们可以通过maven坐标来管理。
    <dependencies>
        <dependency>
            <groupId>org.apache.zookeeper</groupId>
            <artifactId>zookeeper</artifactId>
            <version>3.5.9</version>
        </dependency>
        <dependency>
            <groupId>com.github.sgroschupf</groupId>
            <artifactId>zkclient</artifactId>
            <version>0.1</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>

    </dependencies>
  
1. API的使用
1.1 连接ZK服务
package com.bobo.test;

import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooKeeper;
import org.junit.Test;

import java.io.IOException;

public class Test1 {

    private String connectString = "192.168.100.121:2181,192.168.122:2181,192.168.100.122:2181";

    private int sessionTimeOut = 5000;

    /**
     * 连接Zookeeper服务端
     */
    @Test
    public void test1() throws IOException {
        zooKeeper = new ZooKeeper(connectString, sessionTimeOut, new Watcher() {
            /**
             * 触发监听事件的回调方法
             * @param watchedEvent
             */
            @Override
            public void process(WatchedEvent watchedEvent) {
                System.out.println("触发了.....");
            }
        });
        //System.out.println("--->" + zooKeeper);
    }

}
  

  
1.2 基本操作
package com.bobo.test;

import jdk.nashorn.internal.ir.CallNode;
import org.apache.zookeeper.*;
import org.apache.zookeeper.data.Stat;
import org.junit.Before;
import org.junit.Test;

import java.io.IOException;
import java.util.List;

public class Test1 {

    private String connectString = "192.168.100.121:2181,192.168.122:2181,192.168.100.122:2181";

    private int sessionTimeOut = 10000;

    ZooKeeper zooKeeper = null;

    /**
     * 连接Zookeeper服务端
     */
    @Before
    public void test1() throws IOException {
        zooKeeper = new ZooKeeper(connectString, sessionTimeOut, new Watcher() {
            /**
             * 触发监听事件的回调方法
             * @param watchedEvent
             */
            @Override
            public void process(WatchedEvent watchedEvent) {
                System.out.println("触发了.....");
            }
        });
        //System.out.println("--->" + zooKeeper);
    }

    /**
     * 创建节点
     */
    @Test
    public void createNode() throws Exception{
        String path = zooKeeper.create("/apptest" // 节点路径
                ,"HelloZookeeper".getBytes() // 节点的数据
                , ZooDefs.Ids.OPEN_ACL_UNSAFE // 权限
        , CreateMode.PERSISTENT // 节点类型
        );
        System.out.println(path);
    }

    /**
     * 判断节点是否存在
     */
    @Test
    public void exist() throws  Exception{
        // true表示的是使用Zookeeper中的watch
        Stat stat = zooKeeper.exists("/apptest", true);
        if(stat != null){
            System.out.println("节点存在"+ stat.getNumChildren());
        }else{
            System.out.println("节点不存在 ....");
        }
    }

    /**
     * 获取某个节点下面的所有的子节点
     */
    @Test
    public void getChildrens() throws Exception{
        List<String> childrens = zooKeeper.getChildren("/app1", true);
        for (String children : childrens) {
            // System.out.println(children);
            // 获取子节点中的数据
            byte[] data = zooKeeper.getData("/app1/" + children, false, null);
            System.out.println(children+":" + new String(data));
        }
    }

    /**
     * 修改节点的内容
     */
    @Test
    public void setData() throws Exception{
        // -1 不指定版本 自动维护
        Stat stat = zooKeeper.setData("/app1/a1", "666666".getBytes(), -1);
        System.out.println(stat);
    }


    /**
     * 删除节点
     */
    @Test
    public void deleteNode() throws Exception{
        zooKeeper.delete("/app1",-1);

    }

}
  
1.3 事件监听处理
Java程序如何监听Zookeeper中的数据的变化?
    /**
     * 监听Node节点下的子节点的变化
     */
    @Test
    public void nodeChildrenChange() throws Exception{
        List<String> list = zooKeeper.getChildren("/app1", new Watcher() {

            /**
             *              None(-1),
             *             NodeCreated(1),
             *             NodeDeleted(2),
             *             NodeDataChanged(3),
             *             NodeChildrenChanged(4),
             *             DataWatchRemoved(5),
             *             ChildWatchRemoved(6);
             * @param watchedEvent
             */
            @Override
            public void process(WatchedEvent watchedEvent) {
                System.out.println("--->"+ watchedEvent.getType());
            }
        });
        for (String s : list) {
            System.out.println(s);
        }

        Thread.sleep(Integer.MAX_VALUE);
    }

    /**
     * 监听节点内容变更
     */
    @Test
    public void nodeDataChanged() throws Exception{
        byte[] data = zooKeeper.getData("/app1/a1", new Watcher() {
            @Override
            public void process(WatchedEvent watchedEvent) {
                System.out.println("--->" + watchedEvent.getType());
            }
        }, null);
        System.out.println("--->" + new String(data));
        Thread.sleep(Integer.MAX_VALUE);
    }

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

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

相关文章

web学习笔记(九)

目录 1.初识JS(JavaScript) 1.1什么是JavaScript&#xff1f; 1.2HTML5 CSS3 javaScript三者的关系 1.3 JAVAScript的作用 1.4JAVAScript的组成部分 1.5JS注释 1.6补充知识 2.JS的引入方法 2.1行内式 2.2嵌入式&#xff08;内嵌式&#xff09; 2.3外链式 3.输入和…

深入理解Word Embeddings:Word2Vec技术与应用

目录 前言1 Word2Vec概述2 CBOW模型2.1 CBOW模型简介2.2 基于词袋&#xff08;bag of word&#xff09;的假设2.3 One-hot向量编码2.4 分类问题 3 Skip-gram模型3.1 Skip-gram模型简介3.2 目标词预测上下文3.3 词语关联性的捕捉 4 优化Word2Vec模型的方法4.1 负采样和分层softm…

转转服务瘦身实战

文章目录 1 背景2 第一步-发现并下掉僵尸服务2.1 如何发现僵尸服务2.2 如何下掉僵尸服务 3 第二步-发现并下掉僵尸方法3.1 如何发现僵尸方法3.1.1 全量方法的获取3.1.2 活动方法的获取3.1.3 ServiceAbility Agent方案详解3.1.3.1 ServiceAbility Agent使用方法3.1.3.2 解决stop…

分布式系统架构设计之分布式缓存技术选型

一、概述 随着互联网业务的快速发展&#xff0c;分布式系统已经成为了解决大规模并发请求、高可用性、可扩展性等问题的重要手段。在分布式系统中&#xff0c;缓存作为提高系统性能的关键技术&#xff0c;能够显著降低数据库负载、减少网络延迟、提高数据访问速度。当面对大量…

XD6500S一款串口SiP模块 射频LoRa芯片 内置sx1262

1.1产品介绍 XD6500S是一款集射频前端和LoRa射频于一体的LoRa SIP模块系列收发器SX1262 senies&#xff0c;支持LoRa⑧和FSK调制。LoRa技术是一种扩频协议优化低数据速率&#xff0c;超长距离和超低功耗用于LPWAN应用的通信。 XD6500S设计具有4.2 mA的有效接收电流消耗&#…

Python基础知识总结2——python中的字符串

python字符串 字符串基本特点空字符串和len()函数转义字符字符串拼接字符串复制不换行打印从控制台读取字符串replace() 实现字符串替换str()实现数字转型字符串使用[]提取字符字符串切片slice操作split()分割和join()合并字符串驻留机制和字符串比较字符串比较和同一性成员操作…

Python如何实现微信支付功能代码示例

微信支付是一种基于互联网的移动支付服务&#xff0c;由中国的即时通讯工具微信提供。用户可以通过微信支付在微信平台上进行在线支付、转账和收款。微信支付支持多种支付方式&#xff0c;包括银行卡支付、微信钱包余额支付、扫码支付等。用户可以用微信支付购买商品、支付账单…

C语言编译器(C语言编程软件)完全攻略(第二十一部分:Code::Blocks汉化教程(附带汉化包))

介绍常用C语言编译器的安装、配置和使用。 二十一、Code::Blocks汉化教程&#xff08;附带汉化包&#xff09; 由于官方下载的 CodeBlocks 全部都是英文版&#xff0c;本教程中给大家推荐的 CodeBlocks 17.12 版本也是官方英文版&#xff0c;所以本节给大家介绍&#xff1a;如…

C# .Net学习笔记—— 异步和多线程(await/async)

一、介绍 1、控制台测试await/async 2、C# 5.0 .Net framework4.5 CLR4.0 以后才有&#xff0c;本身是一种语法糖 二、基本测试 1、不加await测试。 private async static Task TestAsync() {Log.Info($"当前主线程id{Thread.CurrentThread.ManagedThreadId}"…

【六大排序详解】终篇 :冒泡排序 与 快速排序

终篇 :冒泡排序 与 快速排序 1 冒泡排序1.1 冒泡排序原理1.2 排序步骤1.3 代码实现 2 快速排序2.1 快速排序原理2.1.1 Hoare版本代码实现 2.1.2 hole版本代码实现 2.1.3 前后指针法代码实现 2.1.4 注意取中位数局部优化 2.1.5 非递归版本非递归原理代码实现 2.2 特性总结 谢谢阅…

负责任的人工智能与人机环境系统智能

负责任的人工智能是指在人工智能系统的设计、开发、管理、使用和维护过程中&#xff0c;所有相关的角色&#xff08;包括设计者、开发者、管理者、使用者、维护者等等&#xff09;都承担其行为的道义、法律和社会责任。这意味着这些角色需要确保人工智能系统的设计与使用符合伦…

网络安全B模块(笔记详解)- Web渗透测试

Web信息收集 1.通过Kali对服务器场景Linux进行Web扫描渗透测试(使用工具nikto,查看该命令的完整帮助文件),并将该操作使用命令中固定不变的字符串作为Flag提交; Flag:nikto -H 2.通过Kali对服务器场景Linux进行Web扫描渗透测试(使用工具nikto,扫描目标服务器8080端口,…

阻止持久性攻击改善网络安全

MITRE ATT&CK框架是一个全球可访问的精选知识数据库&#xff0c;其中包含基于真实世界观察的已知网络攻击技术和策略。持久性是攻击者用来访问系统的众多网络攻击技术之一;在获得初始访问权限后&#xff0c;他们继续在很长一段时间内保持立足点&#xff0c;以窃取数据、修改…

文章解读与仿真程序复现思路——电网技术EI\CSCD\北大核心《考虑多元不确定性和备用需求的微电网双层鲁棒容量规划》

本专栏栏目提供文章与程序复现思路&#xff0c;具体已有的论文与论文源程序可翻阅本博主免费的专栏栏目《论文与完整程序》 这个标题涉及微电网&#xff08;Microgrid&#xff09;的双层鲁棒容量规划&#xff0c;考虑了多元不确定性和备用需求。让我们逐步解读这个标题&#xf…

【软考中级-软件设计师】day1:CPU、数据的表示、校验码

考点分布目录 中央处理单元CPU 练习题 数据的表示 二进制转十进制 练习题 十进制转二进制 练习题 原码 练习题 反码 练习题 补码 练习题 练习题 移码 浮点数 练习题 奇偶校验 练习题 校验码 模2除法 循环冗余校验CRC 练习题 练习题 练习题 奇偶校验码 只…

docker kingbase

docker kingbase run 命令 docker run -tid \ -e ENABLE_CIyes \ -e NEED_STARTyes \ -e DB_MODEoracle \ -e DB_USERkingbase \ -e DB_PASSWORD123456 \ --privileged \ -p 4321:54321 \ -v /home/admin/SoftWare/volume/kingbase/userdata/data:/home/kingbase/userdata/da…

基于seatunnel实现mysql同步clickhouse验证

场景&#xff1a; 需求想要实现mysql同步到clickhouse&#xff0c;seatunnel部署见前面文档linux环境seatunnel安装运行-CSDN博客。 官方说明文档 Clickhouse | Apache SeaTunnel mysql同步配置 server-id1 log_bin/var/lib/mysql/bin.log binlog_formatROW #binlog-do-db 具…

astadmin安装querylist插件Puppeteer

我本来是想在linux服务器上安装&#xff0c;折腾了一天也没安装成功&#xff0c;由于急着用&#xff0c;就先做window10上安装了&#xff0c;以后有时间再研究centos7上安装 一 首先需要安装fastadmin 框架和querylist插件 这个大家可以自行安装&#xff0c;querylist安装地址…

B059-权限管理系统01

目录 知识点介绍项目演示项目搭建动态菜单查询分析(权限表分析)权限系统表分析角色模块pageInfopageHelper实现前端动态分页高级查询新增与修改删除角色 分配权限-表分析角色授权数据-一级和二级权限查询 知识点介绍 项目演示 准备数据库 准备工程auth_new tips&#xff1a;…

三极管组成的光控开关电路原理图

什么是光控开关 光控开关/光控时控器采用先进的嵌入式微型计算机控制技术&#xff0c;融光控功能和普通时控器两大功能为一体的多功能高级时控器&#xff08;时控开关&#xff09;&#xff0c;根据节能需要可以将光控探头&#xff08;功能&#xff09;与时控功能同时启用&…