【Kafka 消息队列深度解析与应用】

Kafka 消息队列深度解析与应用

一、Kafka 概述

(一)产生背景

  • Kafka 最初是由 LinkedIn 开发,旨在解决其内部海量数据的实时传输问题。在现代大数据环境下,企业需要处理海量的数据流入和流出,包括用户的行为数据、系统日志、业务数据等,传统的消息队列系统在处理这些大数据量、高并发的数据时,面临着诸多挑战,如性能瓶颈、扩展性差、数据一致性难以保证等。Kafka 应运而生,它为大规模数据处理和实时数据传输提供了一个高性能、高可靠的分布式消息队列解决方案。

(二)特点

1. 高吞吐量
  • Kafka 能够处理海量的数据,支持每秒百万级别的消息传输,这得益于其高效的存储和网络 I/O 设计。从源码角度来看,在 Kafka 的存储层,使用了日志追加的存储方式,将消息顺序追加到磁盘上,避免了随机写操作,减少了磁盘寻道时间。例如,在 Log 类中,append() 方法负责将消息追加到日志文件中,其实现利用了操作系统的页缓存机制,使得写入操作可以在内存中完成,之后再由操作系统将数据异步刷到磁盘,提高了写入性能。在网络 I/O 方面,通过使用 Selector 类进行网络通信,采用了非阻塞式的 I/O 操作,结合零拷贝技术(FileChannel.transferTo() 方法的使用),减少了数据在用户态和内核态之间的拷贝次数,提高了数据传输效率,使 Kafka 可以高效地处理大量并发的生产者和消费者请求。
2. 可扩展性
  • Kafka 是分布式的,通过增加 Kafka 集群中的 Broker 节点可以轻松扩展系统的存储和处理能力。在源码中,KafkaController 类负责集群的管理和协调,当新节点加入时,会触发相应的负载均衡操作,如 onBrokerStartup() 方法会根据新节点的加入重新分配分区和副本,将部分分区的数据迁移到新节点上,确保数据分布的均匀性和负载的均衡,使 Kafka 可以灵活应对数据量的增长和并发的提高。
3. 持久性
  • Kafka 会将消息持久化存储在磁盘上,这确保了消息的可靠性,即使在消息被消费后,也可以根据配置的保留时间进行存储,以备后续的分析或重新消费。LogSegment 类负责存储消息的逻辑片段,它将消息存储在磁盘上的文件中,同时会根据配置的日志段大小和保留时间对消息进行清理或滚动,保证了消息存储的有序性和持久性。
4. 高可用性
  • Kafka 通过多副本机制来保证高可用性,每个主题的分区可以有多个副本,分布在不同的 Broker 节点上。在 ReplicaManager 类中,会对副本进行管理,通过 makeFollowers() 和 makeLeaders() 等方法实现副本的角色转换,当一个 Broker 出现故障时,其副本可以继续提供服务,保证了数据的可用性。

(三)核心架构

1. 生产者(Producer)
  • 生产者负责将消息发送到 Kafka 主题中。在 KafkaProducer 类中,会使用 RecordAccumulator 类来缓存消息,根据分区策略(如轮询、按关键字等)将消息分配到不同的分区,使用 Sender 类将消息发送到相应的 Broker。生产者可以配置一些重要的参数,如 acks 用于确定消息的确认机制(表示需要多少个副本确认收到消息才认为发送成功),batch.size 用于设置消息的批次大小,linger.ms 用于设置发送消息的延迟时间,以优化发送性能。
2. 消费者(Consumer)
  • 消费者从 Kafka 主题中订阅消息。在 KafkaConsumer 类中,使用 ConsumerCoordinator 类来协调消费者组内的消费者,使用 Fetcher 类从 Broker 中拉取消息。消费者可以配置 group.id 表示其所属的消费者组,通过 subscribe() 方法订阅主题,使用 poll() 方法拉取消息,还可以使用 commitSync() 或 commitAsync() 方法来提交消费偏移量,以便在下次消费时从正确的位置开始。
