一、使用net kafka 消费
在一个项目中使用C#开发WPF的大屏展示程序,需要实时监控用户的车辆信息,并在地图上进行展示和更新,后台采取的策略是:用户车辆GPS传感器通过socket 发送到我们的kafka集群中,前端使用kafka 进行数据的接收并进行数据解析、更新展示,kafka 对主流的开发语言支持还是比较好的,如java、C#、python、Go等,C#开发库目前主流是两个,分别是kafka-net、confluent kafka,详细的介绍可以参考这篇博客。
刚开始选择的是kafka-net,但是在使用的过程中发现了很多问题,如:
1.不指定offset 的话,每次都会从头开始消费;
2.另外最让人无法接受的是无法设置consumer group ,时不时会出现同样的topic 通过其它语言进行监听消费,完全没问题, 但是用此库就是无法接收消息.
一开始选择这个库的原因是调用非常简单,但是到了后期,上面累积的问题,不得不转向另外一个库confluent kafka。
下面分别介绍这两个库的一些用法,和相应的demo,这些库在github上都在不断的更新,大家可以及时关注新的更新,也许我说的上面的一些问题,随着后面版本的更新会慢慢解决。
二、kafka-net
本项目在github上的地址为:
https://github.com/Jroland/kafka-net
基础使用方法:
Producer
var options = new KafkaOptions(new Uri("http://SERVER1:9092"), new Uri("http://SERVER2:9092"));
var router = new BrokerRouter(options);
var client = new Producer(router);
client.SendMessageAsync("TestHarness", new[] { new Message("hello world")}).Wait();
using (client) { }
Consumer
var options = new KafkaOptions(new Uri("http://SERVER1:9092"), new Uri("http://SERVER2:9092"));
var router = new BrokerRouter(options);
var consumer = new Consumer(new ConsumerOptions("TestHarness", router));
//Consume returns a blocking IEnumerable (ie: never ending stream)
foreach (var message in consumer.Consume())
{
Console.WriteLine("Response: P{0},O{1} : {2}",
message.Meta.PartitionId, message.Meta.Offset, message.Value);
}
如果不想从头消费的话,需要在消费之前设置offset,下面代码中三个OffsetPosition 要根据集群的实际数量进行设置,另外里面的偏移量也是根据特定的topic实际情况分别设置
OffsetPosition p0 = new OffsetPosition(0, 100);
OffsetPosition p1 = new OffsetPosition(0,100);
OffsetPosition p2 = new OffsetPosition(0, 100);
consumer .SetOffsetPosition(new OffsetPosition[] {p0,p1,p2 });
开发库,已经上传,可以在这个地址下载:
三、confluent kafka
本项目在github上的地址为:
https://github.com/confluentinc/confluent-kafka-dotnet
基本使用方法如下:
Basic Producer Example
using System;
using System.Text;
using System.Collections.Generic;
using Confluent.Kafka;
using Confluent.Kafka.Serialization;
public class Program
{
public static void Main()
{
var config = new Dictionary<string, object>
{
{ "bootstrap.servers", "localhost:9092" }
};
using (var producer = new Producer<Null, string>(config, null, new StringSerializer(Encoding.UTF8)))
{
var dr = producer.ProduceAsync("my-topic", null, "test message text").Result;
Console.WriteLine($"Delivered '{dr.Value}' to: {dr.TopicPartitionOffset}");
}
}
}
Basic Consumer Example
using System;
using System.Text;
using System.Collections.Generic;
using Confluent.Kafka;
using Confluent.Kafka.Serialization;
public class Program
{
public static void Main()
{
var conf = new Dictionary<string, object>
{
{ "group.id", "test-consumer-group" },
{ "bootstrap.servers", "localhost:9092" },
{ "auto.commit.interval.ms", 5000 },
{ "auto.offset.reset", "earliest" }
};
using (var consumer = new Consumer<Null, string>(conf, null, new StringDeserializer(Encoding.UTF8)))
{
consumer.OnMessage += (_, msg)
=> Console.WriteLine($"Read '{msg.Value}' from: {msg.TopicPartitionOffset}");
consumer.OnError += (_, error)
=> Console.WriteLine($"Error: {error}");
consumer.OnConsumeError += (_, msg)
=> Console.WriteLine($"Consume error ({msg.TopicPartitionOffset}): {msg.Error}");
consumer.Subscribe("my-topic");
while (true)
{
consumer.Poll(TimeSpan.FromMilliseconds(100));
}
}
}
}
这个库使用不复杂,前期没有选择这个开发库的主要原因,是它的依赖比较多,前期一直跑不起来,在经过多方找寻后,终于跑通 了,开发库已经上传,大家可以在这个地址下载
我的一个测试项目依赖如下:
runtimes 文件夹里面,选择自己系统对应的文件夹内容即可:
四、总结
相对比两个库进行测试验证,confluent kafka 整体使用效果要比kafka-net要好很多,也经过了实际的项目验证,具体的车辆GPS监控接收目标效果如下: