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

关于SpringBoot集成Kafka

关于Kafka

Apache Kafka 是一个分布式流处理平台,广泛用于构建实时数据管道和流应用。它能够处理大量的数据流,具有高吞吐量、可持久化存储、容错性和扩展性等特性。

Kafka一般用作实时数据流处理、消息队列、事件架构驱动等

Kafka的整体架构

  • ZooKeeper:

位于架构的顶部,负责管理和协调 Kafka 集群的各种元数据,包括集群配置、主题信息、分区领导者的选举等。

  • Producers (生产者):

Kafka体系中的主要角色之一,它们负责产生消息并将其发送到 Kafka 集群中的相应主题。

  • Brokers (代理/服务器):节点,也就是具体的Kafka实例,集群的组成单元,多个 Broker 组成一个集群。每个 Broker 存储着一部分主题的分区数据。
    • Topics (主题):主题是消息的类别,生产者将消息发布到特定的主题。一个Brokers包含多个topic。
      • Partitions (分区):每个主题可以划分为一个或多个分区,分区是物理上存储消息的地方。一个主题可以有多个分区
        • Leaders and Followers (领导者和跟随者):对于每个分区,有一个 Leader 负责接受所有生产和消费请求,而 Follower 则复制 Leader (图中红色部分)的数据。
        • Segments (段): 分区内部又细分为多个 Segment,每个 Segment 包括一个 .log 文件和其他相关文件,用于消息数据持久化。 
  • Consumers (消费者):

Kafka体系中的另一个主要角色,它们订阅主题并从 Kafka 集群中拉取消息。消费者可以组织成消费者组,同一组内的消费者共享消息。

Kafka的工作流程

  • 消息发布

生产者创建消息并将它们发送到指定的主题。生产者可以选择将消息发送到特定的分区,或者让 Kafka 根据某种策略(如轮询、哈希等)自动选择分区。

  • 消息存储

当消息到达Broker时,它会被追加到指定分区的日志文件末尾。每个分区都是一个独立的日志文件,按照偏移量(Offset)进行索引,确保消息的顺序性。

  • 消息消费

消费者订阅感兴趣的主题,并从指定的分区读取消息。消费者通过维护一个偏移量来跟踪已经处理的消息,确保不会重复消费。

  • 故障恢复

如果Broker发生故障,Kafka会从其他副本中选举一个新的Leader分区来继续提供服务,确保系统的高可用性。 

SpringBoot集成Kafka

引入依赖

在SpringBoot框架下,可以直接通过引入Kafka依

    <!-- Spring Kafka Starter --><dependency><groupId>org.springframework.kafka</groupId><artifactId>spring-kafka</artifactId></dependency>

yaml配置详解

关于SpringBoot中使用Kafka的配置结构如下:

spring:kafka:bootstrap-servers: localhost:9092  # Kafka整体配置:服务器地址,可以是多个以逗号分隔consumer: #作为消费者的具体配置group-id: my-group # 消费者的组ID,属于同一组的消费者会互相竞争消费消息# …… 消费者其他的配置producer: #作为生产者的具体配置value-serializer: org.apache.kafka.common.serialization.StringSerializer # 值的序列化器#……其他控制生产者的配置

各类参数配置说明:

归属配置项说明默认值作用
全局bootstrap-servers指定Kafka集群的地址,可以是多个地址,用逗号分隔-生产者和消费者通过这些地址与Kafka集群建立连接
消费者consumer.group-id指定消费者的组ID-属于同一组的消费者会互相竞争消费消息,确保每个消息只被组内的一个消费者消费
consumer.auto-offset-reset当没有初始偏移量可用或当前偏移量不再存在时,自动重置偏移量的策略latest决定了在消费者组没有已知偏移量时,从哪里开始读取消息
consumer.key-deserializer指定键的反序列化器org.apache.kafka.common.serialization.ByteArrayDeserializer将从Kafka接收到的字节数据转换为Java对象
consumer.value-deserializer指定值的反序列化器org.apache.kafka.common.serialization.ByteArrayDeserializer将从Kafka接收到的字节数据转换为Java对象
consumer.enable-auto-commit是否启用自动提交偏移量true如果启用,消费者会定期自动提交偏移量,否则需要手动提交
consumer.auto-commit-interval自动提交偏移量的时间间隔(毫秒)5000(5秒)控制自动提交的频率
consumer.max-poll-records单次轮询返回的最大记录数500控制每次轮询从Kafka获取的消息数量
consumer.fetch-min-bytes消费者从Kafka获取数据的最小字节数1如果小于该值,Kafka不会立即返回数据,而是等待更多数据积累
consumer.fetch-max-wait消费者从Kafka获取数据的最大等待时间(毫秒)500控制消费者在没有足够数据时的等待时间
consumer.session-timeout消费者会话超时时间(毫秒)10000(10秒)控制消费者在未发送心跳的情况下,Kafka认为其失效的时间
生产者producer.key-serializer指定键的序列化器org.apache.kafka.common.serialization.ByteArraySerializer将Java对象转换为字节数据,以便发送到Kafka
producer.value-serializer指定值的序列化器org.apache.kafka.common.serialization.ByteArraySerializer将Java对象转换为字节数据,以便发送到Kafka
producer.acks生产者发送消息时的确认模式1控制消息发送的可靠性
producer.retries生产者发送消息失败时的重试次数0控制消息发送失败时的重试机制
producer.batch-size生产者批量发送消息的大小(字节)16384(16KB)控制消息的批量发送,提高性能
producer.linger-ms生产者在发送消息前等待的时间(毫秒),以便收集更多的消息进行批量发送0控制消息的批量发送,提高性能

示例配置

spring:kafka:# 指定Kafka集群的地址,可以是多个地址,用逗号分隔# 生产者和消费者通过这些地址与Kafka集群建立连接bootstrap-servers: localhost:9092consumer:# 指定消费者的组ID# 属于同一组的消费者会互相竞争消费消息,确保每个消息只被组内的一个消费者消费group-id: my-group# 当没有初始偏移量可用或当前偏移量不再存在时,自动重置偏移量的策略# 可选值: earliest, latest, none# earliest: 自动重置为最早的偏移量# latest: 自动重置为最新的偏移量# none: 如果没有找到消费者组的偏移量,则抛出异常auto-offset-reset: earliest# 指定键的反序列化器# 将从Kafka接收到的字节数据转换为Java对象key-deserializer: org.apache.kafka.common.serialization.StringDeserializer# 指定值的反序列化器# 将从Kafka接收到的字节数据转换为Java对象value-deserializer: org.apache.kafka.common.serialization.StringDeserializer# 是否启用自动提交偏移量# 如果启用,消费者会定期自动提交偏移量,否则需要手动提交enable-auto-commit: true# 自动提交偏移量的时间间隔(毫秒)# 控制自动提交的频率auto-commit-interval: 5000# 单次轮询返回的最大记录数# 控制每次轮询从Kafka获取的消息数量max-poll-records: 100# 消费者从Kafka获取数据的最小字节数# 如果小于该值,Kafka不会立即返回数据,而是等待更多数据积累fetch-min-bytes: 1# 消费者从Kafka获取数据的最大等待时间(毫秒)# 控制消费者在没有足够数据时的等待时间fetch-max-wait: 500# 消费者会话超时时间(毫秒)# 控制消费者在未发送心跳的情况下,Kafka认为其失效的时间session-timeout: 10000producer:# 指定键的序列化器# 将Java对象转换为字节数据,以便发送到Kafkakey-serializer: org.apache.kafka.common.serialization.StringSerializer# 指定值的序列化器# 将Java对象转换为字节数据,以便发送到Kafkavalue-serializer: org.apache.kafka.common.serialization.StringSerializer# 生产者发送消息时的确认模式# 可选值: 0, 1, all# 0: 不等待任何确认# 1: 等待leader节点确认# all: 等待所有副本节点确认acks: all# 生产者发送消息失败时的重试次数# 控制消息发送失败时的重试机制retries: 3# 生产者批量发送消息的大小(字节)# 控制消息的批量发送,提高性能batch-size: 16384# 生产者在发送消息前等待的时间(毫秒),以便收集更多的消息进行批量发送# 控制消息的批量发送,提高性能linger-ms: 1

关于消费者的 auto-commit属性:

enable-auto-commit 是Kafka消费者的一个重要配置属性,它决定了消费者是否自动提交偏移量。

如果设置为true,即自动提交:

  • 消费者会定期自动提交偏移量。
  • 提交的频率由 auto-commit-interval 配置项决定,默认为5秒。
  • 消费者在每次轮询后会检查是否需要提交偏移量,如果达到提交间隔时间,则提交当前偏移量。

设置为true的优势主要在于简化开发,如果消费者崩溃,重新启动后可以从上次提交的偏移量继续消费,避免重复消费大量消息。劣势则是自动提交的频率在处理大数据量是会有性能风险。

如果设置为false,即手动提交:

  • 消费者不会自动提交偏移量。
  • 开发者需要手动调用方法来提交偏移量(具体提交方法在下文)
  • 可以在消息处理完成后立即提交偏移量,也可以批量提交。

设置为false的优势在于更为精准的控制,能有效提升性能,开发者可以完全控制何时提交偏移量,确保消息处理的可靠性和一致性。可以根据业务需求选择同步提交或异步提交,具有更强的灵活性。劣势则是如果忘记提交偏移量,可能会导致消息重复消费或丢失。

