kafka使用_Kafka介绍与使用

最近在研究kafka,觉得需要输出点东西才能更好的吸收,遂总结与大家分享,话不多说。

一、先上思维导图:

759a086adc31a16a29e02f260bdd6d38.png

二、再上kafka整体架构图:

ab91be71661c23c893c60256d7f30900.png

2.1、Producer:消息生产者,就是向kafka broker发消息的客户端。

2.2、Consumer :消息消费者,向kafka broker取消息的客户端

2.3、Topic :每条发布到kafka集群的消息都有一个类别,这个类别被称为主题Topic。(物理上不同Topic的消息分开存储,逻辑上一个Topic的消息虽然保存于一个或多个broker上但用户只需指定消息的Topic即可生产或消费数据而不必关心数据存于何处)。

2.4、Consumer Group (CG):这是kafka用来实现一个topic消息的广播(发给所有的consumer)和单播(发给任意一个consumer)的手段。一个topic可以有多个CG。topic的消息会复制(不是真的复制,是概念上的)到所有的CG,但每个partition只会把消息发给该CG中的一个consumer。如果需要实现广播,只要每个consumer有一个独立的CG就可以了。要实现单播只要所有的consumer在同一个CG。用CG还可以将consumer进行自由的分组而不需要多次发送消息到不同的topic。

2.5、Broker :一台kafka服务器就是一个broker。一个集群由多个broker组成。一个broker可以容纳多个topic。

2.6、Partition:为了实现扩展性,一个非常大的topic可以分布到多个broker(即服务器)上,一个topic可以分为多个partition,每个partition是一个有序的队列。partition中的每条消息都会被分配一个有序的id(offset)。kafka只保证按一个partition中的顺序将消息发给consumer,不保证一个topic的整体(多个partition间)的顺序。

2.7、Offset:kafka的存储文件都是按照offset.kafka来命名,用offset做名字的好处是方便查找。例如你想找位于2049的位置,只要找到2048.kafka的文件即可。当然the first offset就是00000000000.kafka。

三、部分小点请看导图

四、Kafka集群部署 (提前备好ZK集群环境)

4.1、下载安装包

http://kafka.apache.org/downloads

或者在linux中使用wget命令下载安装包

wget http://mirrors.hust.edu.cn/apache/kafka/2.5.0/kafka_2.13-2.5.0.tgz

4.2、解压安装包

tar -zxvf /root/mysoftpackage/kafka_2.13-2.5.0.tgz -C /root/apps/

4.3、创建软链接

如后续配置环境变量后,升级版本啥的不用再重新配置环境变量。

cd /root/apps/

ln -s kafka_2.13-2.5.0 kafka

4.4、修改配置文件

cp /root/apps/kafka/config/server.properties 

/root/apps/kafka/config/server.properties.bak

vi /root/apps/kafka/config/server.properties

修改以下配置:

# Broker的全局唯一编号,集群内不重复即可

broker.id=0

#kafka运行日志存放的路径

log.dirs=/root/kafkadata/logs

#kafka依赖的ZK集群

zookeeper.connect=hdp-node-01:2181,hdp-node-02:2181,hdp-node-03:2181

vi /root/apps/kafka/config/producer.properties

修改以下配置:

bootstrap.servers=hdp-node-01:9092,hdp-node-02:9092,hdp-node-03:9092

vi /root/apps/kafka/config/consumer.properties

修改以下配置:

bootstrap.servers=hdp-node-01:9092,hdp-node-02:9092,hdp-node-03:9092

4.5、分发安装包

scp -r /root/apps/kafka_2.13-2.5.0 hdp-node-02:/root/apps

scp -r /root/apps/kafka_2.13-2.5.0 hdp-node-03:/root/apps

然后分别在各机器上创建软连

cd /root/apps/

ln -s kafka_2.13-2.5.0 kafka

4.6、再次修改配置文件(重要)

依次修改各服务器上配置文件的的broker.id,分别是0,1,2不得重复。

4.7、环境变量配置

vi /etc/profile

export KAFKA_HOME=/root/apps/kafka

export PATH=$PATH:$KAFKA_HOME/bin

刷新下系统环境变量

source /etc/profile

4.8、守护进程启动集群

依次在各节点上启动kafka

