浅谈 kafka

引言

  • 同事在公司内部分享了关于 kafka 技术一些相关的内容,所以有了这篇文章;
  • 部分图片选自网络摘抄;

1 Kafka概述

1.1 定义

Kafka传统定义:kafka是一个分布式的基于发布/订阅模式的消息队列。
Kafka最新定义:kafka用于构建实时数据处理系统,它具有横向扩展、高可用,速度极快等特点,已经被很多公司使用。

1.2 应用场景

  • 消息系统:解耦、削峰、缓存消息、异步通信等。
  • 日志收集:可以用kafka收集各种服务的log,通过kafka以统一接口服务的方式开放给各种consumer。
  • 用户活动跟踪:kafka经常被用来记录web用户或者app用户的各种活动,如浏览网页、搜索、点击等活动,这些活动信息被各个服务器发布到kafka的topic中,然后消费者通过订阅这些topic来做实时的监控分析,亦可保存到数据库。
    运营指标:kafka也经常用来记录运营监控数据。包括收集各种分布式应用的数据,生产各种操作的集中反馈,比如报警和报告。
    大数据实时计算:kafka被应用到大数据处理,如与hadoop、spark、storm等整合。

1.3 主流MQ对比

什么是MQ,谈谈你的理解?

特性ActiveMQRabbitMQRocketMQKafka
单机吞吐量万级万级十万级,支撑高吞吐十万级,高吞吐
性能的稳定性老牌消息队列,性能一般、资源消耗比较大。消息堆积时,性能不稳定、明显下降队列较多、消息堆积时性能稳定队列/分区多时性能不稳定、明显下降;消息堆积时性能稳定
时效性ms级微秒级ms级延迟在ms级以内
可用性非常高,分布式架构非常高,分布式,多个副本
消息可靠性有较低的概率丢失数据基本不丢失经过参数优化配置,可以做到0丢失同RocketMQ
技术栈JavaErlangJavaJava、Scala

1.4 初识Kafka(kafka-2.12-3.2.0)

(Kafka之所以受到越来越多的青睐,与它所“扮演 ”的三大角色是分不开的 :)

  • 消息系统: Kafka和传统的消息系统(也称作消息中间件)都具备系统解稿、冗余存储、流量削峰、缓冲、异步通信、扩展性、 可恢复性等功能。与此同时,Kafka 还提供了大多数消息系统难以实现的消息顺序性保障及回溯消费的功能。
  • 存储系统: Kafka 把消息持久化到磁盘,相比于其他基于内存存储的系统而言,有效地降低了数据丢失的风险 。 也正是得益于Kafka的消息持久化功能和多副本机制,我们可以把Kafka作为长期的数据存储系统来使用,只需要把对应的数据保留策略设置为“永久”或启用主题的日志压缩功能即可。
  • 流式处理平台: Kafka不仅为每个流行的流式处理框架提供了可靠的数据来源,还提供了一个完整的流式处理类库,比如窗口、连接、变换和聚合等各类操作。

1.5 基本概念

  • 消息:消息就是kafka中的一条数据,类似于数据库中的一行。
  • Producer:生产者,向kafka主题发布消息的应用程序。
  • Consumer:消费者,从kafka主题订阅消息的应用程序。
  • Consumer Group:消费者组,由多个 consumer 组成。消费者组内每个消费者负责消费不同分区的数据,一个分区只能由一个组内消费者消费;消费者组之间互不影响。 所有的消费者都属于某个消费者组,即消费者组是逻辑上的一个订阅者。
  • Broker:kafka服务器,一个broker可以容纳多个topic。
  • Topic:主题是承载消息的逻辑容器,在实际使用中用来区分具体业务。
  • Partition:为了实现扩展性,一个非常大的topic可以分布到多个broker上,一个topic可以分为多个partition,每个partition是一个有序的队列。如果一个topic中的partition有5个,那么topic的并发度为5。
  • Offset:每个Consumer 消费的信息都会有自己的序号,我们称作当前队列的offset。即消费点位标识消费到的位置。
  • Replica:副本,为保证集群中的某个节点发生故障时,该节点上的partition数据不丢失,且kafka仍然能够继续工作,kafka提供了副本机制,一个topic的每个分区都有若干个副本,一个leader和若干个follower。
  • Leader:每个分区多个副本的“主”,生产者发送数据的对象,以及消费者消费数据的对象都是leader。
  • Follower:每个分区多个副本中的“从”,实时从leader中同步数据,保持和leader数据的同步。 leader发生故障时,某个follower会成为新的 leader。