消费与生成的使用

进行消息监听与消费

消息的监听主要是通过@KafkaListener注解来完成,以下是一个例子:

@Service
public class KafkaConsumer {@Autowiredprivate DataService dataService;@KafkaListener(topics = "my-topic", groupId = "my-group")public void listen(String message) {//如果你的方法参数是一个 String 类型,那么默认情况下,这个参数会被解析为消息的值(Value)log.info("Received Message: {}" , message);dataService.OpData(message); }//如果你想同时获取消息的键(Key)和值(Value),可以使用 ConsumerRecord 对象。ConsumerRecord 包含了消息的所有信息,包括键、值、分区、偏移量等。@KafkaListener(topics = "my-topic")public void listen(ConsumerRecord<String, String> record) {log.info("Received Message Key: " + record.key());log.info("Received Message Value: " + record.value());log.info("Partition: " + record.partition());log.info("Offset: " + record.offset());}}

关于@KafkaListener注解的参数如下:

参数类型说明示例
topicsString[]指定要监听的主题列表。@KafkaListener(topics = "my-topic")
topicPartitionsTopicPartitionOffset[]指定要监听的主题和分区。可以用于更细粒度的控制。@KafkaListener(topicPartitions = @TopicPartition(topic = "my-topic", partitions = { "0", "1" }))
groupIdString指定消费者的组ID。如果在配置文件中已经指定了组ID,这里可以省略。@KafkaListener(topics = "my-topic", groupId = "my-group")
containerFactoryString指定用于创建监听器容器的工厂Bean的名称。通常在配置类中定义。@KafkaListener(topics = "my-topic", containerFactory = "kafkaListenerContainerFactory")
idString指定监听器的唯一标识符。可以在监控和管理中使用。@KafkaListener(topics = "my-topic", id = "myListener")
concurrencyString指定并发消费者线程的数量。@KafkaListener(topics = "my-topic", concurrency = "3")
autoStartupboolean指定监听器是否在应用程序启动时自动启动。@KafkaListener(topics = "my-topic", autoStartup = "false")
propertiesMap<String, String>指定额外的Kafka消费者属性。@KafkaListener(topics = "my-topic", properties = "max.poll.interval.ms:120000")
groupIdPrefixString指定组ID的前缀。实际的组ID将是前缀加上方法名。@KafkaListener(topics = "my-topic", groupIdPrefix = "prefix-")
clientIdPrefixString指定客户端ID的前缀。实际的客户端ID将是前缀加上方法名。@KafkaListener(topics = "my-topic", clientIdPrefix = "client-")
containerPropertiesContainerProperties指定容器的属性。@KafkaListener(topics = "my-topic", containerProperties = @ContainerProperties(ackMode = AckMode.MANUAL))
errorHandlerString指定错误处理器Bean的名称。@KafkaListener(topics = "my-topic", errorHandler = "myErrorHandler")
replyTemplateString指定回复模板Bean的名称。@KafkaListener(topics = "my-topic", replyTemplate = "myReplyTemplate")
replyTopicString指定回复主题。@KafkaListener(topics = "my-topic", replyTopic = "reply-topic")
replyTimeoutlong指定回复超时时间(毫秒)。@KafkaListener(topics = "my-topic", replyTimeout = 5000)
replyHeadersString[]指定要传递的回复头。@KafkaListener(topics = "my-topic", replyHeaders = { "header1", "header2" })
groupIdIsolationLevelIsolationLevel指定隔离级别。@KafkaListener(topics = "my-topic", groupIdIsolationLevel = IsolationLevel.READ_COMMITTED)
containerGroupString指定容器组。@KafkaListener(topics = "my-topic", containerGroup = "group1")