kafka-server-start.sh -daemon /root/apps/kafka/config/server.properties

4.9、编写脚本批量启动集群kafka服务(kafkaBatchStart.sh)

#!/bin/bash

for i in 1 2 3

do

ssh hdp-node-0$i "source /etc/profile;/root/apps/kafka/bin/kafka-server-start.sh -daemon /root/apps/kafka/config/server.properties"

done

五、基本管理操作Shell命令

5.1、查看当前服务器中的所有topic

kafka-topics.sh --list --zookeeper hdp-node-01:2181

245ae3533c64772fc0520a5be0498af0.png

5.2、创建topic

replication-facto:副本数、partition:分区数

kafka-topics.sh --create --zookeeper hdp-node-01:2181 --replication-factor 3 --partitions 3 --topic goodsMq

5.3、删除topic

kafka-topics.sh --delete --zookeeper hdp-node-01:2181 --topic goodsMq

5.4、通过shell命令发送消息

kafka-console-producer.sh --broker-list hdp-node-01:9092 --topic goodsMq

kafka-console-producer.sh --bootstrap-server hdp-node-01:9092,hdp-node-02:9092 --topic goodsMq

7d474f276703dc42fb7de6bc7cab42a7.png

5.5、通过shell消费消息

--from-beginning:指定偏移量从头开始消费

kafka-console-consumer.sh --bootstrap-server hdp-node-01:9092,hdp-node-02:9092 --topic goodsMq --from-beginning

9bdaff2ab1dde1be18658fe7cff9db81.png

5.6、查看某个Topic的详情

kafka-topics.sh --topic goodsMq --describe --zookeeper hdp-node-01:2181,hdp-node-02:2181

4014409d432917ed7fabb2ab878dbcad.png

六、Java简单代码示例

6.1、引入pom依赖

<dependency><groupId>org.apache.kafkagroupId><artifactId>kafka-clientsartifactId><version>2.5.0version>dependency

6.2、消息生产者

public static void main(String[] args) {   //指定当前kafka producer生产的数据的目的地   String topicName = "orderMq";   // 读取配置文件   Properties props = new Properties();   //指定kafka服务器地址 如果是集群可以指定多个 但是就算只指定一个他也会去集群环境下寻找其他的节点地址   props.setProperty("bootstrap.servers","hdp-node-01:9092,hdp-node-02:9092,hdp-node-03:9092");   //key序列化器   props.setProperty("key.serializer", StringSerializer.class.getName());   //value序列化器   props.setProperty("value.serializer",StringSerializer.class.getName());   //通过配置文件,创建生产者   KafkaProducer<String, String> producer = new KafkaProducer<String, String>(props);   //生产数据   for (int messageNo = 1; messageNo < 100; messageNo++) {      //调用producer的send方法发送数据      ProducerRecord record = new ProducerRecord<String, String>(topicName, messageNo + "", "appid-" + UUID.randomUUID() + "-测试");      //发送记录      producer.send(record);   }   producer.close();   System.out.println("done!!!");}

6.3、消息消费者

public static void main(String[] args) throws Exception{    Properties properties = new Properties();    properties.setProperty("bootstrap.servers","hdp-node-01:9092,hdp-node-02:9092,hdp-node-03:9092");    properties.setProperty("key.deserializer", StringDeserializer.class.getName());    properties.setProperty("value.deserializer",StringDeserializer.class.getName());    properties.setProperty("group.id","test-consumer-group");    KafkaConsumer<String,String> consumer = new KafkaConsumer<String, String>(properties);    consumer.subscribe(Collections.singletonList("orderMq"));    while (true){        ConsumerRecords<String, String> poll = consumer.poll(Duration.ofMillis(500));        for (ConsumerRecord<String, String> record : poll) {            System.out.println(record.key() + "=" + record.value());        }    }}

七、思考

7.1、Kafka为什么效率高吞吐量大

1)、硬盘的索引功能,二分查找法。

分区:找到相应的leader分区负责读写操作;

分段:根据文件segment的命名可以确认要查找的offset或timestamp在哪个文件中;

稀疏索引:快速确定要找的offset在哪个内存地址的附近。

2)、通过Partition实现并行处理

3)、I/O优化:

3.1)、磁盘的顺序写入(600MB/S)

9daa26471284d828ac5233b12b6a0883.png

