Window Kafka使用(.Net)
一:环境搭建(windows)
安装jdk1.8,新建环境变量
JAVA_HOME D:\Program_Files\Java\jdk1.8.0_131
1.1 安装zookeeper
下载最新版zookeeper,http://www.apache.org/dyn/closer.cgi/zookeeper/
修改系统环境变量,在Path后添加 ;D:\Program_Files\apache-zookeeper-3.7.0\bin
复制conf\zoo_sample.cfg,重命名zoo.cfg,修改zoo.cfg中的dataDir,并添加一行dataLogDir
dataDir=D:/Program_Files/apache-zookeeper-3.7.0/data
dataLogDir=D:/Program_Files/apache-zookeeper-3.7.0/log
启动zkServer,cmd -> zkServer
2.2 安装kafka
下载最新版kafka,http://kafka.apache.org/downloads
添加系统环境变量,在Path后添加 ;D:\Program_Files\kafka_2.13-2.8.0\bin\windows
解压到指定路径,如:E:\kafka_2.12-0.10.2.0
修改kafka_2.13-2.8.0\config目录下的server.properties中 log.dirs的值
log.dirs=D:/Program_Files/kafka_2.13-2.8.0/kafka-logs
启动kafka,cmd
d:
cd D:\Program_Files\kafka_2.13-2.8.0
.\bin\windows\kafka-server-start.bat .\config\server.properties
二:测试
运行cmd命令行,创建一个topic,命令如下:
kafka-topics.bat --create --zookeeper localhost:2181 --replication-factor 1 --partitions 1 --topic test
再打开一个cmd,创建一个Producer,命令如下:
kafka-console-producer.bat --broker-list localhost:9092 --topic test
再打开一个cmd,创建一个Customer,命令如下:
kafka-console-consumer.bat --bootstrap-server localhost:9092 --topic test --from-beginning
程序添加Nuget
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 | using Confluent.Kafka; using System; using System.Collections.Generic; using System.Threading; namespace KafKaNet { class Program { // localhost static void Main( string [] args) { ThreadPool.QueueUserWorkItem( new WaitCallback(Consumer)); Produce(); } /// <summary> /// 生产者 /// </summary> public static void Produce() { var config = new ProducerConfig { BootstrapServers = "localhost:9092" }; Action<DeliveryReport<Null, string >> handler = r => Console.WriteLine(!r.Error.IsError ? $ "Delivered message to {r.TopicPartitionOffset}" : $ "Delivery Error: {r.Error.Reason}" ); using ( var p = new ProducerBuilder<Null, string >(config).Build()) { try { for ( var i = 1; i <= 10; i++) { p.Produce( "test" , new Message<Null, string > { Value = $ "my111 message: {i}" }, handler); } p.Flush(TimeSpan.FromSeconds(3)); // 超时时间 } catch (ProduceException<Null, string > e) { Console.WriteLine($ "Delivery failed: {e.Error.Reason}" ); } } Console.WriteLine( "Done!" ); Console.ReadKey(); } /// <summary> /// 消费者 /// </summary> public static void Consumer( object obj) { var conf = new ConsumerConfig { GroupId = "test-consumer-group" , BootstrapServers = "localhost:9092" , AutoOffsetReset = AutoOffsetReset.Earliest, EnableAutoCommit = false // 设置非自动偏移,业务逻辑完成后手动处理偏移,防止数据丢失 }; using ( var c = new ConsumerBuilder<Ignore, string >(conf).Build()) { c.Subscribe( "test" ); try { while ( true ) { try { var consume = c.Consume(); string receiveMsg = consume.Message.Value; Console.WriteLine($ "Consumed message '{receiveMsg}' at: '{consume.TopicPartitionOffset}'." ); if ( true ) { c.Commit( new List<TopicPartitionOffset>() { consume.TopicPartitionOffset }); //手动提交偏移 } } catch (ConsumeException e) { Console.WriteLine($ "Error occured: {e.Error.Reason}" ); } } } catch (OperationCanceledException) { c.Close(); } } } } } |
kafka存在问题
1. 数据丢失
2. 重复消费问题(已经消费了数据,但是offset没来得及提交)
消费者选择自动提交还是手动提交
问题一:已经消费的数据对于kakfa来说,会将该消费组里面的offset值进行修改。什么时候去修改的?
当数据被消费者拿去之后就自动提交,而不关注消费者是否成功消费,如果消费者端出现故障,就会导致此条数据没有被消费,继续运行就会导致此数据丢失
如果消费者成功消费此数据,而在提交的过程的出现故障,会导致再次发送此数据到消费者,继续运行就会到此数据重复提交
kafka没有提供一个绝对安全的方案,只提供了多种选择来供用户解决此类问题
问题二:比如消费者拿到数据之后,存入到mysql数据库中。但是mysql数据库这个时候,连接不上,抛出异常。但是在处理的时候已经进行提交了,那么kafka上的offset值已经修改了,可是mysql数据库中没有数据--数据丢失
解决方案:可以将数据在处理完成之后,再进行提交,然后进行offset值的修改。默认情况下是自动提交,需要修改为手动提交。
问题三:如果在处理代码中正常处理了,但是在提交的offset请求时,没有连接到kafka或者出翔了故障,那么该次请求,是失败的。那么下次进行读取同一个分区的数据时,会从已经处理掉的offset值在进行处理一次,那么在hbase中就会产生两条一样的数据,也就是重复提交
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律