 额外说明一下containerFactory 参数,为了使用 containerFactory 参数,你需要在配置类中定义相应的工厂Bean:


@Configuration
@EnableKafka
public class KafkaConfig {@Beanpublic ConsumerFactory<String, String> consumerFactory() {Map<String, Object> props = new HashMap<>();props.put(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092");props.put(ConsumerConfig.GROUP_ID_CONFIG, "my-group");props.put(ConsumerConfig.KEY_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class);props.put(ConsumerConfig.VALUE_DESERIALIZER_CLASS_CONFIG, StringDeserializer.class);return new DefaultKafkaConsumerFactory<>(props);}@Beanpublic ConcurrentKafkaListenerContainerFactory<String, String> kafkaListenerContainerFactory() {ConcurrentKafkaListenerContainerFactory<String, String> factory = new ConcurrentKafkaListenerContainerFactory<>();factory.setConsumerFactory(consumerFactory());factory.getContainerProperties().setAckMode(ContainerProperties.AckMode.MANUAL_IMMEDIATE);return factory;}
}

基于使用containerFactory配置一般主要用于手动提交的时候,可以在方法中使用提交参数,如下:

@Service
public class KafkaConsumer {@KafkaListener(topics = "my-topic",containerFactory = "kafkaListenerContainerFactory")public void listen(ConsumerRecord<String, String> record, Acknowledgment acknowledgment){log.info("Received Message: " + record.value());// 处理消息try {// 模拟消息处理Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}// 手动提交偏移量 enable-auto-commit为false的话acknowledgment.acknowledge();}
}

消息生产

主要是基于KafkaTemplate进行消息的发送,可以根据需求,先定义生产者的工厂Bean:

@Configuration
public class KafkaProducerConfig {@Beanpublic ProducerFactory<String, String> producerFactory() {Map<String, Object> configProps = new HashMap<>();configProps.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "localhost:9092");configProps.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, StringSerializer.class);configProps.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, StringSerializer.class);return new DefaultKafkaProducerFactory<>(configProps);}@Beanpublic KafkaTemplate<String, String> kafkaTemplate() {return new KafkaTemplate<>(producerFactory());}
}

 封装生产者方法:

@Service
public class KafkaProducer {@Autowiredprivate KafkaTemplate<String, String> kafkaTemplate;/*** 发送字符串消息到指定主题** @param topic   主题名称* @param message 消息内容*/public void sendMessage(String topic, String message) {kafkaTemplate.send(topic, message);}/*** 发送带键的字符串消息到指定主题** @param topic   主题名称* @param key     消息键* @param message 消息内容*/public void sendMessageWithKey(String topic, String key, String message) {kafkaTemplate.send(topic, key, message);}/*** 异步发送消息并处理回调** @param topic   主题名称* @param message 消息内容* @param callback 回调函数*/public void sendAsyncMessage(String topic, String message, KafkaCallback<String, String> callback) {kafkaTemplate.send(topic, message).addCallback(callback);}/*** 异步发送带键的消息并处理回调** @param topic   主题名称* @param key     消息键* @param message 消息内容* @param callback 回调函数*/public void sendAsyncMessageWithKey(String topic, String key, String message, KafkaCallback<String, String> callback) {kafkaTemplate.send(topic, key, message).addCallback(callback);}
}

为了支持异步发送消息并处理回调,定义回调不同的接口:

public interface KafkaCallback<K, V> extends ListenableFutureCallback<SendResult<K, V>> {@Overridedefault void onSuccess(SendResult<K, V> result) {//回调处理}@Overridedefault void onFailure(Throwable ex) {//处理}
}