3. Broker
  • Broker 是 Kafka 集群中的服务节点,负责存储和处理消息。KafkaServer 类是 Broker 的核心,它包含多个组件,如 LogManager 负责日志存储管理,ReplicaManager 负责副本管理,SocketServer 负责网络通信,KafkaApis 类处理来自生产者和消费者的请求。
4. 主题(Topic)
  • 主题是消息的类别,生产者将消息发送到特定的主题,消费者从主题中消费消息。每个主题可以划分为多个分区,分区可以分布在不同的 Broker 上,这样可以提高并行处理能力。在 TopicConfig 类中可以对主题的各种属性进行配置,如分区数量、副本数量、消息保留时间等。

(四)应用场景

  • 大数据流处理:Kafka 可以作为大数据处理的数据源,将实时的数据流(如用户的点击流、传感器数据等)发送给下游的处理系统,如 Apache Spark 或 Apache Flink。这些大数据处理系统可以通过 Kafka 的消费者 API 实时消费数据,进行数据清洗、转换和分析。例如,在实时推荐系统中,用户的行为数据通过 Kafka 持续流入,Spark Streaming 可以实时消费这些数据,为用户提供实时的推荐内容。
  • 日志收集:在分布式系统中,不同的服务可以将日志信息发送到 Kafka,通过 Kafka 作为日志收集的中央枢纽,然后再将日志发送给日志存储和分析系统(如 Elasticsearch 和 Kibana 组合)。多个服务作为生产者将日志信息发送到 Kafka 主题,日志存储和分析系统作为消费者从 Kafka 中拉取日志信息进行存储和分析,实现了日志的集中管理和分析。

二、Kafka 的安装与配置

(一)安装过程

  • 下载 Kafka 软件包:
    首先,从 Kafka 官方网站下载适合你系统的 Kafka 软件包。
  • 解压和配置文件修改:
    解压后,进入 Kafka 的配置文件目录,主要修改 server.properties 文件。需要设置 broker.id 为每个 Broker 节点分配唯一的 ID,设置 listeners 以确定 Kafka 监听的网络地址和端口,设置 log.dirs 确定日志存储的目录,设置 zookeeper.connect 来指定 ZooKeeper 的连接地址(Kafka 依赖 ZooKeeper 进行集群管理)。

详细安装过程请参考这篇文章 Kafka实战

(二)代码示例:消息的生产和消费

1. 生产者代码示例
import org.apache.kafka.clients.producer.KafkaProducer;
import org.apache.kafka.clients.producer.Producer;
import org.apache.kafka.clients.producer.ProducerRecord;
import java.util.Properties;public class KafkaProducerExample {public static void main(String[] args) {Properties properties = new Properties();properties.put("bootstrap.servers", "localhost:9092");properties.put("acks", "all");properties.put("retries", 0);properties.put("batch.size", 16384);properties.put("linger.ms", 1);properties.put("buffer.memory", 33554432);properties.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer");properties.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer");Producer<String, String> producer = new KafkaProducer<>(properties);for (int i = 0; i < 100; i++) {ProducerRecord<String, String> record = new ProducerRecord<>("test-topic", Integer.toString(i), "message " + i);producer.send(record);}producer.close();}
}

代码解释:

  • properties 中设置了生产者的各种配置,包括 bootstrap.servers 指定 Kafka 集群的地址,acks 确定消息确认机制,batch.size 决定消息的批次大小,linger.ms 决定消息的延迟发送时间,buffer.memory 是消息缓冲区的大小。

KafkaProducer 类是 Kafka 的生产者类,通过 send() 方法发送 ProducerRecord 消息,消息包含主题、键和值。这里将消息发送到 test-topic 主题,键为 i 的字符串表示,值为 message + i。

