在 ASP.NET Core 中使用 Confluent.Kafka 实现 Kafka 生产者和消费者

大家好,我是深山踏红叶,今天来聊一聊<aspnetcore中怎么集成kafka>,读作卡夫卡,和星铁里面的一个角色名名字一样,那什么是kafka,Kafka 是一个高效、可靠、可扩展的分布式消息队列,适用于实时数据流的处理和传输。适用于日志收集,实时数据流处理,事件驱动架构等场景,是不是有点类似rabbitmq那味了,在aspnetcore中怎么集成,大家请往下看。

安装

首先, 老规矩,先安装依赖包

bash 复制代码
dotnet add package Confluent.Kafka

生产者

Program.cs 中配置 Kafka 生产者,使其作为服务注入到依赖注入容器中。这样可以在应用的任何地方轻松地使用 Kafka 生产者。

csharp 复制代码
using Confluent.Kafka;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;

var builder = WebApplication.CreateBuilder(args);

// 配置 Kafka 生产者
builder.Services.AddSingleton<IProducer<Null, string>>(provider =>
{
    var config = new ProducerConfig
    {
        BootstrapServers = "localhost:9092",
        Acks = Acks.All,
        //DeliveryReportOnlyError = true, //net分享
        MessageSendMaxRetries = 3
    };
    return new ProducerBuilder<Null, string>(config).Build();
});
 // 注册 Kafka 生产者
builder.Services.AddSingleton<KafkaProducerService>(); 

var app = builder.Build(); 

创建一个服务类来封装 Kafka 消息生产者。

csharp 复制代码
using Confluent.Kafka;
using System.Threading.Tasks;

public class KafkaProducerService
{
    private readonly IProducer<Null, string> _producer;

    public KafkaProducerService(IProducer<Null, string> producer)
    {
        _producer = producer;
    }

    public async Task ProduceMessageAsync(string topic, string message)
    {
        try
        {
            var result = await _producer.ProduceAsync(topic, new Message<Null, string> { Value = message });
            Console.WriteLine($"Message '{result.Value}' delivered to {result.TopicPartitionOffset}");
        }
        catch (ProduceException<Null, string> e)
        {
            Console.WriteLine($"Error producing message: {e.Error.Reason}");
        }
    }
}

使用它,在需要的地方注入 KafkaProducerService 并使用它来发送消息。

csharp 复制代码
using Microsoft.AspNetCore.Mvc;
using System.Threading.Tasks;

[ApiController]
[Route("api/[controller]")]
public class KafkaController : ControllerBase
{
    private readonly KafkaProducerService _producerService;

    public KafkaController(KafkaProducerService producerService)
    {
        _producerService = producerService;
    }

    [HttpPost]
    public async Task<IActionResult> ProduceMessage([FromBody] string message)
    {
        await _producerService.ProduceMessageAsync("test-topic", message);
        return Ok("Message sent to Kafka");
    }
}

消费者

Kafka 消费者可以作为单独的后台服务运行,以便异步消费来自 Kafka 的消息。

ASP.NET Core 中,可以使用 IHostedService 来实现后台消费者服务。

csharp 复制代码
using Confluent.Kafka;
using Microsoft.Extensions.Hosting;
using System;
using System.Threading;
using System.Threading.Tasks;

public class KafkaConsumerService : IHostedService
{
    private readonly IConsumer<Ignore, string> _consumer;

    public KafkaConsumerService()
    {
        var config = new ConsumerConfig
        {
            BootstrapServers = "localhost:9092",
            GroupId = "test-consumer-group",
            AutoOffsetReset = AutoOffsetReset.Earliest,
            EnableAutoCommit = false,
            StatisticsIntervalMs = 5000
        };

        _consumer = new ConsumerBuilder<Ignore, string>(config).Build();
    }

    public Task StartAsync(CancellationToken cancellationToken)
    {
        // 启动消费者线程
        Task.Run(() => ConsumeMessages(cancellationToken), cancellationToken);
        return Task.CompletedTask;
    }

    private void ConsumeMessages(CancellationToken cancellationToken)
    {
        _consumer.Subscribe("test-topic");

        while (!cancellationToken.IsCancellationRequested)
        {
            try
            {
                var consumeResult = _consumer.Consume(cancellationToken);
                Console.WriteLine($"Consumed message: {consumeResult.Message.Value} at {consumeResult.TopicPartitionOffset}");
            }
            catch (ConsumeException e)
            {
                Console.WriteLine($"Error: {e.Error.Reason}");
            }
        }
    }

    public Task StopAsync(CancellationToken cancellationToken)
    {
        _consumer.Close();
        return Task.CompletedTask;
    }
}

Program.cs 中将消费者服务注册为后台服务:

csharp 复制代码
var builder = WebApplication.CreateBuilder(args);

// 注册 Kafka 生产者和消费者服务
builder.Services.AddSingleton<IProducer<Null, string>>(provider =>
{
    var config = new ProducerConfig
    {
        BootstrapServers = "localhost:9092"
    };
    return new ProducerBuilder<Null, string>(config).Build();
});
builder.Services.AddHostedService<KafkaConsumerService>();  // 注册消费者为后台服务

var app = builder.Build();

// 中间件等其他配置...

app.Run();

错误处理和重试机制

在生产和消费消息时,错误是不可避免的。你可以根据需要增加重试逻辑或使用回调处理失败。可以通过配置 Kafka 消费者的 AutoOffsetResetEnableAutoCommit 等选项来控制消费者行为。

csharp 复制代码
var config = new ConsumerConfig
{
    BootstrapServers = "localhost:9092",
    GroupId = "test-consumer-group",
    AutoOffsetReset = AutoOffsetReset.Earliest,  // 从最早的消息开始消费
    EnableAutoCommit = false  // 手动提交偏移量
};

提高性能

  • 批量发送消息 :使用 ProduceAsync 方法的批量发送功能。
  • 异步消费:确保消费者在处理消息时不会阻塞主线程。
  • 分区策略:合理分配消息到不同的分区,以提高并发处理能力。

总结

通过上面的操作,你可以在 ASP.NET Core 应用中实现 Kafka 生产者和消费者的功能。生产者可以将消息发送到 Kafka,消费者则可以从 Kafka 中异步消费消息。还可以通过优化和扩展该系统,如使用序列化、分区策略、消费者组协调等。

进一步阅读

欢迎关注我的公众号"Net分享",技术文章第一时间推送,随缘更新 , 分享一些你可能注意不到的细节

相关推荐
Asthenia04121 小时前
Spring扩展点与工具类获取容器Bean-基于ApplicationContextAware实现非IOC容器中调用IOC的Bean
后端
bobz9651 小时前
ovs patch port 对比 veth pair
后端
Asthenia04121 小时前
Java受检异常与非受检异常分析
后端
uhakadotcom2 小时前
快速开始使用 n8n
后端·面试·github
JavaGuide2 小时前
公司来的新人用字符串存储日期,被组长怒怼了...
后端·mysql
bobz9652 小时前
qemu 网络使用基础
后端
Asthenia04122 小时前
面试攻略:如何应对 Spring 启动流程的层层追问
后端
Asthenia04122 小时前
Spring 启动流程:比喻表达
后端
Asthenia04123 小时前
Spring 启动流程分析-含时序图
后端
ONE_Gua3 小时前
chromium魔改——CDP(Chrome DevTools Protocol)检测01
前端·后端·爬虫