 直接使用

@RestController
@RequestMapping("/kafka")
public class KafkaController {@Autowiredprivate KafkaProducerService kafkaProducerService;@PostMapping("/send")public String sendMessage(@RequestBody String message) {kafkaProducerService.sendMessage("my-topic", message);return "Message sent: " + message;}@PostMapping("/send-with-key")public String sendMessageWithKey(@RequestBody String message) {kafkaProducerService.sendMessageWithKey("my-topic", "key1", message);return "Message with key sent: " + message;}@PostMapping("/send-async")public String sendAsyncMessage(@RequestBody String message) {kafkaProducerService.sendAsyncMessage("my-topic", message, new KafkaCallback<String, String>());return "Async message sent: " + message;}@PostMapping("/send-async-with-key")public String sendAsyncMessageWithKey(@RequestBody String message) {kafkaProducerService.sendAsyncMessageWithKey("my-topic", "key1", message, new KafkaCallback<String, String>());return "Async message with key sent: " + message;}
}

相关文章:

关于SpringBoot集成Kafka

关于Kafka Apache Kafka 是一个分布式流处理平台&#xff0c;广泛用于构建实时数据管道和流应用。它能够处理大量的数据流&#xff0c;具有高吞吐量、可持久化存储、容错性和扩展性等特性。 Kafka一般用作实时数据流处理、消息队列、事件架构驱动等 Kafka的整体架构 ZooKeeper:…...

windows C#-取消任务列表(上)

如果不想等待异步控制台应用程序完成&#xff0c;可以取消该应用程序。 通过遵循本文的示例&#xff0c;可将取消添加到下载网站内容的应用程序。 可通过将 CancellationTokenSource 实例与每个任务进行关联来取消多个任务。 如果选择 Enter 键&#xff0c;则将取消所有尚未完成…...

RabbitMQ4:work模型

欢迎来到“雪碧聊技术”CSDN博客&#xff01; 在这里&#xff0c;您将踏入一个专注于Java开发技术的知识殿堂。无论您是Java编程的初学者&#xff0c;还是具有一定经验的开发者&#xff0c;相信我的博客都能为您提供宝贵的学习资源和实用技巧。作为您的技术向导&#xff0c;我将…...

《筑牢安全防线:培养 C++安全编程思维习惯之道》

在当今数字化飞速发展的时代&#xff0c;软件安全的重要性已提升到前所未有的高度。C作为一种广泛应用于系统开发、游戏制作、高性能计算等众多领域的编程语言&#xff0c;其程序的安全性更是关乎重大。培养 C安全编程的思维习惯&#xff0c;不仅是开发者个人能力提升的关键&am…...

Python Flask中集成SQLAlchemy和Flask-Login

在现代Web应用开发中,数据库和用户认证是两个非常重要的功能。Flask作为一个轻量级的Python Web框架,本身只提供了最基本的Web功能。但是,它可以通过集成各种优秀的扩展库来增强功能。本文将介绍如何在Flask应用中集成SQLAlchemy(数据库)和Flask-Login(用户认证),并提供一个完整…...

Kafka 生产者优化与数据处理经验

Kafka&#xff1a;分布式消息系统的核心原理与安装部署-CSDN博客 自定义 Kafka 脚本 kf-use.sh 的解析与功能与应用示例-CSDN博客 Kafka 生产者全面解析&#xff1a;从基础原理到高级实践-CSDN博客 Kafka 生产者优化与数据处理经验-CSDN博客 Kafka 工作流程解析&#xff1a…...

web——sqliabs靶场——第十二关——(基于错误的双引号 POST 型字符型变形的注入)

判断注入类型 a OR 1 1# 发现没有报错 &#xff0c;说明单引号不是闭合类型 测试别的注入条件 a) OR 1 1# a)) OR 1 1# a" OR 11 发现可以用双引号闭合 发现是")闭合 之后的流程还是与11关一样 爆破显示位 先抓包 是post传参&#xff0c;用hackbar来传参 unam…...

Spring |(二)IoC相关内容 | bean

文章目录 &#x1f4da;bean基础配置&#x1f407;bean的id和class&#x1f407;bean的name属性&#x1f407;bean作用范围scope配置&#x1f407;bean基础配置小结 &#x1f4da;bean实例化&#x1f407;构造方法实例化&#xff08;常用&#xff09;&#x1f407;静态工厂实例…...

flux的版本

1.flux1-dev.safetensors https://huggingface.co/black-forest-labs/FLUX.1-devhttps://huggingface.co/black-forest-labs/FLUX.1-dev原生的23.8G的模型。原生12B的模型,float16的。需要配合ae.safetensors,flux1-dev.safetensors以及clip-l和T5的权重使用,注意ae.sft和f…...

基于Springboot+Vue的房屋系统 (含源码数据库)

1.开发环境 开发系统:Windows10/11 架构模式:MVC/前后端分离 JDK版本: Java JDK1.8 开发工具:IDEA 数据库版本: mysql5.7或8.0 数据库可视化工具: navicat 服务器: SpringBoot自带 apache tomcat 主要技术: Java,Springboot,mybatis,mysql,vue 2.视频演示地址 3.功能 该系统…...

【Bluedroid】A2DP SINK播放流程源码分析

在Bluedroid协议栈中,A2DP(Advanced Audio Distribution Profile)SINK播放流程是一个复杂但有序的过程,它涉及多个层次和组件的交互。 一、概述 1.1. 初始化流程 在A2DP SINK播放之前,系统需要进行一系列初始化操作,以确保A2DP SINK服务能够正确运行。这些操作包括启动…...

【什么是Redis?】

Redis&#xff1a;高性能内存数据库的深度探索 在当今这个数据驱动的世界里&#xff0c;数据库的选择直接关系到应用程序的性能、可扩展性和可靠性。在众多数据库解决方案中&#xff0c;Redis以其卓越的性能、丰富的数据结构和灵活的使用场景脱颖而出&#xff0c;成为众多开发…...

TCL大数据面试题及参考答案

Mysql 索引失效的场景 对索引列进行运算或使用函数:当在索引列上进行数学运算、函数操作等,索引可能失效。例如,在存储年龄的列上建立了索引,若查询语句是 “SELECT * FROM table WHERE age + 1 = 20”,这里对索引列 age 进行了加法运算,数据库会放弃使用索引而进行全表扫…...

提高总线数据传输率

提高总线数据传输率是一个涉及多个方面的技术问题&#xff0c;以下是一些有效的方法&#xff1a; 一、提高总线时钟频率 总线时钟频率是影响总线传输速率的重要因素之一。通过提高总线时钟频率&#xff0c;可以缩短每个时钟周期的时间&#xff0c;从而在相同的时间内传输更多…...

_FYAW智能显示控制仪表的简单使用_串口通信

一、简介 该仪表可以实时显示位移传感器的测量值&#xff0c;并可设定阈值等。先谈谈简单的使用方法&#xff0c;通过说明书&#xff0c;我们可以知道长按SET键可以进入参数选择状态&#xff0c;按“↑”“↓”可以选择该组参数的上一个或者下一个参数。 从参数一览中可以看到有…...

图的遍历。

图的遍历这一部分&#xff0c;离不开广度优先和深度优先&#xff0c;如果大家已经学过搜索算法的话&#xff0c;这部分将是易如反掌。 万能搜索算法-CSDN博客 文章中不会提太多离散数学中图的专有名词&#xff0c;因为本篇博客只涉及最简单的图的遍历&#xff0c;故以练习题为主…...

Methode Electronics EDI 需求分析

Methode Electronics 是一家总部位于美国的全球性技术公司&#xff0c;专注于设计和制造用于多个行业的电子和电气组件&#xff0c;产品涵盖汽车、工业、电信、医疗设备以及消费电子等多个领域&#xff0c;提供创新的解决方案。 填写Methode_EDI_Parameters_Template Methode_…...

IT资产管理工具-NetBox

IT资产管理工具-NetBox 推荐一款IT资产管理工具 了解推荐阅读官方中文文档 https://docs.wangluohe.com/introduction/ 硬件要求 ​ - 建议4Core 8G以上&#xff0c;100G存储空间 这里我使用的Linux镜像为 CentOS8-Stream 提前关闭Selinux和防火墙 部署NetBox 一&#…...

uniapp接入BMapGL百度地图

下面代码兼容安卓APP和H5 百度地图官网&#xff1a;控制台 | 百度地图开放平台 应用类别选择《浏览器端》 /utils/map.js 需要设置你自己的key export function myBMapGL1() {return new Promise(function(resolve, reject) {if (typeof window.initMyBMapGL1 function) {r…...

AWTK 最新动态:支持鸿蒙系统(HarmonyOS Next)

HarmonyOS是全球第三大移动操作系统&#xff0c;有巨大的市场潜力&#xff0c;在国产替代的背景下&#xff0c;机会多多&#xff0c;AWTK支持HarmonyOS&#xff0c;让AWTK开发者也能享受HarmonyOS生态的红利。 AWTK全称为Toolkit AnyWhere&#xff0c;是ZLG倾心打造的一套基于C…...

React基础知识一

写的东西太多了&#xff0c;照成csdn文档编辑器都开始卡顿了&#xff0c;所以分篇写。 1.安装React 需要安装下面三个包。 react:react核心包 react-dom:渲染需要用到的核心包 babel:将jsx语法转换成React代码的工具。&#xff08;没使用jsx可以不装&#xff09;1.1 在html中…...

Oracle热备过程中对数据库崩溃的处理方法

引言 在热备过程中如果发生数据库崩溃、断电等情况该如何处理? 如果正在备份 users 表空间的数据文件过程中,此时的数据文件表头 SCN 会被锁定,此时正在复制数据文件时数据库崩溃,系统断电。 从而导致数据文件表头与控制文件中的不一致,导致数据库无法打开,会要求介质恢…...

身份证实名认证API接口助力电商购物安全

亲爱的网购达人们&#xff0c;你们是否曾经因为网络上的虚假信息和诈骗而感到困扰&#xff1f;在享受便捷的网购乐趣时&#xff0c;如何确保交易安全成为了我们共同关注的话题。今天&#xff0c;一起来了解一下翔云身份证实名认证接口如何为电子商务保驾护航&#xff0c;让您的…...

win10 禁止更新

一、winR 输入 regedit 二、输入注册列表路径&#xff1a; &#xff08;1&#xff09;计算机\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WindowsUpdate\UX\Settings &#xff08;2&#xff09;按照格式&#xff0c;创建文件命名: FlightSettingsMaxPauseDays &#xff08;3&…...

运维百科:网络性能20大关键指标

网络性能评估是确保网络服务质量和用户体验的关键环节。在网络、运维领域中&#xff0c;存在着一系列关键的性能指标&#xff0c;共同构成了衡量网络性能的基础。以下是网络性能的20大关键指标&#xff0c;每个指标都承载着特定的意义和重要性。 1.速率&#xff08;Rate&#…...

java编程开发基础,正则表达式的使用案例Demo

java编程开发基础,正则表达式的使用案例Demo!实际开发中&#xff0c;经常遇到一些字符串&#xff0c;信息的裁剪和提取操作&#xff0c;正则表达式是经常使用的&#xff0c;下面的案例&#xff0c;可以帮助大家快速的了解和熟悉&#xff0c;正则表达式的使用技巧。 package com…...

结构控制

目录​​​​​​​ 1.顺序结构 2.分支结构 2.1.单分支结构 2.2.二分支结构 2.3.多分支结构 2.4.嵌套分支结构 3.循环结构 3.1.while 循环结构 3.2.while...else 循环结构 PS&#xff1a;break 关键字 PS&#xff1a;pass 关键字 3.3.for 循环结构 PS&#xff1a;…...

Go语言中的内存分配与初始化:new与make函数详解

在Go语言中&#xff0c;内存分配和初始化是编程的基础操作。Go提供了两个内置函数new和make&#xff0c;用于不同场景下的内存分配和初始化。理解这两个函数的区别和适用场景对于编写高效、安全的Go代码至关重要。本文将详细介绍new和make函数&#xff0c;并提供示例说明它们的…...

The 2024 ICPC Kunming Invitational Contest

VP链接&#xff1a;https://codeforces.com/gym/105386 B. Gold Medal 签到题。对每一个读入的数 a&#xff0c;先记录已有奖牌数量&#xff0c;即 &#xff0c;再将 a 对 k 取模。然后将 a 数组从大到小排序&#xff0c;将每个不足 k 的数补到 k。如果 m 有剩余&#xff0c;…...

对原jar包解压后修改原class文件后重新打包为jar

文章目录 背景三种修改方式1.POM中移除原jar中依赖的历史版本2.原jar它不使用pom依赖而是直接放在源码中再编译使用JarEditor 插件对源码进行修改(推荐)使用java-decompiler反编译后修改源码覆盖原class&#xff08;不好用-不推荐直接跳过&#xff09;提醒 参考资料-推荐阅读拓…...

【C++】ReadFile概述,及实践使用时ReadFile的速率影响研究

ReadFile 函数概述 ReadFile 是 Windows API 函数&#xff0c;用于从文件或设备&#xff08;如串口、硬盘等&#xff09;中读取数据。它是同步和异步 I/O 操作的基础函数。 函数原型 BOOL ReadFile(_In_ HANDLE hFile, // 文件或设备句柄_Out_write…...

WebGL进阶(十一)层次模型

理论基础&#xff1a; 效果&#xff1a; 源码&#xff1a; <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"vie…...

Django:从入门到精通

一、Django背景 Django是一个由Python编写的高级Web应用框架&#xff0c;以其简洁性、安全性和高效性而闻名。Django最初由Adrian Holovaty和Simon Willison于2003年开发&#xff0c;旨在简化Web应用的开发过程。作为一个开放源代码项目&#xff0c;Django迅速吸引了大量的开发…...

C++设计模式行为模式———中介者模式

文章目录 一、引言二、中介者模式三、总结 一、引言 中介者模式是一种行为设计模式&#xff0c; 能让你减少对象之间混乱无序的依赖关系。 该模式会限制对象之间的直接交互&#xff0c; 迫使它们通过一个中介者对象进行合作。 中介者模式可以减少对象之间混乱无序的依赖关系&…...

Perfetto学习大全

Perfetto 是一个功能强大的性能分析和追踪工具&#xff0c;主要用于捕获和分析复杂系统中的事件和性能数据&#xff0c;特别是在 Android 和 Linux 环境下。它的核心目标是帮助开发者深入了解系统和应用程序的运行状态&#xff0c;以便优化性能和诊断问题。 Perfetto的主要作用…...

管家婆财贸ERP BR040.销售单明细表变更

最低适用版本&#xff1a; C系列 23.8 插件简要功能说明&#xff1a; 销售明细表支持直接修改单据自由项1-16更多细节描述见下方详细文档 插件操作视频&#xff1a; 进销存类定制插件--销售单明细表变更 1. 应用中心增加菜单【销售单明细表变更】 a. 复制23.8版本销售单明细…...

2411rust,实现特征

原文 在Rust2024中,impl Trait在中位置的默认工作方式有了变化.是为了简化impl Trait,以更好地匹配人们一般的需求. 还添加了一个灵活的语法,让你需要时可完全控制. 从Rust2024开始,一直在更改,何时可在返回位置impl Trait的隐藏类型中使用泛型参数的规则: 1,即对返回位置i…...

SpringBoot3与JUnit5集成测试

你可以在 Spring Boot 3 中轻松设置和运行 JUnit 集成测试。合理使用 Spring 提供的注解和工具&#xff0c;可以确保测试的高效性和可靠性。以下是集成测试的步骤和示例&#xff1a; 1. 添加依赖 在 pom.xml 中添加 Spring Boot Starter Test 依赖&#xff0c;它包含 JUnit 5 …...

工程企业需要什么样的物资管理系统?为什么需要物资管理系统?

一、背景与意义 在工程项目的建设中&#xff0c;无论是高楼大厦的拔地而起&#xff0c;还是高速公路的绵延铺展&#xff0c;物资都是最基础的要素之一。从钢筋水泥到施工机械&#xff0c;任何一种物资的管理不善都可能导致项目延误、成本超支&#xff0c;甚至质量问题。然而&a…...

Vue + Websocket播放PCM(base64转ArrayBuffer、 字符串转ArrayBuffer)

文章目录 引言I 音视频处理相关概念和APIII 案例:基于开源库 pcm-player方式播放借助MediaSource和Audio对象播放音频流。基于原生api AudioContext 播放操作III 格式转换js字符串转ArrayBufferbase64 转 ArrayBufferIV 解决pcm-player分片播放问题引言 需求: 基于webscoket传…...

华为防火墙技术基本概念学习笔记

1.防火墙概述 1.1防火墙与交换机、路由器对比 路由器与交换机的本质是转发&#xff0c;防火墙的本质是控制。 防火墙与路由器、交换机是有区别的。路由器用来连接不同的网络&#xff0c;通过路由协议保证互联互通&#xff0c;确保将报文转发到目的地;交换机则通常用来组建局域…...

Mesh路由组网

Mesh无线网格网络&#xff0c;多跳&#xff08;multi-hop&#xff09;网络&#xff0c;为解决全屋覆盖信号&#xff0c;一般用于家庭网络和小型企业 原理 网关路由器&#xff08;主路由&#xff0c;连接光猫&#xff09;&#xff0c;Mesh路由器&#xff08;子路由&#xff0c;…...

【数据结构】七种常用排序总结

一、七种排序及其讲解 以下为七种排序的讲解&#xff1a; 【数据结构】插入排序——直接插入排序 和 希尔排序 【数据结构】选择排序——选择排序 和 堆排序 【数据结构】交换排序——冒泡排序 和 快速排序 【数据结构】归并排序 —— 递归及非递归解决归并排序 二、排序的…...

【在Linux世界中追寻伟大的One Piece】多线程(一)

目录 1 -> Linux线程概念 1.1 -> 什么是线程 1.2 -> 线程的优点 1.3 -> 线程的缺点 1.4 -> 线程异常 1.5 -> 线程用途 2 -> Linux线程 VS 进程 2.1 -> 线程和进程 2.2 -> 进程的多个线程共享 3 -> Linux线程控制 3.1 -> POSIX线程…...

《Python编程实训快速上手》第十天--处理CSV文件和JSON数据

CSV&#xff1a;简化的电子表格&#xff0c;被保存为纯文本文件 JSON&#xff1a;是一种数据交换格式&#xff0c;易于人阅读和编写&#xff0c;同时也易于机器解析和生成&#xff0c;以JavaScript源代码的形式将信息保存在纯文本文件中 一、csv模块 CSV文件中的每行代表电…...

基于springboot停车场管理系统源码和论文

如今社会上各行各业&#xff0c;都喜欢用自己行业的专属软件工作&#xff0c;互联网发展到这个时候&#xff0c;人们已经发现离不开了互联网。新技术的产生&#xff0c;往往能解决一些老技术的弊端问题。因为传统停车场管理系统信息管理难度大&#xff0c;容错率低&#xff0c;…...

Linux的桌面

Linux的桌面是可以卸载的 的确&#xff0c;Linux并不像Windows&#xff0c;Linux本身是一个基于命令行的操作系统&#xff0c;在内核眼中&#xff0c;桌面只不过是个普通的应用程序&#xff0c;所以&#xff0c;在Linux的桌面中可以完成的事情&#xff0c;命令行中也基本可以完…...

Spring Boot 3.0废弃了JavaEE,改用了Jakarta EE

Spring Boot 3.0废弃了JavaEE&#xff0c;改用了Jakarta EE 历史背景 javax变成Jakarta的主要原因是因为Java EE项目从Oracle转移到了Eclipse Foundation&#xff0c;并改名为Jakarta EE。 JavaEE是从Java 1.2版本开始推出的Java企业级开发平台&#xff0c;最初的名称是J2EE(J…...

java-排序算法汇总

排序算法&#xff1a; 冒泡排序&#xff08;Bubble Sort&#xff09; 选择排序&#xff08;Selection Sort&#xff09; 插入排序&#xff08;Insertion Sort&#xff09; 快速排序&#xff08;Quick Sort&#xff09; 归并排序&#xff08;Merge Sort&#xff09; 堆排序&…...

C0030.Clion中运行提示Process finished with exit code -1073741515 (0xC0000135)解决办法

1.错误提示 2.解决办法 添加环境变量完成之后&#xff0c;重启Clion软件&#xff0c;然后就可以正常调用由mingw编译的opencv库了。...