2 Kafka生产者

2.1生产者消息发送流程

2.1.1 整体架构

在这里插入图片描述
在这里插入图片描述

2.1.2 名词释义
  • 消息在网络上都是以字节(Byte)的形式传输的,在发送之前需要创建一块内存区域来保存对应的消息。在Kafka生产者客户端中,通过java.io.ByteBuffer实现消息内存的创建和释放。不过频繁的创建和释放是比较耗费资源的,在RecordAccumulator的内部还有一个BufferPool,它主要用来实现ByteBuffer的复用,以实现缓存的高效利用。不过BufferPool只针对特定大小的ByteBuffer进行管理,而其他大小的ByteBuffer不会缓存进BufferPool中,这个特定的大小由batch.size参数来指定,默认值为16KB
  • RecordAccumulator 缓存消息以便 Sender 线程可以批量发送,进而减少网络传输的资源消耗以提升性能。RecordAccumulator 缓存的大小可以通过生产者客户端参数 buffer.memory 配置,默认值为32MB。如果生产者发送消息的速度超过发送到服务器的速度,则会导致生产者空间不足,这个时候KafkaProducer的send()方法调用要么被阻塞,要么抛出异常,这个取决于参数max.block.ms的配置,此参数的默认值为60秒
  • 主线程中发送过来的消息都会被追加到RecordAccumulator的某个双端队列(Deque)中,在RecordAccumulator 的内部为每个分区都维护了一个双端队列,队列中的内容就是ProducerBatch,即 Queque<ProducerBatch>。将较小的ProducerRecord拼凑成一个较大的ProducerBatch,也可以减少网络请求的次数以提升整体的吞吐量。
  • SenderRecordAccumulator 中获取缓存的消息之后,会进一步将原本<分区,Deque<ProducerBatch>>的保存形式转变成<Node,List< ProducerBatch>的形式,其中Node表示Kafka集群的broker节点。然后进一步封装成<Node,Request>的形式,这样就可以将Request请求发往各个Node。
  • 请求在从Sender线程发往Kafka之前还会保存到 InFlightRequests中,InFlightRequests保存对象的具体形式为 Map<NodeId,Deque<Request>>,它的主要作用是缓存了已经发出去但还没有收到响应的请求(NodeId 是一个 String 类型,表示节点的 id 编号)。通过配置参数max.in.flight.requests.per.connection,默认值为 5,即每个连接最多只能缓存 5 个未响应的请求,超过该数值之后就不能再向这个连接发送更多的请求了,除非有缓存的请求收到了响应(Response)。通过比较Deque<Request>的size与这个参数的大小来判断对应的Node中是否已经堆积了很多未响应的消息,如果真是如此,那么说明这个Node 节点负载较大或网络连接有问题,再继续向其发送请求会增大请求超时的可能。

2.2 重要的生产者参数

2.2.1 acks
  • acks=0, 生产者在成功写入消息之前不会等待任何来自服务器的相应。如果出现问题生产者是感知不到的,消息就丢失了。不过因为生产者不需要等待服务器响应,所以它可以以网络能够支持的最大速度发送消息,从而达到很高的吞吐量。
  • acks=1,只要集群的leader节点收到消息,生产这就会收到一个来自服务器的成功响应。如果消息无法达到leader节点(比如leader节点崩溃,新的leader还没有被选举出来),生产者会收到一个错误响应,为了避免数据丢失,生产者会重发消息。但是,这样还有可能会导致数据丢失,如果收到写成功通知,此时leader节点还没来的及同步数据到follower节点,leader节点崩溃,就会导致数据丢失。
  • acks=-1(all), 只有当所有参与复制的节点都收到消息时,生产这会收到一个来自服务器的成功响应,这种模式是最安全的,它可以保证不止一个服务器收到消息。