3.2)、充分利用操作系统文件读取缓存(PageCache)

       Kafka 的数据并不是实时的写入硬盘,它充分利用了现代操作系统分页存储来利用内存提高 I/O 效率。再通过mmap(Memory Mapped Files)内存映射文件零拷贝的方式,它的工作原理是直接利用操作系统的 Page 来实现文件到物理内存的直接映射,完成映射之后你对物理内存的操作会被同步到硬盘上(操作系统在适当的时候)。通过 mmap,进程像读写硬盘一样读写内存(当然是虚拟机内存),也不必关心内存的大小,有虚拟内存为我们兜底。

       使用这种方式可以获取很大的 I/O 提升,省去了用户空间到内核空间复制的开销。但也有一个很明显的缺陷——不可靠,写到 mmap 中的数据并没有被真正的写到硬盘,操作系统会在程序主动调用 Flush 的时候才把数据真正的写到硬盘。

       Kafka 提供了一个参数 producer.type 来控制是不是主动 Flush:

如果Kafka 写入到 mmap 之后就立即 Flush,然后再返回 Producer 叫同步 (Sync)。如果 Kafka 写入 mmap 之后立即返回 Producer 不调用 Flush 叫异步 (Async)。

3.3.)、基于 Sendfile 实现零拷贝(Zero Copy)方式读取磁盘数据

传统模式下,当需要对一个文件进行传输的时候,其具体流程细节如下:

e5343f6561f66a69681fa3ac2be8e076.png

a、调用 Read 函数,文件数据被 Copy 到内核缓冲区。

b、Read 函数返回,文件数据从内核缓冲区 Copy 到用户缓冲区

c、Write 函数调用,将文件数据从用户缓冲区 Copy 到内核与 Socket 相关的缓冲区。

d、数据从 Socket 缓冲区 Copy 到相关协议引擎。

以上细节是传统 Read/Write 方式进行网络文件传输的方式,我们可以看到,在这个过程当中,文件数据实际上是经过了四次 Copy 操作:

硬盘—>内核 buf—>用户 buf—>Socket 相关缓冲区—>协议引擎


Sendfile 的引入以减少数据复制,同时减少上下文切换

8cfc97e012995d154761dfad986c521f.png

3.4)、批量压缩减少网络IO损耗

      在很多情况下,系统的瓶颈不是 CPU 或磁盘,而是网络 IO,对于需要在广域网上的数据中心之间发送消息的数据流水线尤其如此。进行数据压缩会消耗少量的 CPU 资源,不过对于 Kafka 而言,网络 IO 更应该考虑:因为每个消息都压缩,但是压缩率相对很低,所以 Kafka 使用了批量压缩,即将多个消息一起压缩而不是单个消息压缩。

       Kafka 允许使用递归的消息集合,批量的消息可以通过压缩的形式传输并且在日志中也可以保持压缩格式,直到被消费者解压缩。

       kafka在压缩数据时使用的压缩算法,可选参数有:none、gzip、snappy。none即不压缩,gzip,和snappy压缩算法之间取舍的话gzip压缩率比较高,系统cpu占用比较大,但是带来的好处是,网络带宽占用少,snappy压缩比没有gzip高,cpu占用率不是很高,性能也还行,如果网络带宽比较紧张的话。可以选择gzip,一般推荐snappy。

7.2、数据生产时的分发策略是什么

Producer客户端负责消息的分发。

      kafka集群中的任何一个broker都可以向producer提供metadata信息,这些metadata中包含"集群中存活的servers列表、partitions、leader列表"等信息;

     当producer获取到metadata信息之后, producer将会和Topic下所有partition leader保持socket连接;

     消息由producer直接通过socket发送到broker,中间不会经过任何"路由层",事实上,消息被路由到哪个partition上由producer客户端决定;

     比如可以采用"random"、"key-hash""轮询"等,如果一个topic中有多个partitions,那么在producer端实现"消息均衡分发"是必要的。

     在producer端的配置文件中,开发者可以指定partition路由的方式。

7.3、如何保证数据不丢失完全生产

Producer消息发送的应答机制。

设置发送数据是否需要服务端的反馈,有三个值0,1,all

0: producer不会等待broker发送ack 

1: 当leader接收到消息之后发送ack 

