From e6327a57df6fb8c229dc394435e751c31d104b57 Mon Sep 17 00:00:00 2001 From: zenghongyao <873884283@qq.com> Date: Fri, 18 Apr 2025 09:29:38 +0800 Subject: [PATCH] =?UTF-8?q?=E5=90=88=E5=B9=B6=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ConsoleApplicationBuilder.cs | 72 +++++++ .../JiShe.CollectBus.Kafka.Test.csproj | 40 ++++ .../KafkaProduceBenchmark.cs | 108 +++++++++++ .../KafkaSubscribeTest.cs | 68 +++++++ .../Lib/JiShe.CollectBus.Kafka.dll | Bin 0 -> 59904 bytes .../JiShe.CollectBus.Kafka.Test/Program.cs | 172 +++++++++++++++++ .../appsettings.json | 180 ++++++++++++++++++ 7 files changed, 640 insertions(+) create mode 100644 modules/JiShe.CollectBus.Kafka.Test/ConsoleApplicationBuilder.cs create mode 100644 modules/JiShe.CollectBus.Kafka.Test/JiShe.CollectBus.Kafka.Test.csproj create mode 100644 modules/JiShe.CollectBus.Kafka.Test/KafkaProduceBenchmark.cs create mode 100644 modules/JiShe.CollectBus.Kafka.Test/KafkaSubscribeTest.cs create mode 100644 modules/JiShe.CollectBus.Kafka.Test/Lib/JiShe.CollectBus.Kafka.dll create mode 100644 modules/JiShe.CollectBus.Kafka.Test/Program.cs create mode 100644 modules/JiShe.CollectBus.Kafka.Test/appsettings.json diff --git a/modules/JiShe.CollectBus.Kafka.Test/ConsoleApplicationBuilder.cs b/modules/JiShe.CollectBus.Kafka.Test/ConsoleApplicationBuilder.cs new file mode 100644 index 0000000..f6b0891 --- /dev/null +++ b/modules/JiShe.CollectBus.Kafka.Test/ConsoleApplicationBuilder.cs @@ -0,0 +1,72 @@ +using Microsoft.AspNetCore.Builder; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Http.Features; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace JiShe.CollectBus.Kafka.Test +{ + public class ConsoleApplicationBuilder: IApplicationBuilder + { + public IServiceProvider ApplicationServices { get; set; } + public IDictionary Properties { get; set; } = new Dictionary(); + + public IFeatureCollection ServerFeatures => throw new NotImplementedException(); + + private readonly List> _middlewares = new(); + + public IApplicationBuilder Use(Func middleware) + { + _middlewares.Add(middleware); + return this; + } + + public RequestDelegate Build() + { + RequestDelegate app = context => Task.CompletedTask; + foreach (var middleware in _middlewares) + { + app = middleware(app); + } + return app; + } + + public IApplicationBuilder New() + { + return new ConsoleApplicationBuilder + { + ApplicationServices = this.ApplicationServices, + Properties = new Dictionary(this.Properties) + }; + } + } + + + public static class HostBuilderExtensions + { + public static IHostBuilder ConfigureConsoleAppBuilder( + this IHostBuilder hostBuilder, + Action configure) + { + hostBuilder.ConfigureServices((context, services) => + { + // 注册 ConsoleApplicationBuilder 到 DI 容器 + services.AddSingleton(provider => + { + var appBuilder = new ConsoleApplicationBuilder + { + ApplicationServices = provider // 注入服务提供者 + }; + configure(appBuilder); // 执行配置委托 + return appBuilder; + }); + }); + return hostBuilder; + } + } +} diff --git a/modules/JiShe.CollectBus.Kafka.Test/JiShe.CollectBus.Kafka.Test.csproj b/modules/JiShe.CollectBus.Kafka.Test/JiShe.CollectBus.Kafka.Test.csproj new file mode 100644 index 0000000..db97b00 --- /dev/null +++ b/modules/JiShe.CollectBus.Kafka.Test/JiShe.CollectBus.Kafka.Test.csproj @@ -0,0 +1,40 @@ + + + + Exe + net8.0 + enable + enable + + + + + Always + true + PreserveNewest + + + + + + + + + + + + + + + + + + + + + + diff --git a/modules/JiShe.CollectBus.Kafka.Test/KafkaProduceBenchmark.cs b/modules/JiShe.CollectBus.Kafka.Test/KafkaProduceBenchmark.cs new file mode 100644 index 0000000..a8b8d93 --- /dev/null +++ b/modules/JiShe.CollectBus.Kafka.Test/KafkaProduceBenchmark.cs @@ -0,0 +1,108 @@ +using BenchmarkDotNet.Attributes; +using BenchmarkDotNet.Jobs; +using Confluent.Kafka; +using JiShe.CollectBus.Kafka.AdminClient; +using JiShe.CollectBus.Kafka.Consumer; +using JiShe.CollectBus.Kafka.Producer; + +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Logging; +using Serilog; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace JiShe.CollectBus.Kafka.Test +{ + [SimpleJob(RuntimeMoniker.Net80)] + //[SimpleJob(RuntimeMoniker.NativeAot80)] + [RPlotExporter] + public class KafkaProduceBenchmark + { + + // 每批消息数量 + [Params(1000, 10000, 100000)] + public int N; + public ServiceProvider _serviceProvider; + public IConsumerService _consumerService; + public IProducerService _producerService; + public string topic = "test-topic1"; + + [GlobalSetup] + public void Setup() + { + // 构建配置 + var config = new ConfigurationBuilder() + .SetBasePath(Directory.GetCurrentDirectory()) + .AddJsonFile("appsettings.json") + .Build(); + // 直接读取配置项 + var greeting = config["ServerTagName"]; + Console.WriteLine(greeting); // 输出: Hello, World! + // 创建服务容器 + var services = new ServiceCollection(); + // 注册 IConfiguration 实例 + services.AddSingleton(config); + + // 初始化日志 + Log.Logger = new LoggerConfiguration() + .ReadFrom.Configuration(config) // 从 appsettings.json 读取配置 + .CreateLogger(); + + // 配置日志系统 + services.AddLogging(logging => + { + logging.ClearProviders(); + logging.AddSerilog(); + }); + services.AddSingleton(); + services.AddSingleton(); + services.AddSingleton(); + + // 构建ServiceProvider + _serviceProvider = services.BuildServiceProvider(); + + // 获取日志记录器工厂 + var loggerFactory = _serviceProvider.GetRequiredService(); + var logger = loggerFactory.CreateLogger(); + logger.LogInformation("程序启动"); + + var adminClientService = _serviceProvider.GetRequiredService(); + + + //await adminClientService.DeleteTopicAsync(topic); + // 创建 topic + adminClientService.CreateTopicAsync(topic, 3, 3).ConfigureAwait(false).GetAwaiter(); + + _consumerService = _serviceProvider.GetRequiredService(); + + _producerService = _serviceProvider.GetRequiredService(); + } + + [Benchmark] + public async Task UseAsync() + { + List tasks = new(); + for (int i = 0; i < N; ++i) + { + var task = _producerService.ProduceAsync(topic, i.ToString()); + tasks.Add(task); + } + await Task.WhenAll(tasks); + } + + [Benchmark] + public async Task UseLibrd() + { + List tasks = new(); + for (int i = 0; i < N; ++i) + { + var task = _producerService.ProduceAsync(topic, i.ToString(),null); + } + await Task.WhenAll(tasks); + } + } +} diff --git a/modules/JiShe.CollectBus.Kafka.Test/KafkaSubscribeTest.cs b/modules/JiShe.CollectBus.Kafka.Test/KafkaSubscribeTest.cs new file mode 100644 index 0000000..4c06e22 --- /dev/null +++ b/modules/JiShe.CollectBus.Kafka.Test/KafkaSubscribeTest.cs @@ -0,0 +1,68 @@ +using JiShe.CollectBus.Common.Consts; +using JiShe.CollectBus.Common.Enums; +using JiShe.CollectBus.Common.Models; +using JiShe.CollectBus.IotSystems.MessageReceiveds; +using JiShe.CollectBus.Kafka.Attributes; +using Microsoft.Extensions.DependencyInjection; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Text.Json; +using System.Threading.Tasks; +using Volo.Abp.Timing; + +namespace JiShe.CollectBus.Kafka.Test +{ + public class KafkaSubscribeTest: IKafkaSubscribe + { + [KafkaSubscribe(ProtocolConst.TESTTOPIC, EnableBatch=false,BatchSize=1000)] + + public async Task KafkaSubscribeAsync(object obj) + { + Console.WriteLine($"收到订阅消息: {JsonSerializer.Serialize(obj)}"); + return SubscribeAck.Success(); + } + + + [KafkaSubscribe(ProtocolConst.SubscriberLoginIssuedEventName)] + //[CapSubscribe(ProtocolConst.SubscriberLoginIssuedEventName)] + public async Task LoginIssuedEvent(IssuedEventMessage issuedEventMessage) + { + Console.WriteLine($"收到订阅消息: {JsonSerializer.Serialize(issuedEventMessage)}"); + return SubscribeAck.Success(); + } + + [KafkaSubscribe(ProtocolConst.SubscriberHeartbeatIssuedEventName)] + //[CapSubscribe(ProtocolConst.SubscriberHeartbeatIssuedEventName)] + public async Task HeartbeatIssuedEvent(IssuedEventMessage issuedEventMessage) + { + Console.WriteLine($"收到订阅消息: {JsonSerializer.Serialize(issuedEventMessage)}"); + return SubscribeAck.Success(); + } + + [KafkaSubscribe(ProtocolConst.SubscriberReceivedEventName)] + //[CapSubscribe(ProtocolConst.SubscriberReceivedEventName)] + public async Task ReceivedEvent(MessageReceived receivedMessage) + { + Console.WriteLine($"收到订阅消息: {JsonSerializer.Serialize(receivedMessage)}"); + return SubscribeAck.Success(); + } + + [KafkaSubscribe(ProtocolConst.SubscriberHeartbeatReceivedEventName)] + //[CapSubscribe(ProtocolConst.SubscriberHeartbeatReceivedEventName)] + public async Task ReceivedHeartbeatEvent(MessageReceivedHeartbeat receivedHeartbeatMessage) + { + Console.WriteLine($"收到订阅消息: {JsonSerializer.Serialize(receivedHeartbeatMessage)}"); + return SubscribeAck.Success(); + } + + [KafkaSubscribe(ProtocolConst.SubscriberLoginReceivedEventName)] + //[CapSubscribe(ProtocolConst.SubscriberLoginReceivedEventName)] + public async Task ReceivedLoginEvent(MessageReceivedLogin receivedLoginMessage) + { + Console.WriteLine($"收到订阅消息: {JsonSerializer.Serialize(receivedLoginMessage)}"); + return SubscribeAck.Success(); + } + } +} diff --git a/modules/JiShe.CollectBus.Kafka.Test/Lib/JiShe.CollectBus.Kafka.dll b/modules/JiShe.CollectBus.Kafka.Test/Lib/JiShe.CollectBus.Kafka.dll new file mode 100644 index 0000000000000000000000000000000000000000..7ca63d6d702394a85aa034669c75c10d3f975481 GIT binary patch literal 59904 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 literal 0 HcmV?d00001 diff --git a/modules/JiShe.CollectBus.Kafka.Test/Program.cs b/modules/JiShe.CollectBus.Kafka.Test/Program.cs new file mode 100644 index 0000000..a359e14 --- /dev/null +++ b/modules/JiShe.CollectBus.Kafka.Test/Program.cs @@ -0,0 +1,172 @@ +// See https://aka.ms/new-console-template for more information +using BenchmarkDotNet.Configs; +using BenchmarkDotNet.Running; +using Confluent.Kafka; +using DeviceDetectorNET.Parser.Device; +using JiShe.CollectBus.Common.Consts; +using JiShe.CollectBus.Kafka; +using JiShe.CollectBus.Kafka.AdminClient; +using JiShe.CollectBus.Kafka.Consumer; +using JiShe.CollectBus.Kafka.Producer; +using JiShe.CollectBus.Kafka.Test; +using Microsoft.AspNetCore.Builder; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; +using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Options; +using Serilog; +using System.Diagnostics; +using System.Reflection; +using System.Reflection.PortableExecutable; +using System.Text.Json; + +#region 基准测试 +//var summary = BenchmarkRunner.Run(); +//Console.WriteLine("压测完成"); +//return; +#endregion 基准测试 + + +var host = Host.CreateDefaultBuilder(args) + .ConfigureServices(services => + { + // 构建配置 + var config = new ConfigurationBuilder() + .SetBasePath(Directory.GetCurrentDirectory()) + .AddJsonFile("appsettings.json") + .Build(); + // 直接读取配置项 + var greeting = config["Kafka:ServerTagName"]; + Console.WriteLine(greeting); // 输出: Hello, World! + + + // 创建服务容器 + //var services = new ServiceCollection(); + // 注册 IConfiguration 实例 + services.AddSingleton(config); + + // 初始化日志 + Log.Logger = new LoggerConfiguration() + .ReadFrom.Configuration(config) // 从 appsettings.json 读取配置 + .CreateLogger(); + + // 配置日志系统 + services.AddLogging(logging => + { + logging.ClearProviders(); + logging.AddSerilog(); + }); + services.Configure(config.GetSection("Kafka")); + + services.AddSingleton(); + services.AddSingleton(); + services.AddSingleton(); + services.AddTransient(); + + }) + .ConfigureConsoleAppBuilder(appBuilder => + { + + }) + .Build(); + + + await host.StartAsync(); + var appBuilder = host.Services.GetRequiredService(); + appBuilder.ApplicationServices.UseKafkaSubscribe(); + + +// 构建ServiceProvider +//var serviceProvider = services.BuildServiceProvider(); + +// 获取日志记录器工厂 +var loggerFactory = host.Services.GetRequiredService(); +var logger = loggerFactory.CreateLogger(); +logger.LogInformation("程序启动"); +var adminClientService = host.Services.GetRequiredService(); +var configuration = host.Services.GetRequiredService(); +string topic = "test-topic"; +//await adminClientService.DeleteTopicAsync(topic); +// 创建 topic +//await adminClientService.CreateTopicAsync(topic, configuration.GetValue(CommonConst.NumPartitions), 3); + +var consumerService = host.Services.GetRequiredService(); +//var kafkaOptions = host.Services.GetRequiredService>(); +//await consumerService.SubscribeAsync(topic, (message) => +//{ +// try +// { +// logger.LogInformation($"消费消息:{message}"); +// return Task.FromResult(true); + +// } +// catch (ConsumeException ex) +// { +// // 处理消费错误 +// logger.LogError($"kafka消费异常:{ex.Message}"); +// } +// return Task.FromResult(false); +//}, "default"); + +//Stopwatch stopwatch = Stopwatch.StartNew(); + +//for (int i = 0; i < 3; i++) +//{ +// await consumerService.SubscribeBatchAsync(topic, (message) => +// { +// try +// { +// int index = 0; +// logger.LogInformation($"消费消息_{index}消费总数:{message.Count()}:{JsonSerializer.Serialize(message)}"); +// return Task.FromResult(true); + +// } +// catch (ConsumeException ex) +// { +// // 处理消费错误 +// logger.LogError($"kafka消费异常:{ex.Message}"); +// } +// return Task.FromResult(false); +// }); +//} +//stopwatch.Stop(); +//Console.WriteLine($"耗时: {stopwatch.ElapsedMilliseconds} 毫秒,{stopwatch.ElapsedMilliseconds/1000} 秒"); + +var producerService = host.Services.GetRequiredService(); +//int num = 840; +//while (num <= 900) +//{ +// //await producerService.ProduceAsync(topic, new TestTopic { Topic = topic, Val = i }); +// await producerService.ProduceAsync(topic, num.ToString()); +// num++; +//} +await Task.Factory.StartNew(async() => { + int num = 0; + while (true) + { + //await producerService.ProduceAsync(topic, new TestTopic { Topic = topic, Val = i }); + await producerService.ProduceAsync(topic, num.ToString()); + num++; + } +}); +Console.WriteLine("\n按Esc键退出"); +while (true) +{ + var key = Console.ReadKey(intercept: true); // intercept:true 隐藏按键显示 + + if (key.Key == ConsoleKey.Escape) + { + await host.StopAsync(); + Console.WriteLine("\n程序已退出"); + break; + } +} +(host.Services as IDisposable)?.Dispose(); + + +public class TestTopic +{ + public string Topic { get; set; } + public int Val { get; set; } +} \ No newline at end of file diff --git a/modules/JiShe.CollectBus.Kafka.Test/appsettings.json b/modules/JiShe.CollectBus.Kafka.Test/appsettings.json new file mode 100644 index 0000000..b2579c6 --- /dev/null +++ b/modules/JiShe.CollectBus.Kafka.Test/appsettings.json @@ -0,0 +1,180 @@ +{ + "Serilog": { + "Using": [ + "Serilog.Sinks.Console", + "Serilog.Sinks.File" + ], + "MinimumLevel": { + "Default": "Information", + "Override": { + "Microsoft": "Warning", + "Volo.Abp": "Warning", + "Hangfire": "Warning", + "DotNetCore.CAP": "Warning", + "Serilog.AspNetCore": "Information", + "Microsoft.EntityFrameworkCore": "Warning", + "Microsoft.AspNetCore": "Warning" + } + }, + "WriteTo": [ + { + "Name": "Console" + }, + { + "Name": "File", + "Args": { + "path": "logs/logs-.txt", + "rollingInterval": "Day" + } + } + ] + }, + "App": { + "SelfUrl": "http://localhost:44315", + "CorsOrigins": "http://localhost:4200,http://localhost:3100" + }, + "ConnectionStrings": { + "Default": "mongodb://admin:admin02023@118.190.144.92:37117,118.190.144.92:37119,118.190.144.92:37120/JiSheCollectBus?authSource=admin&maxPoolSize=400&minPoolSize=10&waitQueueTimeoutMS=5000", + "Kafka": "192.168.1.9:29092,192.168.1.9:39092,192.168.1.9:49092", + "PrepayDB": "server=118.190.144.92;database=jishe.sysdb;uid=sa;pwd=admin@2023;Encrypt=False;Trust Server Certificate=False", + "EnergyDB": "server=118.190.144.92;database=db_energy;uid=sa;pwd=admin@2023;Encrypt=False;Trust Server Certificate=False" + }, + "Redis": { + "Configuration": "192.168.1.9:6380,password=1q2w3e!@#,syncTimeout=30000,abortConnect=false,connectTimeout=30000,allowAdmin=true", + "MaxPoolSize": "50", + "DefaultDB": "14", + "HangfireDB": "15" + }, + "Jwt": { + "Audience": "JiShe.CollectBus", + "SecurityKey": "dzehzRz9a8asdfasfdadfasdfasdfafsdadfasbasdf=", + "Issuer": "JiShe.CollectBus", + "ExpirationTime": 2 + }, + "HealthCheck": { + "IsEnable": true, + "MySql": { + "IsEnable": true + }, + "Pings": { + "IsEnable": true, + "Host": "https://www.baidu.com/", + "TimeOut": 5000 + } + }, + "SwaggerConfig": [ + { + "GroupName": "Basic", + "Title": "【后台管理】基础模块", + "Version": "V1" + }, + { + "GroupName": "Business", + "Title": "【后台管理】业务模块", + "Version": "V1" + } + ], + "Cap": { + "RabbitMq": { + "HostName": "118.190.144.92", + "UserName": "collectbus", + "Password": "123456", + "Port": 5672 + } + }, + "Kafka": { + "BootstrapServers": "192.168.1.9:29092,192.168.1.9:39092,192.168.1.9:49092", + "EnableFilter": true, + "EnableAuthorization": false, + "SecurityProtocol": "SaslPlaintext", + "SaslMechanism": "Plain", + "SaslUserName": "lixiao", + "SaslPassword": "lixiao1980", + "KafkaReplicationFactor": 3, + "NumPartitions": 1, + "ServerTagName": "JiSheCollectBus2" + //"Topic": { + // "ReplicationFactor": 3, + // "NumPartitions": 1000 + //} + }, + //"Kafka": { + // "Connections": { + // "Default": { + // "BootstrapServers": "192.168.1.9:29092,192.168.1.9:39092,192.168.1.9:49092" + // // "SecurityProtocol": "SASL_PLAINTEXT", + // // "SaslMechanism": "PLAIN", + // // "SaslUserName": "lixiao", + // // "SaslPassword": "lixiao1980", + // } + // }, + // "Consumer": { + // "GroupId": "JiShe.CollectBus" + // }, + // "Producer": { + // "MessageTimeoutMs": 6000, + // "Acks": -1 + // }, + // "Topic": { + // "ReplicationFactor": 3, + // "NumPartitions": 1000 + // }, + // "EventBus": { + // "GroupId": "JiShe.CollectBus", + // "TopicName": "DefaultTopicName" + // } + //}, + "IoTDBOptions": { + "UserName": "root", + "Password": "root", + "ClusterList": [ "192.168.1.9:6667" ], + "PoolSize": 2, + "DataBaseName": "energy", + "OpenDebugMode": true, + "UseTableSessionPoolByDefault": false + }, + "ServerTagName": "JiSheCollectBus3", + "Cassandra": { + "ReplicationStrategy": { + "Class": "NetworkTopologyStrategy", //策略为NetworkTopologyStrategy时才会有多个数据中心,SimpleStrategy用在只有一个数据中心的情况下 + "DataCenters": [ + { + "Name": "dc1", + "ReplicationFactor": 3 + } + ] + }, + "Nodes": [ + { + "Host": "192.168.1.9", + "Port": 9042, + "DataCenter": "dc1", + "Rack": "RAC1" + }, + { + "Host": "192.168.1.9", + "Port": 9043, + "DataCenter": "dc1", + "Rack": "RAC2" + } + ], + "Username": "admin", + "Password": "lixiao1980", + "Keyspace": "jishecollectbus", + "ConsistencyLevel": "Quorum", + "PoolingOptions": { + "CoreConnectionsPerHost": 4, + "MaxConnectionsPerHost": 8, + "MaxRequestsPerConnection": 2000 + }, + "SocketOptions": { + "ConnectTimeoutMillis": 10000, + "ReadTimeoutMillis": 20000 + }, + "QueryOptions": { + "ConsistencyLevel": "Quorum", + "SerialConsistencyLevel": "Serial", + "DefaultIdempotence": true + } + } +} \ No newline at end of file