2. 消费者代码示例
import org.apache.kafka.clients.consumer.Consumer;
import org.apache.kafka.clients.consumer.ConsumerRecords;
import org.apache.kafka.clients.consumer.KafkaConsumer;
import java.util.Collections;
import java.util.Properties;public class KafkaConsumerExample {public static void main(String[] args) {Properties properties = new org.apache.kafka.clients.consumer.Properties();properties.put("bootstrap.servers", "localhost:9092");properties.put("group.id", "test-group");properties.put("enable.auto.commit", "true");properties.put("auto.commit.interval.ms", "1000");properties.put("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");properties.put("value.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");Consumer<String, String> consumer = new KafkaConsumer<>(properties);consumer.subscribe(Collections.singletonList("test-topic"));while (true) {ConsumerRecords<String, String> records = consumer.poll(100);records.forEach(record -> System.out.printf("offset = %d, key = %s, value = %s%n", record.offset(), record.key(), record.value()));}}
}

代码解释:

  • properties 中设置了消费者的各种配置,包括 bootstrap.servers 用于连接 Kafka 集群,group.id 表示消费者组的 ID,enable.auto.commit 表示是否自动提交消费偏移量,auto.commit.interval.ms 表示自动提交的时间间隔。

KafkaConsumer 类是消费者类,通过 subscribe() 方法订阅主题,使用 poll() 方法拉取消息,拉取到的消息存储在 ConsumerRecords 中,然后遍历并打印消息的偏移量、键和值。

(三)分区机制

1. 概念

分区是 Kafka对主题的进一步划分,将主题的数据分布在多个分区中,提高了并行处理能力。每个分区内的消息是有序的,但不同分区之间的消息顺序不保证。在DefaultPartitioner 类中,会根据不同的分区策略(如轮询、按消息键的哈希值等)将消息分配到不同的分区。

2. 实现原理

  • 在 ProducerRecord 中,如果没有指定分区,会使用 partitioner 类进行分区分配,例如,在 DefaultPartitioner 中,当使用轮询策略时,会根据递增的计数器将消息分配到不同分区;当使用哈希策略时,会根据消息键的哈希值对分区数取模来分配分区。

3. 性能

  • 分区可以提高 Kafka 的并行处理能力,多个生产者可以同时向不同的分区发送消息,多个消费者可以同时从不同的分区消费消息,提高了系统的吞吐量。在性能测试中,增加分区数可以在一定程度上提高系统的并发处理能力,但也会增加管理成本,过多的分区可能导致性能下降,需要根据实际情况进行调整。

(四)副本机制

1. 概念

  • 副本是为了保证数据的高可用性,每个分区可以有多个副本,分布在不同的 Broker上,其中一个是领导者(Leader),其余为跟随者(Follower)。

2. 实现原理

  • 在 ReplicaManager 类中,当消息发送到 Leader 副本时,Leader 会将消息复制给 Follower 副本,Follower 副本会不断从 Leader 副本同步消息。当 Leader 副本不可用时,会从 Follower 副本中选举出一个新的 Leader 副本。在 Partition 类中,makeLeader() 和 makeFollower() 方法负责角色的转换,确保消息的一致性和可用性。

3. 性能

  • 副本机制提高了 Kafka 的可用性,但也会增加网络和存储的开销,因为需要将消息复制到多个副本上。不过,在实际使用中,合理设置副本数可以在性能和可用性之间取得平衡,一般副本数为 2 或 3 比较常见。
    (五)消息的顺序性和高可用性
1. 消息顺序性
  • 在同一个分区内,Kafka 可以保证消息的顺序性,因为消息是按顺序追加存储的。生产者发送消息时,尽量将有顺序要求的消息发送到同一个分区,例如,在日志收集场景中,同一个服务的日志可以发送到同一个分区,保证日志的时间顺序。
  • 从源码角度,在 RecordBatch 类中,会将同一批次的消息存储在一个逻辑单元中,在发送到分区时会按顺序存储,保证了分区内消息的顺序性。
2. 高可用性
  • 高可用性通过副本机制、Broker 的故障转移和 ZooKeeper 的协调来保证。当 Broker 出现故障时,ZooKeeper 会通知 Kafka 集群,Kafka 会从 Follower 副本中选举新的 Leader,在 KafkaController 类中,onBrokerFailure() 方法会触发故障处理流程,确保服务的正常运行。

三、Kafka 的性能优化