2.2.2 buffer.memory

        该参数用来设置生产者内存缓冲区的大小,生产者用它缓冲要发送到服务器的消息。如果应用程序发送消息的速率比写入kafka的速度要快,会导致生产者空间不足。这个时候,send()方法调用要么被阻塞,要么抛出异常,取决于如何设置max.block.ms,表示在抛出异常之前可以阻塞一段时间。)

2.2.3 compression.type

        默认情况下,消息发送时不会被压缩。该参数可以设置成snappy,gzip或lz4,它指定了消息发送给broker之前使用哪一种压缩算法。snappy占用较少的CPU,却能提供较好的性能和相当可观的压缩比,如果比较关注性能和网络带宽,可以使用这种压缩算法。gzip压缩算法一般会占用比较多的CPU,但会提供更高的压缩,如果网络带宽有限,可以使用这种算法。使用压缩可以降低网络传输开销和存储开销,而这往往是向kafka发送消息的瓶颈所在。

2.2.4 max.request.size

        该参数用来限制生产者客户端能发送的消息的最大值,默认为1MB。

2.2.5 retries和retry.backoff.ms

        retries参数用来配置生产者重试的次数,默认值为0,即在发生异常的时候不进行任何重试动作。retry.backoff.ms有关,这个参数的默认值为100,它用来设定两次重试之间的时间间隔,避免无效的频繁重试。

2.2.6 batch.size

        当有多个消息要被发送到同一个分区时,生产者会把它们放在同一个批次里。该参数指定了一个批次可以使用的内存大小,按照字节数计算,而不是消息个数。当批次被填满,批次里的所有消息会被发送出去。不过生产者并不一定都会等到批次被填满才发送,半满的批次,甚至只包含一个消息的批次也可能被发送。所以就算把batch.size设置的很大,也不会造成延迟,只会占用更多的内存而已,如果设置的太小,生产者会因为频繁发送消息而增加一些额外的开销。

2.2.7 linger.ms

        该参数用来指定生产者发送ProducerBatch之前等待更多消息(ProducerRecord)加入ProducerBatch的时间,默认值为0。

3 Kafka Broker

3.1 ZK存储的Kafka信息

在这里插入图片描述

  • /kafka/brokers/ids 记录kafka集群服务器
  • /kafka/brokers/topics/{topic}/partitions/0/state 记录谁是Leader,有哪些服务器可用
  • consumers 以前是用来保存offset信息,0.9版本之后offset存储在kafka主题中
  • controller用来辅助选举Leader

3.2 Broker整体工作流程

在这里插入图片描述

3.3 Kafka副本

  • Kafka副本作用:提高数据可靠性。
  • Kafka默认副本1个,生产环境一般配置为2个,保证数据可靠性;太多副本会增加磁盘存储空间,增加网路上数据传输,降低效率。
  • Kafka中副本分为:Leader和Follewer。Kafka生产者只会把数据发往Leader,然后Follower找Leader进行数据同步。
  • Kafka分区中的所有副本统称为AR,AR=ISR+OSR
        ISR:表示和Leader保持同步的Follower集合(也包含Leader)。如果Follower长时间未向Leader发送通信请求或同步数据,则该Follower将被踢出ISR。该时间阈值由replica.lag.time.max.ms参数设定,默认为30S。Leader发生故障之后,就会从ISR中选举新的Leader。
        OSR:表示Follower与Leader副本同步时,延迟过多的副本集合。

3.4 Leader和Follower故障处理细节

3.4.1 Leader故障处理细节:

在这里插入图片描述

3.4.2 Follower故障处理细节:

在这里插入图片描述

3.5 Kafka的数据存储

在这里插入图片描述
在这里插入图片描述

3.5 Kafka文件清理策略

(Kafka中默认的日志保存时间为7天,可以通过调整如下参数修改保存时间)**

  • log.retention.hours,小时(168)最低优先级,默认7天。
  • log.retention.minutes,分钟。
  • log.retention.ms,毫秒 最高优先级。
  • log.retention.check.interval.ms,负责设置检查周期,默认5分钟。

