在处理kafka消息的时候会遇到这种情况,想要仅获取最新的消息,旧消息不获取。苦于原API中无这种需求的示例,现就该需求参考GitHub以下改动。
1 NuGet管理Confluent.Kafka版本的问题,将版本更新至V1.0.0或以上。
2 编写函数如下:该函数用来接收最新消息,并且参数中的事件对拿到的最新消息进行处理。
/// <summary>
/// 指定的组别的消费者开始消费指定主题的消息
/// </summary>
/// <param name="broker">Kafka消息服务器的地址</param>
/// <param name="topic">Kafka消息所属的主题</param>
/// <param name="groupID">Kafka消费者所属的组别</param>
/// <param name="action">可以对已经消费的消息进行相关处理</param>
public void Consume(string broker, string topic, string groupID, Action<string> action = null)
{
try
{
if (string.IsNullOrEmpty(broker) || string.IsNullOrWhiteSpace(broker) || broker.Length <= 0)
{
throw new ArgumentNullException("Kafka消息服务器的地址不能为空!");
}
if (string.IsNullOrEmpty(topic) || string.IsNullOrWhiteSpace(topic) || topic.Length <= 0)
{
throw new ArgumentNullException("消息所属的主题不能为空!");
}
if (string.IsNullOrEmpty(groupID) || string.IsNullOrWhiteSpace(groupID) || groupID.Length <= 0)
{
throw new ArgumentNullException("用户分组ID不能为空!");
}
var config = new ConsumerConfig
{
BootstrapServers = broker,
GroupId = groupID,
AutoOffsetReset = AutoOffsetReset.Latest
};
using (var consumer = new ConsumerBuilder<Ignore, string>(config).SetPartitionsAssignedHandler((f, ps) =>
{
return ps.Select(tp => new TopicPartitionOffset(tp, f.QueryWatermarkOffsets(tp, TimeSpan.FromSeconds(10)).High ));
}).Build())
{
consumer.Subscribe(topic);
CancellationTokenSource cts = new CancellationTokenSource();
Console.CancelKeyPress += (_, e) =>
{
e.Cancel = true; // prevent the process from terminating.
cts.Cancel();
};
try
{
while (true)
{
try
{
var cr = consumer.Consume(cts.Token);
string CurrentMessage = string.Format("Consumed message {0} at {1}", cr.Value, cr.TopicPartitionOffset);
if (action != null)
{
action(cr.Value);
}
// Console.WriteLine($"Consumed message '{cr.Value}' at: '{cr.TopicPartitionOffset}'.");
}
catch (ConsumeException e)
{
Console.WriteLine($"Error occured: {e.Error.Reason}");
}
}
}
catch (OperationCanceledException)
{
// Ensure the consumer leaves the group cleanly and final offsets are committed.
consumer.Close();
}
}
}
catch(Exception ex)
{
}
}