# BeautyNetWebApi **Repository Path**: leafCore/beauty-net-web-api ## Basic Information - **Project Name**: BeautyNetWebApi - **Description**: Beauty.Net 是一个基于.Net8的扩张服务API项目,在这儿你可以看到RabbitMQ、Kafka、Redis、FreeSql、Elasticsearch、rpc服务等多种二次封装,以极简和详实的代码助力小白工程师完成快速的服务搭建和整体规划 - **Primary Language**: C# - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 18 - **Forks**: 1 - **Created**: 2025-11-04 - **Last Updated**: 2026-05-29 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Beauty.NetWebApi 基于 .NET 8 的微服务全家桶框架,对主流中间件进行二次封装,提供统一接口、高可用保障与开箱即用的体验。 ## 核心价值 - **模块化** — 每个中间件独立为 NuGet 风格的类库,按需引用 - **高可用内置** — 各模块自带重试、熔断、降级、健康检查等生产级保障 - **统一接口** — 一致的命名、一致的 DI 注册方式、一致的配置模型 - **开箱即用** — 提供 Demo 控制器、appsettings 示例和 Docker Compose 模板 ## 架构概览 ``` 请求管道 ExceptionHandler → CORS → Swagger → UseRouting → UseAuthorization → 日志中间件 → 响应包装中间件 → HealthChecks → RabbitMQ消费者 → 微服务网关 → MapControllers 模块分层 Beauty.Net.Integration ← 集成层:Consul + Ocelot 协同 Beauty.Net.Middleware ← 横切层:日志、响应包装 Beauty.Net.Ocelot ← 网关层:路由、限流、熔断 Beauty.Net.Consul ← 服务发现:注册、健康检查、负载均衡 Beauty.Net.Cache ← 缓存层:Memory / Redis(FreeRedis) Beauty.Net.Kafka ← 消息队列层:Kafka 生产/消费 Beauty.Net.RabbitMQ ← 消息队列层:6 种 RabbitMQ 模式 Beauty.Net.Elasticsearch ← 搜索层:Elasticsearch 索引/查询 Beauty.Net.MongoDB ← 数据层:MongoDB CRUD Beauty.Net.JsonWebToken ← 认证层:JWT 签发/验证/撤销 Beauty.Net.MiniExcel ← 工具层:Excel 导入导出 ``` ## 项目结构 ``` Beauty.NetWebApi/ ├── Beauty.Net.Cache/ # 缓存模块(内存 / Redis + 熔断 + 防击穿) ├── Beauty.Net.Consul/ # 服务发现(缓存降级 + 多策略负载均衡) ├── Beauty.Net.Elasticsearch/ # 搜索引擎(Sniffing 节点发现 + 批量 API) ├── Beauty.Net.Integration/ # 集成层(Consul + Ocelot 协同) ├── Beauty.Net.JsonWebToken/ # JWT 认证(黑名单撤销 + 精确错误信息) ├── Beauty.Net.Kafka/ # Kafka 消息队列(死信队列 + Lag 监控) ├── Beauty.Net.Middleware/ # 中间件(全链路 TraceId + 慢请求预警) ├── Beauty.Net.MiniExcel/ # Excel 工具(流式 + 文件大小保护) ├── Beauty.Net.MongoDB/ # MongoDB 数据访问(事务 + 重试 + 分页) ├── Beauty.Net.Ocelot/ # API 网关(熔断 + QoS + 配置热重载) ├── Beauty.Net.RabbitMQ/ # RabbitMQ 消息队列(6 模式 + 发布确认 + 通道池) └── Beauty.NetWebApi/ # 主入口项目 ``` ## 模块详解 ### Beauty.Net.Cache — 缓存模块 | 特性 | 说明 | |------|------| | 统一接口 | `ICacheService`,Memory / Redis 自由切换 | | 熔断保护 | 连续失败 N 次自动熔断,30s 后半开尝试恢复 | | 防缓存击穿 | `GetOrSet` 使用 Redis `SETNX` 分布式锁,仅一个线程回源 | | Pipeline 批量 | ≥10 个 key 时自动走 Redis Pipeline | | 滑动过期 | `SetSliding` 方法支持滑动窗口过期 | | 启动验证 | `IHostedService` 启动时 Ping Redis 验证连接 | ```csharp // Program.cs builder.Services.AddMemoryCacheService(); // 内存缓存 builder.Services.AddRedisCacheService("127.0.0.1:6379"); // Redis 缓存 // 使用 app.MapGet("/product/{id}", async (int id, ICacheService cache) => { return await cache.GetOrSetAsync( $"product:{id}", async ct => await db.GetProductAsync(id, ct), // CancellationToken 支持 TimeSpan.FromMinutes(30)); }); ``` ### Beauty.Net.Consul — 服务发现 | 特性 | 说明 | |------|------| | 重试机制 | 注册/查询失败自动重试,指数退避 | | 缓存降级 | 本地缓存服务实例列表,Consul 不可用时回退 | | 负载均衡 | 加权随机 / 轮询(RoundRobin) / 最少连接数 三种策略 | | 批量健康检查 | 一次 API 调用批量获取所有实例健康状态 | | 心跳自愈 | 心跳失败 3 次自动重新注册服务 | ### Beauty.Net.JsonWebToken — JWT 认证 | 特性 | 说明 | |------|------| | 访问令牌 + 刷新令牌 | `CreateAccessToken` / `CreateRefreshToken` | | 令牌撤销 | 内存黑名单 + `Timer` 定期清理过期条目 | | 精确错误信息 | 按异常类型返回 `SecurityTokenExpiredException` → "Token has expired." 等 | | 密钥长度验证 | < 32 字符开发环境警告并补齐,生产环境抛异常 | ### Beauty.Net.Kafka — Kafka 消息队列 | 特性 | 说明 | |------|------| | 生产者重试 | 发送失败指数退避重试 | | 死信队列 | 消费重试耗尽后自动发送到 `{topic}.dlq`,附带异常元数据 | | 单例安全 | `StartConsumeAsync` 可多次调用,先取消旧消费再启动新 | | Lag 监控 | `GetPartitionLag()` 实时查询消费进度 | | 优雅关闭 | 收到取消信号后等待当前消息处理完成 | ### Beauty.Net.RabbitMQ — RabbitMQ 消息队列 | 特性 | 说明 | |------|------| | 6 种消息模式 | Simple / Work / Pub-Sub / Routing / Topic / Headers | | 自动重连 | `ConnectionShutdown` 事件触发后台重连(指数退避) | | 发布确认 | `WaitForConfirmsOrDie` + 重试,保证消息不丢 | | 死信交换机 | 消息 TTL 超时或消费失败后路由到 `dlx.exchange` | | 通道池 | `ConcurrentQueue` 复用 `IModel`,减少创建开销 | | 消费者隔离 | 每个消费者独立 `try-catch`,一个失败不影响其他 | ### Beauty.Net.Elasticsearch — 搜索引擎 | 特性 | 说明 | |------|------| | Sniffing 节点发现 | 动态感知集群拓扑变化 | | 重试机制 | `HttpRequestException` / `TransportException` 自动重试 | | 真正 Bulk API | `BulkIndexAsync` 一次性批量提交,非逐条索引 | | 别名管理 | `PutAliasAsync` / `SwapAliasAsync` 零停机索引切换 | ### Beauty.Net.MongoDB — 数据访问 | 特性 | 说明 | |------|------| | 重试机制 | `MongoConnectionException` / `TimeoutException` 自动指数退避重试 | | 事务支持 | `ExecuteInTransactionAsync` 封装 Session 生命周期 | | 分页查询 | `FindPagedAsync` 一次请求完成 Count + 分页 | | 批量写入 | `BulkWriteAsync` 支持 `InsertOneModel` / `UpdateOneModel` 等 | ### Beauty.Net.Ocelot — API 网关 | 特性 | 说明 | |------|------| | 熔断器 | 连续 N 次异常 → 熔断 30s → 半开探测 | | QoS 并发控制 | MaxConcurrentRequests + Timeout 防止过载 | | 配置热重载 | `FileSystemWatcher` 监听 `ocelot.json` 变更自动热加载 | | 配置回退 | 解析失败时回退到上一个有效配置,不丢失路由 | ### Beauty.Net.Middleware — 中间件 | 特性 | 说明 | |------|------| | 全链路 TraceId | 每个请求生成 UUID TraceId,通过 `HttpContext.Items` 传播 | | 慢请求预警 | 耗时 ≥ 3s 自动 WARNING 级别日志 | | 请求/响应大小保护 | 请求体 > 1MB 截断,响应体 > 1MB 截断,防 OOM | | 请求超时 | 30s 超时返回 504 Gateway Timeout ApiResponse | | 分页响应模型 | `PaginatedResponse` 内置 Page/PageSize/Total/HasNext | ### Beauty.Net.MiniExcel — Excel 工具 | 特性 | 说明 | |------|------| | 文件大小保护 | 默认 50MB 上限,防 OOM | | 流式操作 | `ExportToStreamAsync` / `ImportFromStreamAsync` | | CancellationToken | 全部异步方法支持取消 | ## 快速开始 ### 环境要求 - .NET 8.0 SDK - Visual Studio 2022 / Rider / VS Code ### 启动 ```bash git clone https://gitee.com/leafCore/beauty-net-web-api.git cd Beauty.NetWebApi dotnet restore dotnet run --project Beauty.NetWebApi ``` 启动后访问: ``` Swagger UI → http://localhost:5000/swagger 健康检查 → http://localhost:5000/health ``` ### 配置文件(appsettings.json) 所有模块配置均可通过 `appsettings.json` 管理: ```json { "JwtOptions": { "SecretKey": "your-secret-key-at-least-32-characters", "Issuer": "Beauty.Net", "AccessTokenExpirationMinutes": 30, "RefreshTokenExpirationHours": 24 }, "RabbitMQ": { "HostName": "localhost", "Port": 5672, "EnableAutomaticRecovery": true, "EnablePublisherConfirms": true }, "Kafka": { "BootstrapServers": "localhost:9092", "GroupId": "beauty-net-consumer", "EnableDeadLetterQueue": true }, "Consul": { "Enabled": true, "Address": "http://127.0.0.1:8500", "ServiceName": "Beauty.NetWebApi", "EnableLocalCache": true }, "Ocelot": { "EnableConsulServiceDiscovery": true, "ReLoadOnChange": true } } ``` ### Docker Compose(依赖服务) ```yaml version: "3" services: redis: image: redis:latest ports: ["6379:6379"] rabbitmq: image: rabbitmq:management ports: ["5672:5672", "15672:15672"] kafka: image: confluentinc/cp-kafka:latest ports: ["9092:9092"] environment: KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://localhost:9092 KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1 elasticsearch: image: elasticsearch:8.12.0 ports: ["9200:9200"] environment: discovery.type: single-node xpack.security.enabled: false consul: image: consul:latest ports: ["8500:8500"] mongodb: image: mongo:latest ports: ["27017:27017"] ``` ## 高可用特性一览 | 模式 | Cache | Consul | Kafka | RabbitMQ | ES | MongoDB | Ocelot | |------|:-----:|:------:|:-----:|:--------:|:--:|:-------:|:------:| | 重试+指数退避 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | - | | 熔断器 | ✅ | - | - | - | - | - | ✅ | | 本地缓存降级 | - | ✅ | - | - | - | - | - | | 死信队列 | - | - | ✅ | ✅ | - | - | - | | 发布确认 | - | - | - | ✅ | - | - | - | | 健康检查 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | - | | 优雅关闭 | - | ✅ | ✅ | ✅ | - | - | - | ## 许可证 MIT License. Copyright (c) 2025 Beauty.Net ## 联系方式 - Gitee: [https://gitee.com/leafCore/beauty-net-web-api](https://gitee.com/leafCore/beauty-net-web-api) - Issues: [https://gitee.com/leafCore/beauty-net-web-api/issues](https://gitee.com/leafCore/beauty-net-web-api/issues) - Email: 154571895@qq.com