日志超过设置时间,Kafka中提供了两种日志清理策略:

  • delete 日志删除:将过期数据删除,参数设置:log.cleanup.policy = delete(a.基于时间,b.基于大小 log.retention.bytes,默认等于-1,表示无穷大)。
  • compact 日志压缩:参数设置:log.cleanup.policy = compact,对于相同key的不同value值,只保留最后一个版本。
    在这里插入图片描述

3.6 数据高效读写

  • kafka支持分布式集群,可以采用分区技术,并行度高。
  • 采用稀疏索引,可以快速定位要消费的数据。
  • 顺序读写磁盘。(顺序写可以达到600M/s,随机写只有100K/s)
  • 页缓存+零拷贝技术
3.6.1 高效读写技术

页缓存:kafka重度依赖底层操作系统提供的PageCache功能。当上层有写操作时,操作系统只是将数据写入PageCache中;当读操作发生时,先从PageCache中查找,如果找不到,再去磁盘中读取。实际上PageCache是把尽可能多的空闲内存当做了磁盘缓存来使用。

DMA:DMA(Direct Memory Access,直接内存访问)拷贝是计算机系统中常用的一种数据传输方式。在进行数据传输时,CPU通常需要参与数据的读取和写入过程,这样会占用CPU的大量时间和资源。为了减轻CPU的负担,提高系统整体性能,引入了DMA技术。

  • DMA拷贝的基本原理是通过直接访问系统内存,绕过CPU的直接控制,实现数据的传输。具体来说,DMA控制器可以直接从设备(如硬盘、网卡等)读取数据,并将数据直接写入系统内存,或者直接从内存读取数据并发送给设备,而无需CPU的参与。这样一来,CPU可以继续执行其他任务,而数据传输过程由DMA控制器完成,从而提高了系统的并发性和整体性能。
  • 在实际应用中,DMA拷贝常用于大规模数据传输,例如文件读写、网络数据传输等场景。通过使用DMA技术,可以显著减少CPU的负载,提高数据传输效率,从而改善系统的响应速度和性能表现。

sendfile():sendfile() 是一个在网络编程中常用的系统调用函数,它用于在两个文件描述符之间直接传输数据,而无需在用户空间进行数据拷贝,避免了数据在用户空间和内核空间之间来回复制的过程。在Linux系统中,sendfile() 函数可以在内核空间和内核缓冲区之间直接传输数据,提高了数据传输的效率和性能。

3.6.2 各种读写流程对比
  • 常规读取数据流程:
    在这里插入图片描述
  • sendfile()方式读取数据流程:
    在这里插入图片描述
  • sendfile + DMA gather copy:
    在这里插入图片描述

4 Kafka 消费者

4.1 消费方式

在这里插入图片描述

4.2 消费者整体工作流程

在这里插入图片描述

4.3 消费者组原理

4.3.1 Consumer Group

(消费者组由多个consumer组成,形成一个消费者组的条件是,所有消费者的groupid相同)

  • 消费者组内每个消费者负责消费不同分区的数据,一个分区只能由一个组内消费者消费。
  • 消费者组之间互不影响,消费者组是逻辑上的一个订阅者。
4.3.2 消费者组初始化流程

在这里插入图片描述

4.3.3 消费者组消费流程

在这里插入图片描述

4.4 分区的分配以及再平衡

        Kafka有四种主流的分区分配策略:Range、RoundRobin、Sticky、CooperativeSticky。可以通过配置参数partition.assignment.strategy修改分区分配策略,默认策略是Range+CooperativeSticky,Kafka可以同时使用多个分区分配策略。

4.4.1 Range策略

在这里插入图片描述

4.4.2 RoundRobin策略

在这里插入图片描述

4.4.3 Sticky策略

         该策略旨在尽可能地保持分配的稳定性,即消费者与分区的绑定关系尽量保持不变,这有助于提高消费者的性能和效率。(粘性分区)

