kafka4.0浅尝辄止
最近工作中接触消息队列比较多,前几周又看到kafka4.0发布,故写一篇博客对消息队列做一个复盘。
目录
- 消息队列对比
- 1. Apache Kafka 4.0
- 2. RabbitMQ
- 3. RocketMQ
- 4. ActiveMQ
- 5. Apache Pulsar
- 6. NSQ
- kafka4.0
- 鲜明的新特性
- Java 版本要求升级
- API 更新与精简
- 移除zk依赖
- 新消费者组协议
- 快速开始
- 环境搭建
- windows环境
- linux Docker环境
- 生产消费
- 命令行
- golang
- 配置参考
消息队列对比
下面给出一个详细的对比表,涵盖了当前业界较主流的几款消息队列(MQ):Apache Kafka(特别是4.0版本)、RabbitMQ、RocketMQ、ActiveMQ以及Apache Pulsar。
产品 | 架构/协调机制 | 吞吐量 | 延迟 | 扩展性 | 消息持久性 | 优点 | 缺点 | 适用场景 |
---|---|---|---|---|---|---|---|---|
Kafka 4.0 | 全新KRaft模式(废弃ZooKeeper),自管理元数据 | 超高(百万级TPS) | ms级 | 极佳(水平扩展非常灵活) | 强(持久化日志存储,支持回溯) | 高吞吐、可扩展、高可用;新增队列语义支持点对点消费;历史消息回放丰富 | 较重的学习曲线;对低延时要求的场景可能稍欠,消息重复风险(需应用层去重) | 大数据实时流处理、日志采集、事件溯源、数据管道、流计算应用 |
RabbitMQ | 基于AMQP协议,Erlang开发;采用Broker模式推模式消息传递 | 中等(万级TPS左右) | 超低(微秒级推送) | 一般(主要依赖垂直扩展) | 可配置持久化(消息确认后删除) | 安装部署简单、支持多种路由和协议、成熟稳定、低延迟;管理界面友好 | 吞吐量较Kafka低;大量消息积压时性能下降;Erlang生态门槛较高 | 企业级系统、异步任务处理、RPC、请求-响应、低延迟实时消息传递 |
RocketMQ | 分布式架构:NameServer+Broker+Producer/Consumer | 高(十万级TPS左右) | ms级 | 很好(通过集群可实现水平扩展) | 强(写盘及副本机制确保不丢失) | 金融级稳定性、支持顺序消息和事务、消息堆积能力出色;在阿里内部经受多次考验 | 客户端语言主要是Java(及不成熟的C++);社区生态较Kafka稍逊 | 订单交易、金融系统、实时计费、业务削峰、对顺序性和事务性要求较高的场景 |
ActiveMQ | 基于JMS规范,主备模式,传统Broker模式 | 较低(万级TPS) | ms级 | 较弱(扩展性有限) | 支持持久化 | 标准JMS实现,功能较全、协议多样、适应传统系统对接 | 性能和扩展性不如新一代MQ,版本更新缓慢,社区活跃度较低 | 小规模企业、传统内部系统、对JMS兼容性要求较高的场景 |
Pulsar | 分层架构:Broker + BookKeeper(存储计算分离),ZooKeeper协同(元数据管理) | 高(十万级TPS) | ms级 | 极佳(支持多租户、跨数据中心) | 强(存储与计算分离,持久性高) | 支持多租户、跨地域容灾、灵活消费模式(独占、共享、failover、key_shared);扩展性好 | 较新,成熟度和生态尚在发展阶段;部署和运维配置较复杂 | 云原生应用、大型分布式系统、多租户环境、跨地域数据复制、需要存储计算分离的场景 |
NSQ | 轻量级 Pub/Sub 架构:nsqd 处理消息,nsqlookupd 负责服务发现 | 高(适当调优下能支持数十万TPS) | 超低(通常毫秒级) | 良好(易于集群水平扩展) | 可选持久化(默认在内存,支持磁盘模式) | 简洁易用、部署成本低、延迟极低、原生 Go 语言实现,高并发性能出色 | 功能较简单,不支持复杂路由、事务;在超大数据持久存储和回放场景下不如 Kafka | 微服务通信、实时数据流、轻量级事件分发、IoT、日志处理、请求-响应场景 |
1. Apache Kafka 4.0
核心变化与架构: Kafka 4.0 的标志性更新在于彻底废弃了对 ZooKeeper 的依赖,通过引入 KRaft(Kafka Raft)模式实现自管理元数据。这一改变简化了集群部署与管理,大大降低了运维复杂度,同时增强了集群的扩展性和可用性。
优点:
- 高吞吐与可扩展性:得益于分布式日志(持久化顺序写)技术,单机可以达到百万级TPS,多节点扩展非常灵活。
- 历史数据回放:持久化存储允许对历史数据进行重放和追溯,适合日志收集和事件溯源。
- 新增队列语义:Kafka 4.0开始支持点对点消费模式(共享组),让消息消费更加灵活。
缺点:
- 对新手来说,新体系结构和协议变化可能带来一定学习曲线。
- 在一些对实时性要求极高的场景下(如金融交易中毫秒级响应),相比基于推模式的RabbitMQ可能稍逊。
消费隔离:
- Kafka 采用 消费者组(Consumer Group) 模型:
- 同一组内,每个分区的消息仅由一个消费者消费,实现负载均衡;
- 不同消费者组独立消费同一主题的所有消息(即多个应用可获取完整消息副本)。
消息确认机制:
- Kafka 借助 offset 提交 来确认消费:
- 消费者处理完消息后提交当前偏移量(可自动或手动提交);
- 消费者故障时,未提交的消息会被重新消费,实现“至少一次”传递;
- 配合幂等生产者和事务,可实现精确一次消费。
Go 语言消费者示例: 使用 segmentio/kafka-go 库:
package mainimport ("context""fmt""log""github.com/segmentio/kafka-go"
)func main() {r := kafka.NewReader(kafka.ReaderConfig{Brokers: []string{"localhost:9092"},Topic: "example-topic",GroupID: "example-group",})defer r.Close()for {m, err := r.ReadMessage(context.Background())if err != nil {log.Fatal("error reading message: ", err)}fmt.Printf("Received message at offset %d: %s\n", m.Offset, string(m.Value))// 消费确认由 offset 提交决定(此库默认自动提交,可改为手动)}
}
适用场景: 主要适合大数据实时流处理、日志采集、事件溯源、数据管道以及流式计算。
2. RabbitMQ
架构特性: RabbitMQ 是基于 AMQP 协议,由 Erlang 开发,擅长消息的推送(push)模式,且内建丰富的交换机(Exchange)类型和路由机制,适合复杂的消息传递逻辑。
优点:
- 低延迟:由于推模式和Erlang语言并发特性,在消息响应上可以达到微秒级,非常适合需要低延时的场景。
- 灵活路由:多种交换机类型支持复杂的消息路由和过滤规则,满足不同业务需求。
- 成熟稳定:广泛应用于企业系统,管理界面友好,功能和插件成熟。
缺点:
- 吞吐量相对Kafka和RocketMQ较低,不太适合海量数据传输。
- 在消息积压时,性能下降较为明显。
- Erlang语言的生态对二次开发的要求较高,团队需要具备相应经验。
消费隔离:
- RabbitMQ 通过 队列与交换机 实现:
- 点对点模式下,同一队列中消息只会被一个消费者消费;
- 发布/订阅模式中,通过不同队列(或者同一个队列多个绑定)实现多个消费者各自获得完整消息。
消息确认机制:
- 使用 ACK/NACK 机制:
- 消费者处理成功后发送 ACK 给 Broker;
- 处理失败或超时则发送 NACK,消息重新投递,确保可靠性。
Go 语言消费者示例: 使用 streadway/amqp 库:
package mainimport ("fmt""log""github.com/streadway/amqp"
)func main() {conn, err := amqp.Dial("amqp://guest:guest@localhost:5672/")if err != nil {log.Fatal(err)}defer conn.Close()ch, err := conn.Channel()if err != nil {log.Fatal(err)}defer ch.Close()msgs, err := ch.Consume("example-queue", // 队列名称"", // consumer tagfalse, // auto-ack,为 false 需手动确认false,false,false,nil,)if err != nil {log.Fatal(err)}forever := make(chan bool)go func() {for d := range msgs {fmt.Printf("Received message: %s\n", d.Body)// 消费确认d.Ack(false)}}()fmt.Println("Waiting for messages. To exit press CTRL+C")<-forever
}
适用场景: 适合中小型企业、企业内部集成、异步任务处理、复杂路由消息(如RPC、请求响应)以及对实时性要求极高的业务场景。
3. RocketMQ
架构特性: RocketMQ 由阿里巴巴推出,采用Java实现,并针对高可靠性与顺序消息传递进行了优化。其核心架构由NameServer、Broker、Producer和Consumer组成,支持分布式部署。
优点:
- 高稳定性:在电商和金融场景中已有广泛验证,能够保证消息绝对不丢失。
- 高吞吐与顺序保证:支持十万级TPS,同时针对顺序消息和事务消息有特殊优化。
- 易于掌控:Java源码公开,便于二次开发和定制。
缺点:
- 客户端语言支持较为有限,主要集中在Java及部分C++实现。
- 社区生态和国际影响力略逊于Kafka。
消费隔离:
- 采用 消费者组(Consumer Group) 模型:
- 同一组内,消息在多个消费者间分配;
- 不同组独立消费同一主题下的全部消息,实现应用级隔离。
消息确认机制:
- 通过 回执确认:
- 消费者成功处理后,向 Broker 返回确认;
- 若未确认,Broker 根据重试策略重新投递消息。
Go 语言消费者示例: 使用 rocketmq-client-go/v2 库:
package mainimport ("context""fmt""log""github.com/apache/rocketmq-client-go/v2""github.com/apache/rocketmq-client-go/v2/consumer""github.com/apache/rocketmq-client-go/v2/primitive"
)func main() {c, err := rocketmq.NewPushConsumer(consumer.WithGroupName("testGroup"),consumer.WithNamesrvAddr([]string{"127.0.0.1:9876"}),)if err != nil {log.Fatalf("could not create consumer: %v", err)}err = c.Subscribe("example-topic", consumer.MessageSelector{}, func(ctx context.Context, msgs ...*primitive.MessageExt) (consumer.ConsumeResult, error) {for _, msg := range msgs {fmt.Printf("Received message: ID=%s, Body=%s\n", msg.MsgId, string(msg.Body))}// 处理成功返回确认return consumer.ConsumeSuccess, nil})if err != nil {log.Fatalf("subscribe error: %v", err)}err = c.Start()if err != nil {log.Fatalf("start consumer error: %v", err)}defer c.Shutdown()select {} // 阻塞等待
}
适用场景: 特别适用于金融、电商、订单交易系统以及对消息顺序和事务要求极高的场景;同时适合大规模消息堆积和削峰场景。
4. ActiveMQ
架构特性: ActiveMQ 基于JMS规范实现,支持多种消息模型(点对点和发布订阅),是较早期的开源消息中间件。
优点:
- 功能完备:实现了JMS标准,支持多种消息协议,兼容性好。
- 成熟稳定:广泛应用于传统企业系统中,适合作为内部消息传递通道。
缺点:
- 吞吐量和扩展性较差,不适合大规模数据处理。
- 社区更新缓慢,新功能和性能优化明显不足。
消费隔离:
- ActiveMQ 支持 队列(Point-to-Point) 和 主题(Publish/Subscribe) 模式:
- 队列模式中,消息只由一个消费者接收;
- 主题模式中,每个订阅者(Subscriber)都能收到消息,实现消费隔离。
消息确认机制:
- 支持多种 JMS 确认模式:
- AUTO_ACKNOWLEDGE(自动确认)、CLIENT_ACKNOWLEDGE(客户端确认)、或 SESSION_TRANSACTED(事务处理)
- 根据需求选择适当的模式,保证消息可靠传递或事务性一致性。
Go 语言消费者示例(基于 STOMP 协议): 使用 go-stomp/stomp 库:
package mainimport ("fmt""log""github.com/go-stomp/stomp"
)func main() {conn, err := stomp.Dial("tcp", "localhost:61613")if err != nil {log.Fatal(err)}defer conn.Disconnect()sub, err := conn.Subscribe("/queue/example.queue", stomp.AckAuto)if err != nil {log.Fatal(err)}defer sub.Unsubscribe()for {msg := <-sub.Cif msg.Err != nil {log.Fatal(msg.Err)}fmt.Printf("Received message: %s\n", string(msg.Body))}
}
适用场景: 适合小型或传统企业内部系统、与JMS兼容性要求较高的场景,对于消息量和吞吐要求不高的应用依然是个不错的选择。
5. Apache Pulsar
架构特性: Pulsar 采用分层架构设计,核心由Broker、BookKeeper(专用存储引擎)和ZooKeeper(元数据管理)组成,实现了存储与计算分离。支持多租户与跨数据中心部署。
优点:
- 灵活性与扩展性:天然支持多租户,集群水平扩展容易,适合大规模云原生应用。
- 高可用与跨区域支持:内置跨数据中心容灾机制,能满足复杂分布式部署需求。
- 多样化消费模式:支持独占、共享、故障转移和Key共享消费模式,灵活应对不同业务需求。
缺点:
- 由于相对较新,成熟度和部分生态支持尚不及Kafka;运维和部署配置较为复杂。
消费隔离:
- Pulsar 通过 订阅(Subscription) 机制实现消费隔离:
- 每个订阅就像一个独立的消费组,不同订阅可以独立消费同一主题的全部消息。
- 提供多种订阅类型(Exclusive、Shared、Failover、Key_Shared),以满足顺序性、负载均衡及容灾需求。
消息确认机制:
- 消费者在处理消息后需要显式 发送 ACK:
- 同时支持单条确认和累积确认,保证至少一次传递;
- 未确认的消息会在规定时间内重新投递。
Go 语言消费者示例: 使用 pulsar-client-go 库:
package mainimport ("context""fmt""log""github.com/apache/pulsar-client-go/pulsar"
)func main() {client, err := pulsar.NewClient(pulsar.ClientOptions{URL: "pulsar://localhost:6650",})if err != nil {log.Fatal(err)}defer client.Close()consumer, err := client.Subscribe(pulsar.ConsumerOptions{Topic: "example-topic",SubscriptionName: "example-subscription",Type: pulsar.Exclusive, // 或 Shared、Failover、KeyShared})if err != nil {log.Fatal(err)}defer consumer.Close()for {msg, err := consumer.Receive(context.Background())if err != nil {log.Fatal(err)}fmt.Printf("Received message [ID=%v]: '%s'\n", msg.ID(), string(msg.Payload()))consumer.Ack(msg)}
}
适用场景: 适合于云原生、大规模分布式、多租户应用、跨数据中心容灾场景以及对存储与计算分离有明确需求的系统。
6. NSQ
架构特性: NSQ 是由 Go 语言开发的实时分布式消息中间件,采用去中心化的架构设计。核心由 nsqd
(消息处理)与 nsqlookupd
(服务发现)组成,不依赖像 ZooKeeper 这样的协调组件,支持原生的 Pub/Sub 模型。通过 HTTP API 与轻量组件组合,实现简洁、高性能、低延迟的消息传递。
优点:
- 部署简单:无外部依赖,单一可执行文件即可运行,便于集群扩展和维护。
- 低延迟高性能:基于 Go 的并发能力,微秒级延迟,单节点即可支撑高并发消息流。
- 架构解耦性好:通过
nsqlookupd
实现服务发现,无中心协调器,天然高可用。 - 接口友好:内建 Web UI 和 HTTP API,开发调试体验良好。
- 原生 Go 支持:Go 项目集成自然,生态偏 Go 场景友好。
缺点:
- 功能较轻:不支持事务、延迟队列、顺序消息等高级特性。
- 持久化能力有限:虽然支持磁盘落盘,但缺乏 Kafka 等级的日志存储与历史重放能力。
- 消费管理弱:无 offset 管理,幂等和消费追踪需业务方补齐。
- 生态较小:相较于 Kafka、RabbitMQ 社区活跃度较低,语言支持主要集中于 Go 与 Python。
消费隔离:
- NSQ 采用 Channel 概念 实现消费隔离:
- 一个 Topic 可以有多个 Channel,每个 Channel 相当于一个独立的消费订阅;
- 同一 Channel 内的多个消费者会自动进行负载均衡,而不同 Channel 则各自收到完整的消息副本。
消息确认机制:
- NSQ 采用 ACK 机制:
- 消费者成功处理后发送 ACK;
- 如果超时未确认,NSQ 会重新投递消息,确保可靠消费。
Go 语言消费者示例: 使用 nsqio/go-nsq 库:
package mainimport ("fmt""log""github.com/nsqio/go-nsq"
)type ConsumerHandler struct{}func (h *ConsumerHandler) HandleMessage(m *nsq.Message) error {fmt.Printf("Received NSQ message: %s\n", string(m.Body))return nil // 返回 nil 即确认消息处理成功
}func main() {config := nsq.NewConfig()consumer, err := nsq.NewConsumer("example_topic", "example_channel", config)if err != nil {log.Fatal(err)}consumer.AddHandler(&ConsumerHandler{})// 连接 nsqlookupd 进行服务发现if err := consumer.ConnectToNSQLookupd("127.0.0.1:4161"); err != nil {log.Fatal(err)}select {} // 阻塞等待
}
适用场景:
适用于微服务架构、实时日志/监控系统、IoT 消息传递、请求-响应异步通信、快速原型/初创项目等。特别适合 Go 项目中需要高并发、低延迟、部署轻便的消息队列方案。
kafka4.0
我们将目光回到kafka4.0!这是一个重要里程碑,官方称这是第一个完全无需 Apache ZooKeeper 运行的重大版本。
Apache Kafka 4.0 是一个重要的里程碑,标志着第一个完全无需 Apache ZooKeeper® 运行的重大版本。通过默认运行在 KRaft 模式下,Kafka 简化了部署和管理,消除了维护单独的 ZooKeeper 集群的复杂性。这一变化显著降低了运营开销,增强了可伸缩性,并简化了管理任务。
Kafka 的主要版本,如 4.0 版本,移除了至少 12 个月前已弃用的 API,以简化平台,并鼓励采用新功能。值得注意的是,在 Kafka 4.0 中,Kafka 客户端和 Kafka Streams 需要 Java 11,而 Kafka 代理、Connect 和工具现在则需要 Java 17。
发布说明:https://archive.apache.org/dist/kafka/4.0.0/RELEASE_NOTES.html
官方文档:https://kafka.apache.org/documentation.html#upgrade_4_0_0
官方下载连接:https://kafka.apache.org/downloads
我们在官方下载二进制包并且解压,会发现以往繁重的zk配置消失了!
鲜明的新特性
Java 版本要求升级
随着 Kafka 4.0 的发布,其对 Java 版本的要求也相应提高,Kafka 客户端和 Kafka Streams 需要 Java 11,而 Kafka 代理、Connect 和相关工具则需要 Java 17。这一升级举措具有多方面的重要意义:
-
性能优化:较新的 Java 版本在性能方面有了显著提升,包括更快的 JIT 编译器、优化的垃圾回收机制等。这将直接反映在 Kafka 的运行效率上,提高消息处理速度和系统响应能力。
-
安全增强:新版本的 Java 修复了众多安全漏洞,并引入了更强大的安全特性。升级到指定的 Java 版本,能够确保 Kafka 系统在日益复杂的网络安全环境中具备更高的安全性,保护数据的完整性和保密性。
-
功能扩展:Java 11 和 17 引入了许多新特性和 API,如 HttpClient、Switch 表达式增强等。这些新特性为 Kafka 的开发和扩展提供了更多可能性,有助于构建更现代化、功能更强大的应用程序。
对于使用 Kafka 的项目团队而言,这一变化提醒他们在升级 Kafka 版本时,务必同步检查和更新 Java 运行环境,以确保系统的兼容性和稳定性。同时,这也是推动团队技术栈升级,拥抱现代化开发工具和实践的良好契机。
在 Kafka 4.0 版本中,用于开发和运行消息生产与消费的客户端库(包括 Kafka Streams 作为流处理库)要求运行环境至少使用 Java 11;而 Kafka 的服务器端组件(也就是 Kafka 代理,即 broker)、用于数据集成的 Kafka Connect 框架以及其它附带的管理和工具程序,则需要在更高版本的 Java(Java 17)上运行。这反映了 Kafka 4.0 在不同组件上对 Java 功能和性能优化的不同需求。
-
Kafka 客户端
- 定义: Kafka 客户端是指开发者在应用程序中使用的库,这些库使得应用程序能够连接到 Kafka 集群,实现消息的生产(Producer)和消费(Consumer)。
- 作用: 客户端负责与 Kafka 服务器通信,发送和接收消息,是应用程序与 Kafka 集群交互的接口。
- Java 要求: Kafka 客户端库(如 Java 的 KafkaProducer 和 KafkaConsumer)需要在 Java 11 环境下运行。
-
Kafka Streams
- 定义: Kafka Streams 是构建在 Kafka 客户端之上的一个高层次流处理库,用于开发实时、分布式的流处理应用程序。
- 作用: 它简化了流数据的处理、转换、聚合等操作,使开发者能够更轻松地构建复杂的实时处理管道。
- Java 要求: 同样需要 Java 11 环境,这与 Kafka 客户端保持一致。
-
Kafka 代理(Broker)
- 定义: Kafka 代理是 Kafka 集群中的服务器组件,负责存储主题、分区数据,并提供数据发布、订阅和持久化功能。
- 作用: 它是 Kafka 集群的核心,负责接收消息、写入日志、管理数据副本、协调集群内部的各种操作等。
- Java 要求: Kafka 代理需要在 Java 17 环境下运行,说明新版代理利用了 Java 17 的新特性和性能改进,以实现更高的稳定性和吞吐量。
-
Kafka Connect
- 定义: Kafka Connect 是一个用于将外部系统(例如数据库、文件系统、搜索引擎等)与 Kafka 集群无缝集成的框架。
- 作用: 它提供了数据的导入和导出功能,使得数据能够在 Kafka 与其他系统之间流动,简化了数据集成工作。
- Java 要求: Kafka Connect 及相关工具也需要在 Java 17 环境下运行,可能是因为这些工具需要更高的性能和更现代的 JVM 特性来支持大规模数据交换和管理任务。
API 更新与精简
为了保持平台的简洁性和可持续发展,Kafka 4.0 删除了至少 12 个月前被废弃的 API。
KIP-724: 移除对消息格式 v0 和 v1 的支持:消息格式 v0 和 v1 在 Apache Kafka 3.0 中被弃用。它们已在 4.0 版本中移除。
移除zk依赖
在 Kafka 3.x 及更早版本中,ZooKeeper(ZK)是元数据管理的核心组件,负责 Broker 注册、Topic 分区分配、控制器选举等关键任务,如图所示。
这种设计存在显著问题:
- 运维复杂度高 :需独立维护 ZK 集群,占用额外资源且增加故障点。
- 性能瓶颈明显 :元数据操作依赖 ZK 的原子广播协议(ZAB),大规模集群(如万级分区)下元数据同步延迟可达秒级。
- 扩展性受限 :ZK 的写性能随节点数增加而下降,限制 Kafka 集群规模。
Apache Kafka Raft(KRaft)是在 KIP-500 中引入的共识协议,用于移除 Apache Kafka 对 ZooKeeper 进行元数据管理的依赖。这通过将元数据管理的责任集中在 Kafka 本身,而不是在两个不同的系统(ZooKeeper 和 Kafka)之间分割,从而大大简化了 Kafka 的架构。
KRaft 模式利用 Kafka 中的新法定多数控制器服务,取代了之前的控制器,并使用基于事件的 Raft 共识协议的变体。
Kafka 4.0 默认启用 KRaft 模式 (Kafka Raft),完全摒弃 ZK 依赖。其核心原理如下:
- 元数据自管理 :基于 Raft 共识算法,将元数据存储于内置的 __cluster_metadata 主题中,由 Controller 节点(通过选举产生)统一管理。
- 日志复制机制 :所有 Broker 作为 Raft 协议的 Follower,实时复制 Controller 的元数据日志,确保强一致性。
- 快照与恢复 :定期生成元数据快照,避免日志无限增长,故障恢复时间从 ZK 时代的分钟级优化至秒级。
新消费者组协议
传统上,Kafka 主要采用发布-订阅模式,消费者组模式下,分区需与消费者一一绑定,如下图所示。
无法实现多消费者协同处理同一分区消息,消费者数量不能超过分区数量——最多为一对一。
在大规模数据处理场景中,消费者组的重平衡操作一直是影响系统性能和用户体验的关键环节。Kafka 4.0 通过引入新的消费者组协议(KIP-848),对这一核心功能进行了深度优化。传统上,当消费者组内的成员发生变化(如消费者实例的加入或退出)时,整个组会触发重平衡过程,以重新分配分区的消费任务。然而,这一过程往往会导致短暂的停机时间和延迟增加,尤其是在消费者组规模较大或分区数量较多的情况下。 新的消费者组协议将重平衡逻辑从客户端转移到了服务器端,从根本上解决了上述问题。
Apache Kafka 通过下一代消费者重平衡协议的通用可用性,告别了 “停止世界” 的重平衡。它提高了消费者组的稳定性和性能,同时简化了客户端。新的协议在服务器端默认启用。消费者必须通过设置 group.protocol=consumer 来选择加入。
在某些特定场景下,如点对点的消息传递、任务分配等,传统的队列语义更具优势。
Kafka 4.0 通过引入“队列”功能, 共享组(Share Group) , 允许多消费者同时处理同一分区消息,实现点对点消费模式 。
Kafka 4.0 通过 共享组 实现队列语义,关键技术包括:
- 多消费者协同消费 :同一分区的消息可由多个消费者并行处理,突破分区数限制。
- 记录级锁机制 :每条消息被消费时加锁(TTL 控制),防止重复处理。
- ACK/NACK 语义 :支持逐条确认(Exactly-Once)或重试(At-Least-Once)。
主要特点:
- 支持传统队列场景 :适用于需要保证消息严格顺序且仅由一个消费者处理的场景。
- 提升资源利用率 :共享组机制使得多个消费者能够动态地共享分区资源,提高了系统资源的利用率和整体吞吐量。
- 简化架构设计 :开发者无需在 Kafka 与其他专门的队列系统之间进行复杂的集成和数据迁移。(因为之前kafka是通过偏移量offset提交的,而不是ack/nack)
快速开始
环境搭建
windows环境
在本地,我们可以下载tgz包然后解压,kafka在bin目录下面开辟了windows子目录,提供了对windows环境的支持,
修改配置文件server.properties
就可以通过启动脚本启动了:
.\bin\windows\kafka-server-start.bat .\config\server.properties
有时候会报错:
'wmic' 不是内部或外部命令,也不是可运行的程序
或批处理文件。
WMIC(Windows Management Instrumentation Command-line),是 Windows 系统中的一种命令行界面工具,用于通过 Windows 管理规范(WMI)获取系统和网络信息、管理 Windows 操作系统和设备。微软已于 2016 年在 Windows Server 中弃用了 WMIC;于 2021 年在 Windows 10 系统中弃用了 WMIC。
2024年微软再度禁用了 Windows 11 中内置的 WMIC 管理工具,并宣布将在 Windows 11 的下个版本中正式“砍掉”这款应用。
我们需要首先去设置->可选功能->查看功能
搜索wmic重新下载:
然后重新启动:
PS H:\kafka\kafka_2.13-4.0.0> .\bin\windows\kafka-server-start.bat .\config\server.properties
DEPRECATED: A Log4j 1.x configuration file has been detected, which is no longer recommended.
To use a Log4j 2.x configuration, please see https://logging.apache.org/log4j/2.x/migrate-from-log4j1.html#Log4j2ConfigurationFormat for details about Log4j configuration file migration.
You can also use the H:\kafka\kafka_2.13-4.0.0/config/tool-log4j2.yaml file as a starting point. Make sure to remove the Log4j 1.x configuration after completing the migration.
'java' 不是内部或外部命令,也不是可运行的程序
或批处理文件。
出现这个命令代表我们本机没有java环境,由于kafka依赖java17,我们去官网下载:https://www.oracle.com/java/technologies/javase/jdk17-archive-downloads.html
然后配置环境变量,并添加path:
变量名:JAVA_HOME
变量值:安装位置%JAVA_HOME%\bin
能正常输入如下内容即代表安装完成,
除此之外,这是因为 Kafka 在使用 KRaft 模式时,需要在日志目录中存在 meta.properties 文件来存储集群元数据(如 cluster.id 和 broker.id),如果该文件缺失,Kafka 将无法启动。默认配置的日志目录会导致无法启动,因此我们修改配置文件:
log.dirs=H:/kafka/kafka_2.13-4.0.0/tmp
然后生成一个唯一的集群 ID(可能会输出log4j的错误,不是kafka的错误,我们直接忽略):
.\bin\windows\kafka-storage.bat random-uuid
然后,使用生成的 UUID 格式化存储目录
.\bin\windows\kafka-storage.bat format --standalone -t <your-uuid> -c .\config\server.properties
然后再次启动:
linux Docker环境
我们可以看到windows下环境搭建非常复杂,docker可以将复杂的环境与开发工作解耦,官方提供的docker镜像有两种:
基于JVM的镜像(Using JVM Based Apache Kafka Docker Image):
docker pull apache/kafka:4.0.0
docker run -p 9092:9092 apache/kafka:4.0.0
基于GraalVM的镜像(Using GraalVM Based Native Apache Kafka Docker Image)
docker pull apache/kafka-native:4.0.0
docker run -p 9092:9092 apache/kafka-native:4.0.0
从体积上看,基于GraalVM的镜像明显小很多,可以按照python和go直观对比,第一种相当于基于python解释器把代码也要放进去,第二种相当于源码编译好后就放了一个可执行文件和配置文件。
GraalVM 本质上是一个支持 Java 的运行时(基于 OpenJDK),但它内置了一个更强大的 JIT 编译器(Graal Compiler)。它可以把 Java 应用编译成一个 不依赖 JVM 的原生可执行文件,启动速度非常快,内存占用更小。原理是 提前编译(AOT),在编译阶段就静态分析代码,连类加载器、GC、反射等都做了裁剪或替换。
GraalVM 支持在一个进程中运行和互操作以下语言:
- Java / Kotlin / Scala 等 JVM 语言
- JavaScript / TypeScript
- Python(实验性)
- Ruby(实验性)
- R、LLVM-based languages(如 C/C++ via Sulong)
编译后的影响:
-
启动速度:kafka-native 镜像由于是原生可执行文件,启动速度更快,适合对启动时间敏感的场景。
-
资源占用:原生镜像在运行时的内存占用通常更小,适合资源受限的环境。
-
兼容性:由于 kafka-native 是通过 GraalVM 编译的,可能在某些特性上与标准 JVM 版本存在差异,需注意兼容性问题。
生产消费
命令行
执行如下命令就可以创建一个名为mytest
的topic:
// windows
bin/windows/kafka-topics.bat --create --topic mytest --bootstrap-server localhost:9092// linux
bin/kafka-topics.sh --create --topic mytest --bootstrap-server localhost:9092
查看topic详细信息:
$ bin/kafka-topics.sh --describe --topic mytest --bootstrap-server localhost:9092
Topic: quickstart-events TopicId: NPmZHyhbR9y00wMglMH2sg PartitionCount: 1 ReplicationFactor: 1 Configs:
Topic: quickstart-events Partition: 0 Leader: 0 Replicas: 0 Isr: 0
生产消息:
$ bin/kafka-console-producer.sh --topic mytest --bootstrap-server localhost:9092
>hello
>world
消费消息:
$ bin/kafka-console-consumer.sh --topic mytest --from-beginning --bootstrap-server localhost:9092
This is my first event
This is my second event
golang
现在去golang package网站搜kafka,人气较高的有两个:
对比下两个库:
特性 | Sarama(IBM 维护) | kafka-go(Segment 维护) |
---|---|---|
Kafka 版本支持 | 支持 Kafka 0.8+,但对 Kafka 4.0 的支持未明确,存在兼容性风险 | 官方测试支持 Kafka 0.10.1.0 至 2.7.1,尚未明确支持 Kafka 4.0 |
分区感知能力 | 存在分区变更后需重启客户端的问题 | 支持自动感知分区变化,具备自动重试和重连机制 |
维护状态 | 由 IBM 接手维护,活跃度一般,文档相对较少 | 维护活跃,文档完善,易于学习和使用 |
性能与资源占用
特性 | Sarama | kafka-go |
---|---|---|
同步写性能 | 异步模式性能较好,但同步模式性能较差,存在内存占用高的问题 | 异步写性能优异,适合高吞吐场景;同步写性能较差 |
内存管理 | 使用指针传递,导致频繁的垃圾回收和较高的内存使用 | 内存管理更高效,资源占用较低 |
功能特性
特性 | Sarama | kafka-go |
---|---|---|
API 设计 | 提供低级 API,使用复杂,缺乏对 Go 上下文(context)的支持 | 提供高级和低级 API,支持 Go 上下文,易于集成 |
消费者组支持 | 支持消费者组,但在多个 Topic 订阅时可能存在部分分区无法消费的问题 | 支持消费者组,具备自动重试和重连机制,稳定性更高 |
Mock 测试支持 | 提供 Mock 测试包,便于单元测试 | 不提供 Mock 测试包,需自行搭建测试环境 |
社区与生态
特性 | Sarama | kafka-go |
---|---|---|
社区活跃度 | 社区活跃度一般,文档相对较少 | 社区活跃,文档完善,易于学习和使用 |
生态支持 | 与其他 Go 项目集成较为复杂 | 易于与 Go 项目集成,适合快速开发 |
-
推荐使用 kafka-go:如果您追求简洁的 API、良好的性能和更高的稳定性,尤其是在需要自动感知分区变化和支持 Go 上下文的场景下,kafka-go 是更合适的选择。
-
谨慎使用 Sarama:尽管 Sarama 在异步高并发操作方面表现良好,但存在分区感知能力差、内存管理不佳等问题,且对 Kafka 4.0 的兼容性未明确,建议在特定需求下谨慎使用。
-
关注 Confluent-Kafka-go:如果您需要完全兼容 Kafka 的所有特性,并且可以接受引入 C++ 库带来的编译复杂度,Confluent-Kafka-go 是一个值得考虑的选择。
这里直接扑上Kafka-go官网的看法:
我们在 Segment 广泛依赖 Go 和 Kafka。不幸的是,在撰写本文时,Kafka 的 Go 客户端库的状态并不理想。可用的选项包括:
-
sarama:虽然是目前最受欢迎的,但使用起来非常困难。它文档不足,API 暴露了 Kafka 协议中的底层概念,而且不支持 Go 的新特性,如 context。它还将所有值都作为指针传递,导致大量的动态内存分配、更频繁的垃圾回收以及更高的内存使用。
-
confluent-kafka-go:这是一个基于 librdkafka 的 cgo 封装,因此它在所有使用该包的 Go 代码中都引入了对 C 库的依赖。它的文档比 sarama 好得多,但仍然不支持 Go 的 context。
-
goka:是一个较新的 Kafka Go 客户端,专注于特定的使用模式。它为将 Kafka 用作服务之间消息总线(而不是事件顺序日志)提供了抽象,但这并不是我们在 Segment 使用 Kafka 的典型方式。该包还依赖 sarama 处理所有与 Kafka 的交互。
这就是 kafka-go 的用武之地。它提供了用于与 Kafka 交互的高级和低级 API,模仿了 Go 标准库的概念并实现了其接口,使其易于使用并能与现有软件集成。
不管怎么说,我们先下载下来看看:github.com/segmentio/kafka-go
,kafka-go提供了低级api和高级api,所谓低级/高级指的是:
低级 API
特点:
- 直接控制:开发者需要直接管理与 Kafka 的连接、分区、偏移量等细节。
- 灵活性高:适用于需要精细控制 Kafka 行为的场景,例如手动管理偏移量、特定的分区消费策略等。
使用示例:
以下是使用低级 API 通过 kafka.Conn
发送消息的示例:
package mainimport ("context""log""time""github.com/segmentio/kafka-go"
)func main() {topic := "my-topic"partition := 0// 连接到 Kafka 的指定分区的 leaderconn, err := kafka.DialLeader(context.Background(), "tcp", "localhost:9092", topic, partition)if err != nil {log.Fatal("failed to dial leader:", err)}defer conn.Close()// 设置写入超时时间conn.SetWriteDeadline(time.Now().Add(10 * time.Second))// 发送消息_, err = conn.WriteMessages(kafka.Message{Value: []byte("Hello Kafka")},kafka.Message{Value: []byte("Another Message")},)if err != nil {log.Fatal("failed to write messages:", err)}
}
高级 API
特点:
- 简化操作:封装了常用的读写操作,内部自动处理连接、分区、偏移量等细节。
- 易于使用:适合大多数常规的 Kafka 使用场景,开发者无需关注底层实现。
使用示例:
以下是使用高级 API 的生产者和消费者示例:
生产者:
package mainimport ("context""log""time""github.com/segmentio/kafka-go"
)func main() {// 初始化一个 writer,指定 Kafka 地址和主题writer := kafka.NewWriter(kafka.WriterConfig{Brokers: []string{"localhost:9092"},Topic: "my-topic",Balancer: &kafka.LeastBytes{},})defer writer.Close()// 创建消息msg := kafka.Message{Key: []byte("Key-A"),Value: []byte("Hello Kafka"),}// 发送消息err := writer.WriteMessages(context.Background(), msg)if err != nil {log.Fatal("failed to write messages:", err)}log.Println("Message is written")
}
消费者:
package mainimport ("context""log""github.com/segmentio/kafka-go"
)func main() {// 初始化一个 reader,指定 Kafka 地址、主题和消费者组reader := kafka.NewReader(kafka.ReaderConfig{Brokers: []string{"localhost:9092"},GroupID: "my-group",Topic: "my-topic",MinBytes: 10e3, // 10KBMaxBytes: 10e6, // 10MB})defer reader.Close()for {// 读取消息msg, err := reader.ReadMessage(context.Background())if err != nil {log.Fatal("failed to read message:", err)}log.Printf("Message at offset %d: %s = %s\n", msg.Offset, string(msg.Key), string(msg.Value))}
}
这次我们采用镜像方式启动kafka,首先打开dockerhub页面搜索kafka,可以看到除了镜像外还有k8s charts文件:
我们采取官方镜像:
Apache Kafka 支持通过环境变量覆盖一系列代理配置。环境变量必须以 KAFKA_ 开头,并且在代理配置中的任何点(.)应在相应的环境变量中用下划线(_)表示。例如,要设置主题的默认分区数 num.partitions,需要设置环境变量 KAFKA_NUM_PARTITIONS。
例如,要在 KRaft 结合模式下运行 Kafka(意味着处理客户端请求的代理和处理集群协调的控制器都运行在同一容器中),并且将默认的主题分区数设置为 3,而不是默认的 1,我们需要指定 KAFKA_NUM_PARTITIONS,并添加其他必需的配置:
docker run -d \--name broker \-e KAFKA_NODE_ID=1 \-e KAFKA_PROCESS_ROLES=broker,controller \-e KAFKA_LISTENERS=PLAINTEXT://:9092,CONTROLLER://:9093 \-e KAFKA_ADVERTISED_LISTENERS=PLAINTEXT://localhost:9092 \-e KAFKA_CONTROLLER_LISTENER_NAMES=CONTROLLER \-e KAFKA_LISTENER_SECURITY_PROTOCOL_MAP=CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXT \-e KAFKA_CONTROLLER_QUORUM_VOTERS=1@localhost:9093 \-e KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR=1 \-e KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR=1 \-e KAFKA_TRANSACTION_STATE_LOG_MIN_ISR=1 \-e KAFKA_GROUP_INITIAL_REBALANCE_DELAY_MS=0 \-e KAFKA_NUM_PARTITIONS=3 \apache/kafka:latest
在命令行中指定这么多环境变量会变得很麻烦。更简单的方法是使用 Docker Compose 来指定和管理 Kafka 容器。
services:broker:image: apache/kafka:latestcontainer_name: brokerenvironment:KAFKA_NODE_ID: 1KAFKA_PROCESS_ROLES: broker,controllerKAFKA_LISTENERS: PLAINTEXT://:9092,CONTROLLER://:9093KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://10.128.145.159:9092KAFKA_CONTROLLER_LISTENER_NAMES: CONTROLLERKAFKA_LISTENER_SECURITY_PROTOCOL_MAP: CONTROLLER:PLAINTEXT,PLAINTEXT:PLAINTEXTKAFKA_CONTROLLER_QUORUM_VOTERS: 1@localhost:9093KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1KAFKA_TRANSACTION_STATE_LOG_REPLICATION_FACTOR: 1KAFKA_TRANSACTION_STATE_LOG_MIN_ISR: 1KAFKA_GROUP_INITIAL_REBALANCE_DELAY_MS: 0KAFKA_NUM_PARTITIONS: 3ports:- 9092:9092networks:- kafka-netnetworks:kafka-net:driver: bridge
启动docker:
docker-compose down
docker-compose up -d
进入镜像并初始化:
docker exec --workdir /opt/kafka/bin/ -it broker sh
./kafka-topics.sh --bootstrap-server localhost:9092 --create --topic mytest
开启一个生产者:
./kafka-console-producer.sh --bootstrap-server localhost:9092 --topic mytest
验证是否可以收到信息:
然后我们以go高级api为例:
package mainimport ("context""github.com/segmentio/kafka-go""log"
)var (brokers = []string{"10.128.145.159:9092",}groupId = "generalzy"topic = "mytest"
)func main() {// 初始化一个 reader,指定 Kafka 地址、主题和消费者组reader := kafka.NewReader(kafka.ReaderConfig{Brokers: brokers,GroupID: groupId,Topic: topic,MinBytes: 10e3, // 10KBMaxBytes: 10e6, // 10MB})defer reader.Close()for {// 读取消息msg, err := reader.ReadMessage(context.Background())if err != nil {log.Fatal("failed to read message:", err)}log.Printf("Message at offset %d: %s = %s\n", msg.Offset, string(msg.Key), string(msg.Value))}
}
最后遗憾收场:
2025/04/13 13:04:05 failed to read message:fetching message: EOF
看样子kafka-go的协议暂未支持kafka4.0。
配置参考
https://kafka.apache.org/documentation.html#brokerconfigs
相关文章:
kafka4.0浅尝辄止
最近工作中接触消息队列比较多,前几周又看到kafka4.0发布,故写一篇博客对消息队列做一个复盘。 目录 消息队列对比1. Apache Kafka 4.02. RabbitMQ3. RocketMQ4. ActiveMQ5. Apache Pulsar6. NSQ kafka4.0鲜明的新特性Java 版本要求升级API 更新与精简移…...
nmcli创建wpa-psk2 wifi热点
1. 创建新的WiFi连接: sudo nmcli connection add type wifi ifname wlan0 con-name WiFi名称 autoconnect yes ssid WiFi名称 2. 配置接入点模式和IP共享: sudo nmcli connection modify WiFi名称 802-11-wireless.mode ap 802-11-wireless.band …...
分布式日志治理:Log4j2自定义Appender写日志到RocketMQ
🧑 博主简介:CSDN博客专家,历代文学网(PC端可以访问:https://literature.sinhy.com/#/?__c1000,移动端可微信小程序搜索“历代文学”)总架构师,15年工作经验,精通Java编…...
【STM32单片机】#8 定时器编码器接口ADC模数转换器
主要参考学习资料: B站江协科技 STM32入门教程-2023版 细致讲解 中文字幕 开发资料下载链接:https://pan.baidu.com/s/1h_UjuQKDX9IpP-U1Effbsw?pwddspb 单片机套装:STM32F103C8T6开发板单片机C6T6核心板 实验板最小系统板套件科协 实验&…...
dify部署,ollama部署,拉取模型,创建ai聊天应用
dify下载安装 dify1.0.1 windos安装包百度云盘地址 通过网盘分享的文件:dify-1.0.1.zip 链接: 百度网盘 请输入提取码 提取码: 1234 dify安装包 linux安装包百度云盘地址 通过网盘分享的文件:dify-1.0.1.tar.gz 链接: 百度网盘 请输入提取码 提取码…...
213、【图论】有向图的完全联通(Python)
题目描述 原题链接:105. 有向图的完全联通 代码实现 import collectionsn, k list(map(int, input().split())) adjacency collections.defaultdict(list) for _ in range(k):head, tail list(map(int, input().split()))adjacency[head].append(tail)visited_…...
Node.js中util模块详解
Node.js 中 util 模块全部 API 详解 一、类型检查函数 const util require(util);// 1. util.types // 检查对象类型 console.log(util.types.isDate(new Date())); // true console.log(util.types.isRegExp(/abc/)); // true console.log(util.types.isArrayBuffer(new …...
BasicTS:全面基准测试与异质性分析
BasicTS:全面基准测试与异质性分析 在当今数字化时代,多元时间序列(Multivariate Time Series, MTS)分析在众多领域发挥着关键作用,从交通管理到能源系统优化,都离不开对MTS的精准预测。然而,当…...
认识python全栈框架reflex:快速打造工具类网站、模型调用web应用
以下是对reflex的简单介绍: 纯Python编写的,高性能、可自定义的 Web 应用开发框架 网页开发内置组件生态完整,灵活使用、快速接入、快速部署支持路由页面,可以开发复杂系统、企业级系统,这方面优于gradio、streamlit…...
课题申报的立项依据方位指南:使用DeepSeek提高课题立项的关键
在竞争日益激烈的学术研究和科研项目申报环境中,立项依据作为课题申报书的灵魂部分,往往决定着一项研究能否获得评审专家的青睐和资助。 然而,许多研究者尽管学术能力突出,却在立项依据的撰写上显得力不从心,导致优质…...
蓝桥杯电子赛_E2PROM(AT24C02)
目录 一 前言 二 E2PROM的相关讲解 AT24C02的地址 PCF8591的地址 三 根据提供的iic写代码 相关可能会有疑问的地方: 1 三个入口参数,都有什么用? 2 为什么在写中,要用IIC_SendByte,在读中,要用IIC_R…...
Kubernetes服务注册到consul流程实践
文章目录 前言架构图示意一、环境准备二、consul部署1.yaml示例2.consul部署验证 三、consulctl工具实现1.核心功能2.注册到consul的标签及元数据3.consulctl工具使用示例 四、通过Dockerfile构建consulctl工具镜像五、Kubernetes集成方案六、 结果验证1.注册验证2.销毁验证 总…...
供应链业务-供应链全局观(三)- 供应链三流的集成
概述 供应链的全局观的全两篇文章主要描述了供应链的基础概念和供应链的协作和集成问题。 供应链业务-供应链全局观(一)定义了什么是供应链和供应链管理。 所谓供应链就是把采购进来的东西,通过自身的生成加工,进行增值服务&am…...
Docker 提示Docker Engine stopped
做AI开发的时候,安装Docker提示Docker Engine stopped,以下是解决步骤: 一般都是成功的,不成功很可能是电脑兼容问题,通过采用4.4.4版本解决的: docker desktop 4.4.4 旧版本下载:在这里找到了4…...
对自己的优缺点评价
在面试中回答优缺点时,需要既体现自我认知的客观性,又能将优缺点与岗位需求结合,避免暴露可能影响工作的硬伤。以下是一个符合Java开发者角色的回答框架,供参考: 回答思路: 优点:选择与岗位直接…...
解决eNSP在24H2版本下AR_40启动失败问题
前言 1.网络学习中缺少不了模拟,自从Windows版本更新24H2以后,eNSP就出现各种问题,最常见的就是AR报错40【启动失败】,之前我也去网站搜了,也问了Microsoft社区,发现他们在底层逻辑上进行了修改(开启了虚拟…...
计算机组成原理-指令系统
1. 指令系统的定义与作用 指令系统(Instruction Set Architecture, ISA)是计算机硬件与软件之间的接口规范,定义了CPU能够识别和执行的所有指令的集合,是计算机体系结构的核心组成部分。 核心作用: 为程序员提供操作…...
Oracle数据库中 LEVEL start with prior connect by
在Oracle数据库中,处理层次结构数据是一项常见且重要的任务。无论是组织结构、分类目录还是其他具有层级关系的数据,Oracle都提供了强大的工具来简化和优化这些操作。其中,LEVEL伪列结合CONNECT BY和START WITH关键字,成为了处理层…...
HTTP 1.1 比 HTTP1.0 多了什么?(详尽版)
相较于HTTP 1.0,1.1 版本增加了以上特性: 1. 新增了连接管理即 keepalive,允许持久连接。 定义: Keepalive允许客户端和服务器在完成一次请求-响应后,保持连接处于打开状态,以便后续请求复用同一连接&am…...
Java学习手册:Java I/O与NIO
Java I/O(Input/Output)和NIO(New Input/Output)是Java语言中用于处理输入输出操作的重要部分。它们提供了丰富的API来处理文件和网络通信。I/O是Java早期版本中引入的,而NIO是在Java 1.4中引入的,旨在提供…...
linux下的目录文件管理和基本文件管理的基本操作
目录 1.目录创建,文件创建和文件编辑的案例 2.文件编辑进阶 --vim 3. 命令的别名 4. 查看文件内容和文件编辑(重定向)的案例 5. 重定向之追加 6. 查看目录和文件编辑的案例 7. 查看目录和文件编辑(覆盖)的案例 为了加深对linux命令的熟悉程度,这…...
magnet库Hello,world!
1.c文件 #include<iostream> #include"Control.hpp" class O1:public mag::Control{bool b; public:O1(){b1;}bool decide(){return b&&islifing();}void action(){std::cout<<"Hello,world!\n";b0;destroy();} }; int main(){O1 o1;…...
应急响应靶机-Linux(1)
挑战内容 账户密码:defend/defend Root/defend 黑客的IP地址遗留下的三个flag 1、按正常思路来走,先登录一手因已经给出root账户密码,先查看一手执行过的命令,发现一个flag值并且看到他往期编辑了一个文件,咱们顺便进去…...
k8s 部署spring项目+动态启动pod
在 Kubernetes 中部署 Spring Boot 项目并实现 动态管理 Pod(自动扩缩容、滚动更新等),需要结合 Docker 镜像构建、Deployment 配置、Service 暴露和 HPA(Horizontal Pod Autoscaler) 等组件。以下是完整操作步骤&…...
【DINO】
detr 简化了检测流水线,消除了许多手工设置的组件 单阶段目标检测 需要前置的backbone抽取特征 faster_rcnn和yolo都是基于anchor,anchor当作候选框,NMS非极大值抑制 重叠的框只保存一个,效率低 所以detr来了,transformer,既有encoder又有decoder,套一个transforme…...
Nature重磅:后晶体管时代光子芯片革新AI计算!光子处理器运行《吃豆人》性能比肩电子,能效提升超500倍
随着人工智能(AI)模型规模以及应用范围的不断拓展,性能上限和能耗瓶颈正逐渐显现出来。大语言模型(LLM)、强化学习和卷积神经网络等 AI 模型的复杂性不断增长,正在将传统电子计算推向极限,能源需…...
Excel表格文件分组归并——通过sql
将 Excel 表转换为 SQL 数据库并直接执行 SQL 查询以获得所需的输出。以下是使用 SQL 实现此目的的步骤: 第 1 步:将 Excel 数据导入 MySQL 假设您设置了 MySQL 数据库,则需要先将 Excel 数据导入到表中。您可以使用语句或工具(…...
2.微服务拆分流程
文章目录 交易服务1.1.创建项目1.2.引入依赖1.3.创建交易服务启动类1.4.创建并编写配置文件1.5.代码连接池4.2.1.引入依赖4.2.2.开启连接池抽取Feign客户端 1.6.抽取ItemClient接口1.7.抽取CartClient接口改造OrderServiceImpl扫描包 1.8.数据库1.9.配置启动项1.10.测试 以拆分…...
vue入门:计算属性computer监听器watch
文章目录 计算属性computer定义计算属性在模板中使用计算属性计算属性的使用场景 监听器watch基本语法深度监听立即执行监听数组异步操作数据校验副作用处理清理监听器 watch 与 computed 的区别 计算属性computer 在 Vue 中,计算属性(computed…...
Jenkins 发送钉钉消息
这里不介绍 Jenkins 的安装,可以网上找到很多安装教程,重点介绍如何集成钉钉消息。 需要提前准备钉钉机器人的 webhook 地址。(网上找下,很多教程) 下面开始配置钉钉机器人,登录 Jenkins,下载 …...
numpy练习
生成一个2行3列随机整数二维数组a使用Numpy方法对(1)中数组a进行整体求积使用Numpy方法对(1)中数组a进行求每列最大值索引定义一个NumPy一维数组 b,元素为 1 到 10 的整数获取(4)数组b中最后五个…...
Ethers.js 开发入门:核心功能、最佳实践与避坑指南
引言 Ethers.js 是当前 Web3 开发领域增长最快、备受开发者青睐的以太坊 JavaScript 库之一。在本篇文章中,我们将介绍 Ethers.js 的核心功能和用法,包括如何连接区块链节点、与钱包交互、读取智能合约数据、发送交易等。同时,我们还将分享使…...
SQL查询语句的书写顺序
一、标准SQL书写顺序(逻辑顺序) 书写顺序是开发者编写SQL时遵循的语法规则,逻辑上更贴近“声明式”需求描述。以下是从前往后的书写顺序: SELECT[DISTINCT] 列名或表达式 FROM表名或子查询 [JOIN ... ON ...] WHERE行级…...
探索加密期权波动率交易的系统化实践——动态对冲工具使用
Trading Volatility – What Are My Options? 在本文中,我们将介绍一些如何交易资产波动性(而非资产价格)的示例。为了帮助理解,我们将使用 Deribit 上提供的几种不同产品,包括但不限于期权。我们将尽可能消除对标的价…...
文件操作和 IO - 3
目录 文件内容的读写 —— 数据流 InputStream 概述 方法: 说明: FileInputStream 概述 read 方法: OutputStream 概述 方法 说明 FileOutputStream 概述 write 方法: Reader 字符流 Writer 字符流 总结:…...
Kubernetes中的Label和Selector核心作用与应用场景
一. Label 和 Selector 的核心概念 Label 和 Selector 是 Kubernetes 中实现灵活资源管理的基石,贯穿部署、服务发现、监控等核心场景。通过合理设计标签,用户可以高效实现自动化运维与精准资源控制。 Label(标签): K…...
L1-6 大勾股定理
题目 大勾股定理是勾股定理的推广:对任何正整数 n 存在 2n1 个连续正整数,满足前 n1 个数的平方和等于后 n 个数的平方和。例如对于 n1 有 3^2 4^2 5^2 ;n2 有 10^2 11^2 12^2 13^2 14^2 等。给定 n,本题就请你找出对应的解。 输…...
esp32-idf Linux 环境安装教程
一、提前说明 1. 系统环境 Ubuntu22.04 2. 适配芯片 ESP32S3 3. idf版本 v5.4.1(截止2025年4月13日为最新版本) 二、安装步骤 1. 安装前置依赖 sudo apt-get install git wget flex bison gperf python3 python3-pip python3-venv cmake ninja-build ccache libffi-dev l…...
关于使用 nuitka进行构建python应用的一些配置,以及github action自动构建;
1. 通用配置 # 设置输出目录和文件名output_dir "dist"app_name "CursorAutoFree"# 基础命令行选项base_options ["--follow-imports", # 跟踪导入"--enable-plugintk-inter", # 启用 Tkinter 支持"--include-packagecusto…...
C++开山解惑
. Solution & Code 本题解仅适用于 C 选手。 这道题可谓是 C 中最基础的题目之一,先上两份代码: #include <cstdio> using namespace std;int main() {long long a, b;scanf("%lld%lld", &a, &b);printf("%lld"…...
Pytorch深度学习框架60天进阶学习计划 - 第41天:生成对抗网络进阶(二)
Pytorch深度学习框架60天进阶学习计划 - 第41天:生成对抗网络进阶(二) 7. 实现条件WGAN-GP # 训练条件WGAN-GP def train_conditional_wgan_gp():# 用于记录损失d_losses []g_losses []# 用于记录生成样本的多样性(通过类别分…...
路由策略/策略路由之route-policy
思科名称:route-map、match、set Route-policy 是一个非常重要的基础性策略工具。你可以把它想象成一个拥有多个节点(node)的列表(这些 node 按编号大小进行排序)。在每个节点中,可以定义条件语句及执行语…...
《嵌入式系统原理》一些题目
1 .ARM 的存储格式?默认的存储模式是? 大端格式和小端格式,默认为小端模式 2 .当前程序状态寄存器?(英文简写、条件码标志位及控制位的含义) CPSR,N,Z,C,V(P26) 3 &a…...
卡洛诗已悄然改写高性价比西餐的竞争规则
在餐饮行业竞争日益激烈的今天,消费者对“高性价比”的定义已从单纯的低价转向品质、体验与情感价值的综合考量。萨莉亚原团队成员出来升级孵化的新概念中式西餐卡洛诗以“访九州异馔,再造东方味”为核心理念,通过本土化创新、严控文化及场景…...
独立开发者之网站的robots.txt文件如何生成和添加
robots.txt是一个存放在网站根目录下的文本文件,用于告诉搜索引擎爬虫哪些页面可以抓取,哪些页面不可以抓取。下面我将详细介绍如何生成和添加robots.txt文件。 什么是robots.txt文件? robots.txt是遵循"机器人排除协议"(Robots…...
02核心-EffectSpec,EffectContext
1.FGameplayEffectSpec 效果Spec 创建:MakeOutGoingSpec>EffectSpecHandle≈EffectSpec. 创建总结:EffectLevelEffectContext>EffectSpec(Handle) 数据:EffectSpec存有效果的等级,上下文,类。 还有很多其他东…...
驱动开发硬核特训 · Day 10(下篇):设备模型实战篇 —— Platform 驱动机制 ≈ 运行时适配器
🔍 B站相应的视屏教程: 📌 内核:博文视频 - 总线驱动模型实战全解析 敬请关注,记得标为原始粉丝。 🔧 📍 一、目标与回顾 在上篇《理论篇》中,我们从软件工程角度,解释…...
集合框架二三事
一.集合框架 Java集合框架(Java Collections Framework)是Java标准库中用于存储和处理对象集合的一组接口和实现类。它提供了一套统一的API,使得开发者能够高效地管理和操作数据集合。以下是关于Java集合框架的详细介绍,包括其核…...
前端jest(vitest)单元测试快速手上
前言 vitest和jest除了配置上不同,其他的基本差不多,这里以jest为例进行说明 安装依赖 npm install -D jest编写测试 例如,我们将编写一个简单的测试来验证将两个数字相加的函数的输出。 sum.js export function sum(a, b) {return a b…...
优化方法介绍(二)
优化方法介绍(二) 本博客是一个系列博客,主要是介绍各种优化方法,使用 matlab 实现,包括方法介绍,公式推导和优化过程可视化 1 BFGS 方法介绍 BFGS 的其实就是一种改良后的牛顿法,因为计算二阶导数 Hessian 矩阵所需的计算资源是比较大的,复杂度为 O ( 2 ⋅ n 2 ) …...