all: 当所有的follower都同步消息成功后发送ack

request.required.acks=0

7.4、Partition如何分布在不同的Broker上

//第i个partition

int i = 0;

//broker列表

list{ broker01, broker02, broker03}

for(int i=0;i<5;i++){

brIndex = I % list.size;

       //第i个partition分布在hostName上

hostName = list.get(brIndex)

}

7.5、Broker如何保存数据其文件存储机制是什么

1)、Kafka文件存储基本结构

       在Kafka文件存储中,同一个topic下有多个不同partition,每个partition为一个目录,partiton命名规则为topic名称+有序序号,第一个partiton序号从0开始,序号最大值为partitions数量减1。

       每个partion(目录)相当于一个巨型文件被平均分配到多个大小相等segment(段)数据文件中。但每个段segment file消息数量不一定相等,这种特性方便old segment file快速被删除。

       默认保留7天的数据。

c00f63ec1e16eddba27314184a4ea211.png

      每个partiton只需要支持顺序读写就行了,segment文件生命周期由服务端配置参数决定。(什么时候创建,什么时候删除)

9daa26471284d828ac5233b12b6a0883.png
2)、Kafka Partition Segment

     Segment file组成:由2大部分组成,分别为index file和data file,这两个文件一一对应,成对出现,后缀".index"和“.log”分别表示为segment索引文件、数据文件。

504db551a06a673ad42090b615982ce4.png

       Segment文件命名规则:partion全局的第一个segment从0开始,后续每个segment文件名为上一个segment文件最后一条消息的offset值。数值最大为64位long大小,19位数字字符长度,没有数字用0填充。

      索引文件存储大量元数据,数据文件存储大量消息,索引文件中元数据指向对应数据文件中message的物理偏移地址。

d4f53a13a91700789a9b0506f0932e25.png

       其中以索引文件中元数据3,497为例,依次在数据文件中表示第3个message(在全局partiton表示第368772个message)、以及该消息的物理偏移地址为497。

3)、Kafka 查找message

读取offset=368776的message,需要通过下面2个步骤查找。

504db551a06a673ad42090b615982ce4.png

第一步:查找segment file

00000000000000000000.index表示最开始的文件,起始偏移量(offset)为0。

00000000000000368769.index的消息量起始偏移量为368770 = 368769 + 1。

00000000000000737337.index的起始偏移量为737338=737337 + 1

其他后续文件依次类推。

以起始偏移量命名并排序这些文件,只要根据offset **二分查找**文件列表,就可以快速定位到具体文件。当offset=368776时定位到00000000000000368769.index和对应log文件。

第二步:通过segment file查找message

当offset=368776时,依次定位到00000000000000368769.index的元数据物理位置和00000000000000368769.log的物理偏移地址

然后再通过00000000000000368769.log顺序查找直到offset=368776为止。

7.6、消费者如何标记消费状态

通过偏移量来标识。

扩展偏移量与偏移量提交:

      偏移量是一个自增长的ID,用来标识当前分区的哪些消息被消费过了,这个ID会保存在kafka的broker当中,而且消费者本地也会存储一份。

       因为每次消费每一条消息都要更新一下偏移量的话,难免会影响整个broker的吞吐量,所以一般这个偏移量在每次发生改动时,先由消费者本地改动,默认情况下,消费者每5秒钟会提交一次改动的偏移量,这样做虽然说吞吐量上来了,但是可能会出现重复消费的问题: 

       因为可能在下一次提交偏移量之前,消费者本地消费了一些消息,然后发生了分区再均衡(分区再均衡在下面有讲) 那么就会出现一个问题。

       假设上次提交的偏移量是 2000 在下一次提交之前,其实消费者又消费了500条数据,也就是说当前的偏移量应该是2500 但是这个2500只在消费者本地,也就是说,假设其他消费者去消费这个分区的时候拿到的偏移量是2000,那么又会从2000开始消费消息,那么2000到2500之间的消息又会被消费一遍,这就是重复消费的问题。

      kafka对于这种问题也提供了解决方案:手动提交偏移量

可以关闭默认的自动提交(enable.auto.commit= false) 然后使用kafka提供的API来进行偏移量提交,kafka提供了两种方式提交偏移量 :同步和异步