(一)调整参数

1. 生产者参数优化
batch.size 和 linger.ms:
  • 增大 batch.size 可以将更多的消息打包成批次发送,减少网络请求次数,提高网络 I/O 效率;增加 linger.ms 可以延迟发送消息,让生产者有更多的时间收集消息形成批次。但如果设置过大,会增加消息的延迟,需要根据消息的流量和实时性要求进行调整。在 RecordAccumulator 类中,会根据这些参数来决定何时发送消息批次。
acks 和 retries:
  • acks 决定了消息发送的确认机制,设置为 all 可以保证消息的可靠性,但会增加发送延迟,可根据对消息可靠性的要求进行调整;retries 决定了发送失败时的重试次数,可根据网络状况和服务器的稳定性设置。
2. 消费者参数优化
fetch.min.bytes 和 fetch.max.wait.ms:
  • fetch.min.bytes 规定了消费者每次拉取的最小字节数,fetch.max.wait.ms 规定了消费者拉取消息的最大等待时间,合理设置可以提高消费者的拉取效率。在 Fetcher 类中,会根据这些参数来拉取消息,平衡消息的延迟和吞吐量。
3. Broker 参数优化
num.io.threads 和 num.replica.fetchers:
  • num.io.threads 决定了 Broker 处理网络 I/O 请求的线程数量,num.replica.fetchers 决定了副本同步的线程数量,根据服务器的 CPU 核心数和负载,可以调整这些参数以优化性能。在 KafkaServer 类中,会根据这些参数启动相应的线程。

(二)优化网络

  • 调整网络缓冲区:
    可以调整 Kafka 的网络缓冲区大小,在 SocketServer 类中,通过设置 socket.send.buffer.bytes 和 socket.receive.buffer.bytes 来优化网络发送和接收缓冲区的大小,提高网络传输效率。
  • 使用压缩:
    可以使用压缩算法(如 GZIP、Snappy 等)对消息进行压缩,在 ProducerConfig 中设置 compression.type 参数,减少网络传输的数据量,提高性能。

(三)与其他大数据组件的集成

1. 与 Spark 的集成

可以使用 Spark Streaming 从 Kafka 中消费数据,以下是一个简单的代码示例:

import org.apache.spark.SparkConf;
import org.apache.spark.streaming.Durations;
import org.apache.spark.streaming.api.java.JavaDStream;
import org.apache.spark.streaming.api.java.JavaStreamingContext;
import org.apache.spark.streaming.kafka010.ConsumerStrategies;
import org.apache.spark.streaming.kafka010.KafkaUtils;
import org.apache.spark.streaming.kafka010.LocationStrategies;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;public class SparkKafkaIntegration {public static void main(String[] args) {SparkConf conf = new SparkConf().setAppName("SparkKafkaIntegration").setMaster("local[2]");JavaStreamingContext jssc = new JavaStreamingContext(conf, Durations.seconds(1));Map<String, Object> kafkaParams = new HashMap<>();kafkaParams.put("bootstrap.servers", "localhost:9092");kafkaParams.put("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");kafkaParams.put("value.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");kafkaParams.put("group.id", "spark-group");kafkaParams.put("auto.offset.reset", "latest");kafkaParams.put("enable.auto.commit", false);JavaDStream<String> stream = KafkaUtils.createDirectStream(jssc,LocationStrategies.PreferConsistent(),ConsumerStrategies.Subscribe(Collections.singletonList("test-topic"), kafkaParams)).map(record -> record.value());stream.foreachRDD(rdd -> {rdd.foreach(record -> {// 在这里对从 Kafka 中获取的数据进行处理,例如打印或其他计算操作System.out.println(record);});});jssc.start();try {jssc.awaitTermination();} catch (InterruptedException e) {e.printStackTrace();}}
}

代码解释:

  • SparkConf 用于配置 Spark 应用程序,这里设置了应用程序名称和运行模式(local[2] 表示本地模式,使用 2 个线程)。
  • JavaStreamingContext 是 Spark Streaming 的上下文,设置了批处理的时间间隔为 1 秒。
  • kafkaParams 包含了连接 Kafka 所需的参数,如 Kafka 集群地址、键和值的反序列化器、消费者组 ID 等。
  • KafkaUtils.createDirectStream 方法创建了一个直接从 Kafka 接收数据的流,使用LocationStrategies.PreferConsistent() 表示数据在可用执行器之间均匀分配,使用 ConsumerStrategies.Subscribe 方法订阅 test-topic 主题。
  • map 操作将从 Kafka 获取的 ConsumerRecord 转换为消息的值。
  • foreachRDD 操作在每个 RDD 上执行操作,这里简单地将消息打印出来。
2. 与 Fluentd 的集成

Fluentd 是一个日志收集工具,可以将收集到的日志发送给 Kafka。

首先需要在 Fluentd 的配置文件中添加 Kafka 的输出插件,如下是一个简单的配置示例:

<source>@type forwardport 24224
</source><match kafka.**>@type kafkabrokers localhost:9092topic_key topicdefault_topic logsoutput_data_type jsonrequired_acks 1<buffer>flush_interval 5s</buffer>
</match>

解释:

  • 部分配置了 Fluentd 接收日志的源,这里使用 forward 类型接收来自其他服务的日志。
  • <match kafka.**> 部分配置了将日志发送到 Kafka,指定了 Kafka 的 brokers 地址,default_topic 为 logs,表示将日志发送到 logs 主题,output_data_type 为 json 表示日志以 JSON 格式发送,required_acks 表示消息的确认机制, 部分设置了消息的刷新间隔。

四、实际项目案例演示 Kafka 在大规模数据处理场景中的应用

(一)案例背景

假设我们有一个大型电商平台,需要处理大量的用户行为数据,包括用户的浏览、点击、购买等行为。这些数据需要实时处理和分析,以便为用户提供个性化推荐、统计分析等功能。

(二)架构设计

  • 数据采集:在电商平台的各个服务中,使用 Kafka 的生产者将用户行为数据发送到 Kafka 的 user-behavior 主题,根据用户的 ID 或行为类型将数据发送到不同的分区,以保证同一用户或同一类型的行为数据在同一分区内,保证数据的局部顺序性。
  • 数据处理:使用 Spark Streaming 从 Kafka 中消费数据,将数据进行清洗、转换和分析。对于用户的浏览数据,可以计算用户的浏览偏好;对于购买数据,可以更新库存和统计销售额等。
  • 数据存储和展示:处理后的数据存储在数据库(如 HBase 或 Cassandra)中,同时使用可视化工具(如 Grafana)展示统计结果。

(三)代码示例

1. 生产者(在电商服务中)
import org.apache.kafka.clients.producer.KafkaProducer;
import org.apache.kafka.clients.producer.Producer;
import org.apache.kafka.clients.producer.ProducerRecord;
import java.util.Properties;public class EcommerceProducer {private static final String TOPIC = "user-behavior";private Producer<String, String> producer;public EcommerceProducer() {Properties properties = new Properties();properties.put("bootstrap.servers", "kafka-broker1:9092,kafka-broker2:9092");properties.put("acks", "all");properties.put("retries", 0);properties.put("batch.size", 16384);properties.put("linger.ms", 1);properties.put("buffer.memory", 33554432);properties.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer");properties.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer");producer = new KafkaProducer<>(properties);}public void sendUserBehavior(String userId, String behavior, String data) {String key = userId; String value = behavior + ":" + data;ProducerRecord<String, String> record = new ProducerRecord<>(TOPIC, key, value);producer.send(record);}public void close() {producer.close();}
}

代码解释:
该生产者类将用户行为数据发送到 user-behavior 主题,根据用户 ID 作为键,将用户行为和相关数据作为值发送消息。
配置参数同之前的生产者示例,确保消息的可靠性和发送性能。

2. 消费者(Spark Streaming)
import org.apache.spark.SparkConf;
import org.apache.spark.streaming.Durations;
import org.apache.spark.streaming.api.java.JavaDStream;
import org.apache.spark.streaming.api.java.JavaStreamingContext;
import org.apache.spark.streaming.kafka010.ConsumerStrategies;
import org.apache.spark.streaming.kafka010.KafkaUtils;
import org.apache.spark.streaming.kafka010.LocationStrategies;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;public class EcommerceConsumer {public static void main(String[] args) {SparkConf conf = new SparkConf().setAppName("EcommerceConsumer").setMaster("local[4]");JavaStreamingContext jssc = new JavaStreamingContext(conf, Durations.seconds(5));Map<String, Object> kafkaParams = new HashMap<>();kafkaParams.put("bootstrap.servers", "kafka-broker1:9092,kafka-broker2:9092");kafkaParams.put("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");kafkaParams.put("value.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");kafkaParams.put("group.id", "ecommerce-group");kafkaParams.put("auto.offset.reset", "latest");kafkaParams.put("enable.auto.commit", false);JavaDStream<String> stream = KafkaUtils.createDirectStream(jssc,LocationStrategies.PreferConsistent(),ConsumerStrategies.Subscribe(Collections.singletonList("user-behavior"), kafkaParams)).map(record -> record.value());stream.foreachRDD(rdd -> {rdd.foreachPartition(partition -> {while (partition.hasNext()) {String behaviorData = partition.next();// 对用户行为数据进行处理,例如解析数据,进行统计分析等processBehaviorData(behaviorData);}});});jssc.start();try {jssc.awaitTermination();} catch (InterruptedException e) {e.printStackTrace();}}private static void processBehaviorData(String behaviorData) {// 这里可以根据具体业务需求进行数据的处理,例如解析数据,更新库存,计算用户偏好等System.out.println("Processing behavior data: " + behaviorData);}
}

代码解释:

  • EcommerceConsumer 从 user-behavior 主题中消费数据,使用 Spark Streaming 进行处理。
  • kafkaParams 包含了连接 Kafka 的参数,包括集群地址、反序列化器、消费者组等。
  • KafkaUtils.createDirectStream 创建了直接从 Kafka 接收数据的流,订阅了 user-behavior 主题。
  • foreachRDD 操作在每个 RDD 上进行处理,这里使用 foreachPartition 对每个分区的数据进行处理,processBehaviorData 方法可以根据具体业务需求进行用户行为数据的处理,如解析数据、更新库存、计算用户偏好等。

(四)性能优化和测试

性能测试:
  • 使用 JMeter 等工具模拟大量的用户行为数据发送,测试 Kafka 的生产者性能,观察消息发送的延迟和吞吐量。使用 Spark 的性能测试工具测试 Spark Streaming 的处理性能,观察数据处理的延迟和吞吐量。
性能优化:
  • 根据测试结果调整 Kafka 的生产者和消费者参数,如增加 batch.size 或 linger.ms 提高生产者性能,调整 fetch.min.bytes 等参数提高消费者性能。
  • 调整 Spark 的参数,如增加 spark.executor.instances 和 spark.executor.cores 提高 Spark 的处理能力。
(五)总结

通过上述的架构设计和代码实现,我们展示了 Kafka 在大规模数据处理场景中的应用。Kafka 作为一个强大的消息队列系统,通过其高吞吐量、可扩展性、高可用性等特点,结合 Spark 等大数据处理组件,可以有效地处理海量的实时数据。在实际应用中,需要根据具体的业务需求和性能测试结果,不断优化 Kafka 的参数和与其他组件的集成方式,以达到最佳的性能和数据处理效果。同时,需要关注 Kafka 的核心架构,如分区机制、副本机制,以保证数据的顺序性和可用性。

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

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

相关文章

Unity-Mirror网络框架-从入门到精通之Basic示例

文章目录 前言Basic示例场景元素预制体元素代码逻辑BasicNetManagerPlayer逻辑SyncVars属性Server逻辑Client逻辑 PlayerUI逻辑 最后 前言 在现代游戏开发中&#xff0c;网络功能日益成为提升游戏体验的关键组成部分。Mirror是一个用于Unity的开源网络框架&#xff0c;专为多人…

AIA - APLIC之二

本文属于《 RISC-V指令集基础系列教程》之一,欢迎查看其它文章。 对于APLIC实现的每一个中断域,都存在一个独享的内存映射的控制区域,用来处理该中断域的中断。 该控制区域大小是由4KB的倍数,并与4KB地址边界对齐,最小的有效控制区域是16KB。 接下来,本文将详细讲解,AP…

设计模式之访问者模式:一楼千面 各有玄机

~犬&#x1f4f0;余~ “我欲贱而贵&#xff0c;愚而智&#xff0c;贫而富&#xff0c;可乎&#xff1f; 曰&#xff1a;其唯学乎” 一、访问者模式概述 \quad 江湖中有一个传说&#xff1a;在遥远的东方&#xff0c;有一座神秘的玉楼。每当武林中人来访&#xff0c;楼中的各个房…

SAP月结、年结前重点检查事项(后勤与财务模块)

文章目录 一、PP生产模块相关的事务检查二、SD销售模块相关的事务检查:三、MM物料管理模块相关的事务检查四、FICO财务模块相关的事务检查五、年结前若干注意事项【SAP系统PP模块研究】 #SAP #生产订单 #月结 #年结 一、PP生产模块相关的事务检查 1、月末盘点后,生产用料的…

JVM实战—6.频繁YGC和频繁FGC的后果

大纲 1.JVM GC导致系统突然卡死无法访问 2.什么是Young GC什么是Full GC 3.Young GC、Old GC和Full GC的发生情况 4.频繁YGC的案例(G1解决大内存YGC过慢) 5.频繁FGC的案例(YGC存活对象S区放不下) 6.问题汇总 1.JVM GC导致系统突然卡死无法访问 (1)基于JVM运行的系统最怕…

蓝牙|软件 Qualcomm S7 Sound Platform开发系列之初级入门指南

本文适用范围 ADK24.2~ 问题/功能描述 S7开发环境搭建与编译介绍 实现方案 本文介绍适用于windows平台Application部分,audio ss的说明会在下一篇文章在做说明,Linux平台如果不进行AI算法的开发,个人认知是没有必要配置,若是做服务器倒是不错的选择.因为编译完成后烧录调试还…

LabVIEW冷却风机性能测试系统

开发了基于LabVIEW软件及LabSQL工具包的冷却风机性能测试系统。系统通过高效的数据库访问技术&#xff0c;实现了对冷却风机测试过程中关键性能数据的采集、存储与管理&#xff0c;优化了测试流程并提升了数据处理的效率。 ​ 项目背景 在工业生产和科研测试中&#xff0c;准…

C 实现植物大战僵尸(四)

C 实现植物大战僵尸&#xff08;四&#xff09; C 实现植物大战僵尸&#xff0c;完结撒花&#xff08;还有个音频稍卡顿的性能问题&#xff0c;待有空优化解决&#xff09;。目前基本的功能模块已经搭建好了&#xff0c;感兴趣的友友可自行尝试编写后续游戏内容 因为 C 站不能…

车间管理:掌握方法,有效应对浪费

在制造企业中&#xff0c;车间的有效管理对于提高生产效率、降低成本以及提升产品质量至关重要&#xff0c;然而面对外部激烈的市场竞争&#xff0c;利润微薄&#xff0c;内部车间却充满了各种浪费&#xff0c;企业管理者头痛不已&#xff0c;如果能有效改进内部车间浪费&#…

Logo设计免费生成器工具:轻松创建独特标志

在当今的商业世界中&#xff0c;一个独特且引人注目的Logo是任何企业或品牌的身份象征。它不仅代表了公司的形象&#xff0c;还传达了公司的价值观和使命。然而&#xff0c;对于许多初创企业或小型企业来说&#xff0c;聘请专业设计师来设计一个Logo可能是一笔不小的开销。这时…

【智行安全】基于Synaptics SL1680的AI疲劳驾驶检测方案

随著车载技术的快速进步&#xff0c;驾驶安全越来越受到重视&#xff0c;而疲劳驾驶是造成交通事故的重要原因之一。传统的驾驶监控技术因精度不足或反应迟缓&#xff0c;无法满足实时监测需求。因此&#xff0c;结合人工智能技术的疲劳驾驶检测系统成为行业新方向&#xff0c;…

uni-ui样式修改

因为之前官网uni-ui有些组件的样式不好看&#xff0c;所以要做一些调整&#xff0c;做个记录。用分段器举例~ 官网原生样式 调整后的 首先找到我们的static文件夹&#xff0c;里面一般存着项目的全局样式文件&#xff0c;没有的话自己创一个 uniui.scss /deep/ .segmented-con…

大模型WebUI:Gradio全解系列9——Additional Features:补充特性(下)

大模型WebUI&#xff1a;Gradio全解系列9——Additional Features&#xff1a;补充特性&#xff08;下&#xff09; 前言本篇摘要8. Additional Features&#xff1a;补充特性8.5 分享demo8.5.1 嵌入托管 Spaces8.5.2 使用 Web Components 嵌入8.5.3 Embedding with IFrames 8.…

计算机网络 (17)点对点协议PPP

一、PPP协议的基本概念 PPP协议最初设计是为两个对等节点之间的IP流量传输提供一种封装协议&#xff0c;它替代了原来非标准的第二层协议&#xff08;如SLIP&#xff09;。在TCP/IP协议集中&#xff0c;PPP是一种用来同步调制连接的数据链路层协议&#xff08;OSI模式中的第二层…

HTML5滑块(Slider)

HTML5 的滑块&#xff08;Slider&#xff09;控件允许用户通过拖动滑块来选择数值。以下是如何实现一个简单的滑块组件的详细说明。 HTML5 滑块组件 1. 基本结构 使用 <input type"range"> 元素可以创建一个滑块。下面是基本实现的代码示例&#xff1a; <…

在Linux上获取MS(如Media Server)中的RTP流并录制为双轨PCM格式的WAV文件

在Linux上获取MS(如Media Server)中的RTP流并录制为双轨PCM格式的WAV文件 一、RTP流与WAV文件格式二、实现步骤三、伪代码示例四、C语言示例代码五、关键点说明六、总结在Linux操作系统上,从媒体服务器(如Media Server,简称MS)获取RTP(Real-time Transport Protocol)流…

Unity3D仿星露谷物语开发12之创建道具列表

1、目标 道具是游戏的核心部分&#xff0c;道具包括你可以拾取的东西&#xff0c;你可以使用的工具和你能种的东西等。 本节就是创建道具的信息类。同时了解ScriptableObject类的使用。 2、创建道具枚举类 修改Assets -> Scripts -> Enums.cs脚本&#xff0c; 新增如…

华为云Welink数据怎么连接到小满CRM?

Welink是什么&#xff1f;好用吗&#xff1f; 华为云WeLink是华为内部打磨多年的协同办公平台、远程办公软件、移动办公平台、协同办公软件&#xff0c;来源华为19万员工的数字化办公实践&#xff0c;融合多屏协同、打卡、报销、考勤、审批、企业网盘、IM消息、邮件、视频会议…

借助 FinClip 跨端技术探索鸿蒙原生应用开发之旅

在当今数字化浪潮汹涌澎湃的时代&#xff0c;移动应用开发领域正经历着深刻的变革与创新。鸿蒙操作系统的崛起&#xff0c;以其独特的分布式架构和强大的性能表现&#xff0c;吸引了众多开发者的目光。而FinClip 跨端技术的出现&#xff0c;为开发者涉足鸿蒙原生应用开发提供了…

IDEA+Docker一键部署项目SpringBoot项目

文章目录 1. 部署项目的传统方式2. 前置工作3. SSH配置4. 连接Docker守护进程5. 创建简单的SpringBoot应用程序6. 编写Dockerfile文件7. 配置远程部署 7.1 创建配置7.2 绑定端口7.3 添加执行前要运行的任务 8. 部署项目9. 开放防火墙的 11020 端口10. 访问项目11. 可能遇到的问…