Sticky 分配策略的工作原理如下:

  • 初始分配:当一个新的消费者加入消费者组时,初始分配会按照其他常规的分配策略(如 Round-robin 等)将分区分配给消费者。
  • Sticky 机制:一旦分配完成后,Sticky 分配策略会尽可能地保持分配的稳定性。即在后续的重新分配中,尽量保持每个消费者与其分配到的分区的绑定关系不变。
  • 重平衡触发:当消费者组发生变化(如有新的消费者加入、有消费者退出等)或者分区发生变化时,会触发重平衡操作。
  • 重平衡操作:在重平衡操作中,根据 Sticky 分配策略,系统会尽量保持消费者与分区的绑定关系不变。这意味着在重新分配分区时,会优先考虑让消费者仍然消费之前分配到的分区。

(通过 Sticky 分配策略,Kafka 可以有效地减少在消费者组内发生重平衡时的数据移动,避免不必要的分区再分配,提高整体的性能和吞吐量。)

4.4.4 CooperativeSticky策略:

        CooperativeSticky 分配策略是 Kafka 新版本中引入的一种消费者分区分配策略,旨在提高消费者的负载均衡和性能

有以下几个特点:

  • 合作式(Cooperative):CooperativeSticky 策略是一种合作式的分配策略,消费者可以共同合作以优化分区的分配。
  • 粘性(Sticky):与 Sticky 策略类似,CooperativeSticky 策略也具有粘性的特点,即消费者在某个分区上可以保持相对长时间的粘性。
  • 动态调整:CooperativeSticky 策略会根据消费者组中各个消费者的处理情况动态调整分区的分配,以实现更好的负载均衡。

工作原理

  • 首次分配:当消费者组第一次订阅主题时,CooperativeSticky 策略会根据消费者的订阅情况和消费能力来为每个消费者分配初始的分区。
  • 协作调整:随着消费者组内消费者的工作情况变化,比如消费者加入或退出消费者组、消费速度不均等情况,CooperativeSticky 策略会协作调整分区的分配情况。
  • 动态优化:策略会根据消费者的消费速度和处理能力,选择最优的分区分配方式,以使得消费者组内各个消费者的负载尽可能均衡,避免出现某些消费者负责过多分区而导致负载不均衡的情况。
  • 保持粘性:同时,CooperativeSticky 策略也会保持一定程度的粘性,确保消费者在一段时间内负责相同的分区,以提高局部性和消费效率。

总结:通过合作式和动态调整的特点,CooperativeSticky 分配策略能够更好地适应消费者组的动态变化,提高消费者组的负载均衡性和整体性能,从而更有效地处理 Kafka 主题的消息消费。

4.5 Offset

        Kafka 中的 Offset(偏移量)是指消费者在一个特定分区中的消息消费进度,即消费者已经读取并处理到哪一条消息

4.5.1 Offset 的作用
  • 标识消费位置:Offset 标识了消费者在特定分区中的消费位置,记录了消费者已经处理过的消息。
  • 实现消息的顺序消费:通过管理 Offset,消费者可以确保消息被按照正确的顺序消费,避免重复消费或漏掉消息。
  • 支持消费者组协调:Offset 的管理可以帮助消费者组内的各个消费者进行协调,避免重复消费,实现负载均衡。
4.5.2 Offset 的类型
  • Commit Offset:消费者将已经处理完的消息的 Offset 提交给 Kafka,表示这些消息已经成功消费。Kafka 会记录 Commit Offset,并在下次消费时从提交的 Offset 开始继续。
  • Current Offset:当前待消费的消息的 Offset,即消费者下一次将要读取的消息的位置。
  • Group Offset:消费者组中每个消费者在每个分区中的消费位置,由消费者组协调器统一管理。
4.5.3 Offset 的存储方式
  • 内部存储:Kafka 内部使用 __consumer_offsets 主题来存储消费者组的 Offset 信息,每个消费者组都有一个特定的 Consumer Group ID。
  • 外部存储:消费者也可以选择自行管理 Offset 的存储,比如在数据库中记录每个分区的最新 Offset,以便在重新启动消费者时恢复消费位置。