//同步提交偏移量kafkaConsumer.commitSync();//异步提交偏移量kafkaConsumer.commitAsync();

       他们之间的区别在于,同步提交偏移量会等待服务器应答,并且遇到错误会尝试重试,但是会一定程度上影响性能不过能确保偏移量到底提交成功与否;而异步提交的对于性能肯定是有提示的,但是弊端也就像我们刚刚所提到遇到错误没办法重试,因为可能在收到你这个结果的时候又提交过偏移量了,如果这时候重试,又会导致消息重复的问题了。

        其实,我们可以采用同步+异步的方式来保证提交的正确性以及服务器的性能。因为异步提交的话,如果出现问题但不是致命问题的话,可能下一次提交就不会出现这个问题了,所以有些异常是不需要解决的(可能单纯的就是网络抽风了呢? ) 所以,我们平时可以采用异步提交的方式,等到消费者中断了(遇到了致命问题,或是强制中断消费者) 的时候再使用同步提交(因为这次如果失败了就没有下次了,所以要让他重试) 。

具体代码:

try {        while (true) {            ConsumerRecords<String, String> poll = kafkaConsumer.poll(500);            for (ConsumerRecord<String, String> context : poll) {                System.out.println("消息所在分区:" + context.partition() + "-消息的偏移量:" + context.offset() + "key:" + context.key() + "value:" + context.value());            }            //正常情况异步提交            kafkaConsumer.commitAsync();        }    } catch (Exception e) {        e.printStackTrace();    } finally {        try {            //当程序中断时同步提交            kafkaConsumer.commitSync();        } catch (Exception e) {            e.printStackTrace();        } finally {            //关闭当前消费者  具体在下面有讲            kafkaConsumer.close();        }    }
      值得一提的是,在手动提交时kafka提供了你可以传入具体的偏移量来完成提交,也就是指定偏移量提交,但是非常不建议手动指定,因为如果指定的偏移量小于分区所存储的偏移量大小的话,那么会导致消息重复消费,如果指定的偏移量大于分区所存储的偏移量的话,那么会导致消息丢失

7.7.消费者的分区再均衡及负载均衡策略是什么

分区再均衡也是kafka里面非常重要的一个概念。

首先操作在以下情况下会触发分区再均衡(Rebalance)操作:

a、组成员发生变更(新consumer加入组、已有consumer主动离开组或已有consumer崩溃了);

b、订阅主题数发生变更,如果你使用了正则表达式的方式进行订阅,那么新建匹配正则表达式的topic就会触发rebalance;

c、订阅主题的分区数发生变更。

当触发Rebalance,kafka重新分配分区所有权

     何为分区所有权?我们之前有提到过,消费者有一个消费者组的概念, 而且一个消费者组在消费一个主题时有以下规则,一个消费者可以消费多个分区,但是一个分区只能被一个消费者消费。如果我有分区 0、1、2 现在有消费者 A,B 那么 kafka可能会让消费者A 消费 0,1 这两个分区,那么 这时候我们就会说,消费者A 拥有分区 0、1的所有权。

      当触发 Rebalance 的时候kafka会重新分配这个所有权,还是基于刚刚的比方,消费者A 拥有 0 和1 的所有权,消费者B 会有2的所有权。当消费者B离开kafka的时候 这时候 kafka会重新分配一下所有权,此时整个消费者组只有一个A 那么 0、1、2 三个分区的所有权都会属于A ,同理如果这时候有消费者C进入这个消费者组,那么这时候kafka会确保每一个消费者都能消费一个分区。

       当触发Rebalance时,由于kafka正在分配所有权,会导致消费者不能消费,而且还会引发一个重复消费的问题, 当消费者还没来得及提交偏移量时,分区所有权遭到了重新分配,那么这时候就会导致一个消息被多个消费者重复消费。

       那么解决方案就是在消费者订阅时,添加一个再均衡监听器,也就是当kafka在做Rebalance操作前后,均会调用再均衡监听器,那么这时候 我们可以在kafka Rebalance之前提交我们消费者最后处理的消息来解决这个问题。

拓展、Close():

      当我们不需要某个消费者继续消费kafka当中的数据时,我们可以选择调用Close方法来关闭它,在关闭之前 close方法会发送一个通知告诉kafka我这个消费者要退出了,那么 kafka就会准备Rebalance 而且如果是采用的自动提交偏移量,消费者自身也会在关闭自己之前提交最后所消费的偏移量 。当然即使没有调用close方法,而是直接强制中断了消费者的进程 kafka也会根据我们后面会说到的系统参数捕捉到消费者退出了。

7.8.如何保证消费者消费的数据有序

      只能保证同一个分区下的数据是有序的,可以让同一类的数据进入到同一个分区里。

      若想保证同一个主题的数据被消费时的顺序和生产时的顺序一致,那么只能设置一个分区。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

linux 关闭端口_手把手教你在Linux中快速检测端口的 3 个小技巧

一个执着于技术的公众号前言 无论是要解决网络连接问题还是配置防火墙&#xff0c;第一件事是要检查系统实际打开了哪些端口。本文介绍了几种快速查找 Linux 系统上哪些端口向外部开放的方法。什么是开放端口 监听端口是应用程序监听的网络端口。你要得到的监听端口名单通常可以…

2020-11-20

ln -s /bis_data/mysql/tmp/mysql.sock /tmp/ find / -name mysql.sock 2>/dev/null

未能找到程序集“platform.winmd_应用程序崩溃后 微软错误报告工具到底是如何联机检查解决方案的?...

在 Windows 应用意外崩溃后&#xff0c;系统似乎会努力地寻找解决方案。但是在绝大多数情况下&#xff0c;这一切都是徒劳的&#xff0c;并不会向用户给出任何结果。即便如此&#xff0c;很多人还是想要知道这个无效的过程期间到底都发生了什么。好消息是&#xff0c;近日微软 …

mysql索引创建和使用注意事项

总结&#xff1a; 1、在使用索引时&#xff0c;一般情况下不建议使用like操作。如果使用&#xff0c;则%放在后面。否则不会使用索引。like ‘%abd%’不会使用索引,而like ‘aaa%’可以使用索引.&#xff08;最左缀原则&#xff09; 2、单列索引的使用&#xff1a; 《1》 只…

不同存储结构的文件磁盘io操作次数_MySQL InnoDB存储引擎

第1章 MySQL体系结构和存储引擎1.1数据库和实例数据库&#xff1a;物理操作系统文件或其他形式文件类型的集合。实例&#xff1a;MySQL数据库由后台线程以及一个共享内存区组成。共享内存可以被运行 的后台线程所共享。数据库实例才是真正用于操作数据库文件的。启动MySQL数据库…

win10-PC端无法输入中文

试过 任务管理器中&#xff0c;的 MscCtfMonitor任务&#xff0c;先选择结束&#xff0c;然后再选择运行。关闭后输入法就可重新使用了---不行 当出现Win10无法输入中文汉字时&#xff0c;首先我们需要重启一下“输入法”程序&#xff1a; 右击桌面“Windows”图标&#xff0c…

因果图中的约束关系

E:互斥&#xff0c;exclude&#xff0c;表示abc最多只能有一个1&#xff0c;即abc000&#xff0c;100&#xff0c;010&#xff0c;001&#xff0c;只能有1个1或者全0&#xff08;可不选&#xff0c;要选最多选一个&#xff09;。I:包含&#xff0c;include&#xff0c;表示abc不…

如何销毁一个实例化对象_JAVA中如何创建和销毁对象

第1条 考虑用静态方法代替构造器类可以通过静态工厂方法来提供它的客户端&#xff0c;而不是通过构造器。提供静态工厂方法而不是公有构造器&#xff0c;这样做具有几大优势。1.静态工厂方法与构造器不同的第一大优势在于&#xff0c;它们有名称。例如&#xff0c;构造器BigInt…

因果图-交通一卡通自动充值软件系统-实例分析

因果图法测试用例的设计步骤 &#xff08;1&#xff09;确定软件规格(需求)中的原因和结果 &#xff08;2&#xff09;确定原因和结果之间的逻辑关系 &#xff08;3&#xff09;确定因果图中的各个约束(constraints) &#xff08;4&#xff09;画出因果图并转换为决策表 &…

如何区分电梯卡为id卡ic卡_电梯刷卡系统基本属性

电梯刷卡控制系统的发展是十分迅速的&#xff0c;在这点上相信大家都有所体会。但是为了节约成本费用&#xff0c;很多地产商都是安装的基本常见的电梯刷卡控制系统&#xff0c;这种常见的电梯&#xff0c;能够满足基本上的用户需求&#xff0c;在零件上面也是能够与大多数的零…

前端校验和后端校验区别

前台验证数据格式 后台验证的是数据的正确性 当下流行的系统架构方案中&#xff0c;前端和后端都是分离开的。 目的&#xff1a;① 为了方便前端开发人员和后端开发人员可以同时开发&#xff1b;② 前后端分离也使得前后端的代码可以分开进行管理&#xff0c;方便了各自的版…

socket timeout是什么引起的_MySQL C API 参数 MYSQL_OPT_READ_TIMEOUT 的一些行为分析

作者&#xff1a;戴岳兵MYSQL_OPT_READ_TIMEOUT 是 MySQL c api 客户端中用来设置读取超时时间的参数。在 MySQL 的官方文档中&#xff0c;该参数的描述是这样的&#xff1a;MYSQL_OPT_READ_TIMEOUT (argument type: unsigned int *)The timeout in seconds for each attempt t…

Python操作文件,报FileNotFoundError: [Error 2] No such file or directory错误

python操作文件时&#xff0c;报No such file or directory错误。 多次检查目录、文件名、语法都是对的。 折腾一番后&#xff0c;打开文件所在文件夹&#xff0c;并显示所有文件后缀名&#xff0c;才发现此文件并没有txt后缀名 解决方法&#xff1a; 添加文件的.txt后缀名&a…

练习ddt-file_data时,报错UnboundLocalError local variable ‘value‘ referenced before assignment

错误原因就是&#xff0c;在xx.yml中的内容无效 更改之前&#xff1a; 更改之后&#xff1a; 注意冒号后面要有空格 改完之后运行就能正确读取到了

卷积神经网络原理_人脸识别背后,卷积神经网络的数学原理原来是这样的

在自动驾驶、医疗以及零售这些领域&#xff0c;计算机视觉让我们完成了一些直到最近都被认为是不可能的事情。卷积神经网络可能是这一巨大成功背后的关键组成模块。这次&#xff0c;我们将要使用卷积神经网络的思想来拓宽我们对神经网络工作原理的理解。简介过去我们接触到了密…

负载均衡策略_常见的负载均衡策略

轮询(Round Robin)&#xff1a; 这种方法就会将收到的请求循环分配到服务器集群中的每台机器&#xff0c;即有效服务器。如果使用这种方式&#xff0c;所有的标记进入虚拟服务的服务器应该有相近的资源容量以及敷在相同的应用程序。如果所有的服务有相同或者相近的性能那么选择…

白盒测试-修正条件判定覆盖

当程序中的判定语句包含多个条件时&#xff0c;运用多条件覆盖方法进行测试&#xff0c;其条件取值组合数目是非常大的。 修正条件判定覆盖要求在一个程序中每一种输入输出至少得出现一次&#xff0c;在程序中的每一个条件必须产生所有可能的输出结果至少一次&#xff0c;并且…

springboot整合shiro_Springboot整合Shiro:简洁的身份认证

简单的web应用进行身份认证的流程&#xff1a;1.对未认证的用户请求进行拦截&#xff0c;跳转到认证页面。2.用户通过用户名密码及其他凭证进行身份认证&#xff0c;认证成功跳转成功页面&#xff0c;认证失败提示相关失败信息。根据流程&#xff0c;采用shiro进行快速开发。1.…

2024年【安全生产监管人员】考试及安全生产监管人员模拟考试题库

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 2024年【安全生产监管人员】考试及安全生产监管人员模拟考试题库&#xff0c;包含安全生产监管人员考试答案和解析及安全生产监管人员模拟考试题库练习。安全生产模拟考试一点通结合国家安全生产监管人员考试最新大纲…

PICT工具安装使用

1、安装PICT 通过下载安装包pict33.msi&#xff0c; 链接&#xff1a;https://pan.baidu.com/s/1YWIA5XLNI0MMFkiQ-EqZ9w 提取码&#xff1a;ho7g 解压安装&#xff0c;安装成功后验证&#xff1a;打开cmd命令终端&#xff0c;输入pict显示如下即证明安装成功。 2、新建Mod…