简单的.NET 8 Web API使用Kafka 发布订阅模式,示例api示例
- kafka
当使用Kafka时,我们需要使用Kafka的客户端库来与Kafka集群进行通信。在.NET Core中,可以使用Confluent.Kafka客户端库来实现与Kafka的集成。首先,我们需要在项目中添加Confluent.Kafka库的引用。
首先,使用NuGet包管理器或者命令行工具添加Confluent.Kafka库的引用:
dotnet add package Confluent.Kafka
接下来,我们可以创建一个名为WeatherUpdatesProducer的类,用于生成天气预报数据并将其发布到Kafka的主题中:
// WeatherUpdatesProducer.csusing Confluent.Kafka;
using System;
using System.Threading;
namespaceWebApiDemo
{
publicclassWeatherUpdatesProducer
{
privatereadonly IProducer<Null, string> _producer;
privatereadonlystring _topicName;
public WeatherUpdatesProducer(string bootstrapServers, string topicName)
{
_topicName = topicName;
var config = new ProducerConfig { BootstrapServers = bootstrapServers };
_producer = new ProducerBuilder<Null, string>(config).Build();
}
public void ProduceWeatherUpdates()
{
var rng = new Random();
for (int i = 0; i < 5; i++)
{
var forecast = new
{
Date = DateTime.Now.AddDays(i),
TemperatureC = rng.Next(-20, 55),
Summary = Summaries[rng.Next(Summaries.Length)]
};
var message = $"{forecast.Date}: {forecast.Summary}";
_producer.Produce(_topicName, new Message<Null, string> { Value = message });
Thread.Sleep(1000); // 模拟每秒发布一次消息
}
}
privatestaticreadonlystring[] Summaries = new[]
{
"Freezing", "Bracing", "Chilly", "Cool", "Mild",
"Warm", "Balmy", "Hot", "Sweltering", "Scorching"
};
}
}
在这个示例中,我们创建了一个名为WeatherUpdatesProducer的类,它负责生成天气预报数据并将其发布到Kafka的主题中。我们使用Confluent.Kafka库中的IProducer接口来实现与Kafka的通信。
接下来,我们可以创建一个名为WeatherUpdatesConsumer的类,用于订阅Kafka的主题并处理接收到的天气更新消息:
// WeatherUpdatesConsumer.csusing Confluent.Kafka;
using System;
namespaceWebApiDemo
{
publicclassWeatherUpdatesConsumer
{
privatereadonly IConsumer<Ignore, string> _consumer;
public WeatherUpdatesConsumer(string bootstrapServers, string groupId, string topicName)
{
var config = new ConsumerConfig
{
BootstrapServers = bootstrapServers,
GroupId = groupId,
AutoOffsetReset = AutoOffsetReset.Earliest
};
_consumer = new ConsumerBuilder<Ignore, string>(config).Build();
_consumer.Subscribe(topicName);
}
public void ConsumeWeatherUpdates()
{
try
{
while (true)
{
try
{
var message = _consumer.Consume();
Console.WriteLine($"Received weather update: {message.Value}");
}
catch (ConsumeException e)
{
Console.WriteLine($"Error occurred: {e.Error.Reason}");
}
}
}
catch (OperationCanceledException)
{
_consumer.Close();
}
}
}
}
在这个示例中,我们创建了一个名为WeatherUpdatesConsumer的类,它负责订阅Kafka的主题并处理接收到的天气更新消息。我们使用Confluent.Kafka库中的IConsumer接口来实现消费者的功能。
接下来,在Startup.cs中注册WeatherUpdatesProducer和WeatherUpdatesConsumer服务,并在应用启动时分别调用ProduceWeatherUpdates和ConsumeWeatherUpdates方法:
// Startup.csusing Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
namespaceWebApiDemo
{
publicclassStartup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
// 注册WeatherUpdatesProducer服务
services.AddSingleton<WeatherUpdatesProducer>(provider =>
{
var bootstrapServers = Configuration["Kafka:BootstrapServers"];
var topicName = Configuration["Kafka:TopicName"];
returnnew WeatherUpdatesProducer(bootstrapServers, topicName);
});
// 注册WeatherUpdatesConsumer服务
services.AddSingleton<WeatherUpdatesConsumer>(provider =>
{
var bootstrapServers = Configuration["Kafka:BootstrapServers"];
var groupId = Configuration["Kafka:GroupId"];
var topicName = Configuration["Kafka:TopicName"];
returnnew WeatherUpdatesConsumer(bootstrapServers, groupId, topicName);
});
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env, WeatherUpdatesProducer weatherUpdatesProducer, WeatherUpdatesConsumer weatherUpdatesConsumer)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
// 在应用启动时生成天气预报数据并发布到Kafka
weatherUpdatesProducer.ProduceWeatherUpdates();
// 在应用启动时订阅Kafka主题并处理天气更新消息
weatherUpdatesConsumer.ConsumeWeatherUpdates();
}
}
}
在这个示例中,我们使用Configuration来获取Kafka的连接配置信息,并在应用启动时分别调用WeatherUpdatesProducer的ProduceWeatherUpdates方法来生成天气预报数据并发布到Kafka,以及调用WeatherUpdatesConsumer的ConsumeWeatherUpdates方法来订阅Kafka的主题并处理接收到的天气更新消息。
这样,我们就实现了基于Kafka的消息发布和订阅功能。当应用启动时,会生成天气预报数据并发布到Kafka的主题中,同时也会订阅Kafka的主题并处理接收到的天气更新消息。
// WeatherUpdatesProducer.cs
using Confluent.Kafka;
using System;
using System.Threading;
namespace WebApiDemo
{
public class WeatherUpdatesProducer
{
private readonly IProducer<Null, string> _producer;
private readonly string _topicName;
public WeatherUpdatesProducer(string bootstrapServers, string topicName)
{
_topicName = topicName;
var config = new ProducerConfig { BootstrapServers = bootstrapServers };
_producer = new ProducerBuilder<Null, string>(config).Build();
}
public void ProduceWeatherUpdates()
{
var rng = new Random();
for (int i = 0; i < 5; i++)
{
var forecast = new { Date = DateTime.Now.AddDays(i), TemperatureC = rng.Next(-20, 55), Summary = Summaries[rng.Next(Summaries.Length)] }; var message = $"{forecast.Date}: {forecast.Summary}"; _producer.Produce(_topicName, new Message<Null, string> { Value = message }); Thread.Sleep(1000); // 模拟每秒发布一次消息
}
}
private static readonly string[] Summaries = new[] { "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" };
}
}
浙公网安备 33010602011771号