4.5.4 Offset 的管理
  • 自动提交:消费者可以选择自动提交 Offset,Kafka 会周期性地自动将消费者消费的 Offset 提交给服务器。但存在风险,可能会导致消息重复消费或漏消费。
  • 手动提交:消费者可以手动控制 Offset 的提交时机,确保消息被正确处理。手动提交能够提供更精确的控制,避免不必要的重复消费。
  • Seek 操作:消费者可以通过 Seek 操作来调整消费位置,使得消费者可以从指定的 Offset 开始消费消息。

总结:Offset 在 Kafka 中扮演着非常重要的角色,帮助消费者管理消息消费的位置和进度,确保消息被正确、顺序地消费。消费者可以根据业务需求选择合适的Offset策略来进行消息消费。

4.6 消费者事务

4.6.1 关于重复消费与漏消费:

在这里插入图片描述
总结:如果想完成Consumer端的精准一次性消费,那么需要Kafka消费端将消费过程和提交Offset过程做原子性绑定,我们需要将Kafka的offset保存到支持事务的自定义介质中,比如Mysql。

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

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

相关文章

【Frida】【Android】05_Objection实战

🛫 系列文章导航 【Frida】【Android】01_手把手教你环境搭建 https://blog.csdn.net/kinghzking/article/details/136986950【Frida】【Android】02_JAVA层HOOK https://blog.csdn.net/kinghzking/article/details/137008446【Frida】【Android】03_RPC https://bl…

Kibana操作Elasticsearch教程

文章目录 简介ES文档操作创建索引查看索引创建映射字段查看映射关系字段属性详解typeindexstore 字段映射设置流程 新增数据新增会随机生成id新增自定义id智能判断 修改数据删除数据查询基本查询查询所有(match_all)匹配查询多字段查询词条匹配多词条精确…

HarmonyOS 应用开发之创建PageAbility

开发者需要重写app.js/app.ets中的生命周期回调函数,开发者通过DevEco Studio开发平台创建PageAbility时,DevEco Studio会在app.js/app.ets中默认生成onCreate()和onDestroy()方法,其他方法需要开发者自行实现。接口说明参见前述章节&#xf…

maven 依赖机制

安全工程师为啥关注maven依赖 log 4j事件之后,大家开始更加关注开源组件安全漏洞这个事。纷纷引入SCA 软件成分分析工具来识别项目中存在的开源组件和漏洞。 在sca工具扫描之后,会报出一大堆组件,review这个事就是安全团队投入时间来研判了…

【Linux多线程】线程的同步与互斥

【Linux多线程】线程的同步与互斥 目录 【Linux多线程】线程的同步与互斥分离线程Linux线程互斥进程线程间的互斥相关背景概念问题产生的原因: 互斥量mutex互斥量的接口互斥量实现原理探究对锁进行封装(C11lockguard锁) 可重入VS线程安全概念常见的线程不安全的情况…

是谁?阻止CXL在AI场景大展身手~

CXL虽然被视为业内新宠,但好像在AI场景的应用反而没有得到广泛的响应。 AI场景对内存带宽、容量以及数据一致性有着极高需求,特别是在深度学习训练和推理过程中,大量数据需要在CPU、GPU、加速器以及内存之间快速、高效地流动。CXL作为一种新…

Java基础入门day24

day24 abstract 抽象:似是而非,像又不是,具备某种对象的特征,但不完整 生活中的抽象:动物,并不真实存在的事物 程序中的抽象:不应该被创建的对象,动物近视一种会吃会睡的对象&#…

Netty核心原理剖析与RPC实践16-20

Netty核心原理剖析与RPC实践16-20 16 IO 加速:与众不同的 Netty 零拷贝技术 今天的课程我们继续讨论 Netty 实现高性能的另一个高阶特性——零拷贝。零拷贝是一个耳熟能详的词语,在 Linux、Kafka、RocketMQ 等知名的产品中都有使用,通常用于…

【单调栈】力扣84.柱状图中最大的矩形

上篇文章我们介绍了使用 无重复值 单调栈代码解决 含有重复值 的问题,在文章的最后,留下了一道考察相同思想的题目,今天我们来看看如何套路解决该题。 (还没看过前几篇介绍的小伙伴赶快关注,在 「单调栈」 集合里查看…

通过node 后端实现颜色窃贼 (取出某个图片的主体rgb颜色 )

1.需求 我前端轮播图的背景色 想通过每一张轮播图片的颜色作为背景色 这样的话 需要通过一张图片 取出图片的颜色 这个工作通过前端去处理 也可以通过后端去处理 前端我试了试 color-thief 的插件 但是 这个插件是基于canvas 的模式来的 我需要在小程序中使用这个插件 而且是…

HarmonyOS-如何使用ArkTS声明式语法和基础组件,实现待办列表。

介绍 本篇Codelab将介绍如何使用ArkTS声明式语法和基础组件,实现简易待办列表。效果为点击某一事项,替换标签图片、虚化文字。效果如图所示: 相关概念 ArkTS语法:ArkTS是HarmonyOS的主要应用开发语言。ArkTS基于TypeScript&…

2024/3/29(MybatisPlus插件代码生成,静态工具,逻辑删除,枚举处理器.JSON处理器,分页插件,通用分页实体)

jdbc:mysql://localhost:3306/mp?useUnicodetrue&characterEncodingutf8&serverTimezoneUTC 需要这样 日志查看级别

【C++杂货铺】内管管理

目录 🌈前言🌈 📁 C/C中内存分布 📁 new 和 delete的使用 📁 new 和 delete的优点 📁 new 和 delete的原理 📂 operator new 和 operator delete函数 📂 内置类型 &#x1f4c2…

代码随想录-DAY4|leetcode-24,19,142,面试题 02.07

文章目录 22. 两两交换链表中的节点19. 删除链表的倒数第N个节点size-n方式删除双指针方式(推荐) 面试题 02.07. 链表相交142. 环形链表II暴力解法快慢指针(推荐) 22. 两两交换链表中的节点 leetcode链接:两两交换链表…

怎样一次性给多篇word文档标注拼音?一键批量注音

随着办公自动化的普及,我们经常会遇到需要处理大量Word文档的情况。在这些文档中,有时需要将文字标注上拼音,特别是在处理一些包含生僻字或需要拼音辅助阅读的文档时。然而,手动一篇篇地给Word文档标注拼音不仅效率低下&#xff0…

Docker搭建LNMP环境实战(08):安装php-fpm

1、编写php测试文件 在文件夹&#xff1a;/mnt/hgfs/dockers/test_site/www目录下创建文件&#xff1a;test.php&#xff0c;内容为&#xff1a; <?phpecho "hello world!!!!!! From test.php"; ?>2、编写php-fpm部署配置文件 在文件夹&#xff1a;/mnt/h…

mars3d兼容老版本Chrome 浏览器的附件参考记录

问题 源代码里面是es5的写法&#xff0c;怎么在浏览器上就转换了。 mars3d会将es5转es6吗&#xff1f; 看加载的Cesium.js源代码没有问题&#xff0c;但是模块里面的源代码已经转换了&#xff0c;再低版本浏览器上面会无法运行“Uncaught SyntaxError: Unexpected token ?”…

JVM(一)——内存结构

一. 前言 1、什么是 JVM? 1&#xff09;定义&#xff1a; Java Virtual Machine - java 程序的运行环境&#xff08;java 二进制字节码的运行环境&#xff09; 2&#xff09;好处&#xff1a; 一次编写&#xff0c;到处运行自动内存管理&#xff0c;垃圾回收功能数组下标越…

测试员再也不怕漏测!花2年总结的这个测试模板太全了!

作为一个测试&#xff0c;最尴尬的莫过于分给你的task&#xff0c;别人做交叉兼容测试的时候&#xff0c;在你负责的内容里找出了很多你没有测试出来的bug。 我也曾因为测试不全被组长在工作群里艾特。说实话&#xff0c;真的恨不得找个地方躲起来。 为了避免自己再次出现类似…

用友BI告诉你,分析指标计算也可以很简单

分析数据&#xff0c;特别是分析财务数据&#xff0c;要计算得分析指标都非常多&#xff0c;涉及的数据来源也是各有不同&#xff0c;一旦哪个环节出了错就一切都得重来。难道分析指标的计算就没有更快更简单的办法了&#xff1f;奥威-用友BI告诉你&#xff0c;分析指标计算有别…