From 8991118f8df83031c42c178d562a2ab5ebd0391b Mon Sep 17 00:00:00 2001 From: zpc Date: Tue, 10 Feb 2026 17:22:38 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8D=E5=8F=91=E8=B4=A7?= =?UTF-8?q?=E9=87=8D=E8=AF=95=E5=90=8E=E5=8F=B0=E6=9C=8D=E5=8A=A1=E4=B8=8D?= =?UTF-8?q?=E6=89=A7=E8=A1=8C=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 使用 IServiceScopeFactory 解决 scoped 服务依赖问题 - IWechatService 是 scoped 服务,不能直接注入到 singleton 后台服务 - 每次处理订单时创建新的 scope 来解析 IWechatService - 将检查间隔从 60 秒改为 30 秒 - 优化 RedisService.GetKeysAsync 使用实时连接状态检查 --- .../ShippingRetryBackgroundService.cs | 39 ++++++++++++++----- .../Cache/RedisService.cs | 9 ++++- 2 files changed, 37 insertions(+), 11 deletions(-) diff --git a/server/HoneyBox/src/HoneyBox.Core/Services/ShippingRetryBackgroundService.cs b/server/HoneyBox/src/HoneyBox.Core/Services/ShippingRetryBackgroundService.cs index f2bd4c16..4ff27f06 100644 --- a/server/HoneyBox/src/HoneyBox.Core/Services/ShippingRetryBackgroundService.cs +++ b/server/HoneyBox/src/HoneyBox.Core/Services/ShippingRetryBackgroundService.cs @@ -1,6 +1,7 @@ using System.Text.Json; using HoneyBox.Core.Interfaces; using HoneyBox.Model.Models.Auth; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; using Microsoft.Extensions.Logging; @@ -12,22 +13,22 @@ namespace HoneyBox.Core.Services; /// public class ShippingRetryBackgroundService : BackgroundService { + private readonly IServiceScopeFactory _scopeFactory; private readonly IRedisService _redisService; - private readonly IWechatService _wechatService; private readonly ILogger _logger; private const int MaxRetryCount = 10; // 最大重试次数 private const int RetryIntervalSeconds = 30; // 重试间隔(秒) - private const int CheckIntervalSeconds = 60; // 检查间隔(秒) + private const int CheckIntervalSeconds = 30; // 检查间隔(秒) private const string RetryKeyPattern = "post_order:*"; public ShippingRetryBackgroundService( + IServiceScopeFactory scopeFactory, IRedisService redisService, - IWechatService wechatService, ILogger logger) { + _scopeFactory = scopeFactory; _redisService = redisService; - _wechatService = wechatService; _logger = logger; } @@ -35,19 +36,32 @@ public class ShippingRetryBackgroundService : BackgroundService { _logger.LogInformation("发货重试后台服务已启动"); + // 启动时等待一小段时间,让其他服务初始化完成 + await Task.Delay(TimeSpan.FromSeconds(5), stoppingToken); + while (!stoppingToken.IsCancellationRequested) { try { await ProcessFailedShippingOrdersAsync(stoppingToken); } + catch (OperationCanceledException) when (stoppingToken.IsCancellationRequested) + { + break; + } catch (Exception ex) { _logger.LogError(ex, "处理发货重试时发生异常"); } - // 等待下一次检查 - await Task.Delay(TimeSpan.FromSeconds(CheckIntervalSeconds), stoppingToken); + try + { + await Task.Delay(TimeSpan.FromSeconds(CheckIntervalSeconds), stoppingToken); + } + catch (OperationCanceledException) when (stoppingToken.IsCancellationRequested) + { + break; + } } _logger.LogInformation("发货重试后台服务已停止"); @@ -63,11 +77,12 @@ public class ShippingRetryBackgroundService : BackgroundService return; } - _logger.LogDebug("发现 {Count} 个待重试的发货订单", failedOrderKeys.Count()); + var keysList = failedOrderKeys.ToList(); + _logger.LogInformation("发现 {Count} 个待重试的发货订单", keysList.Count); var nowTime = DateTimeOffset.UtcNow.ToUnixTimeSeconds(); - foreach (var key in failedOrderKeys) + foreach (var key in keysList) { if (stoppingToken.IsCancellationRequested) break; @@ -83,6 +98,7 @@ public class ShippingRetryBackgroundService : BackgroundService } } + private async Task ProcessSingleOrderAsync(string key, long nowTime) { // 获取订单数据 @@ -125,17 +141,20 @@ public class ShippingRetryBackgroundService : BackgroundService return; } - // 尝试重新发货 + // 尝试重新发货 - 使用新的 scope 来解析 IWechatService _logger.LogInformation("开始重试发货: OrderNo={OrderNo}, RetryCount={RetryCount}", orderData.order_num, orderData.retry_count + 1); + using var scope = _scopeFactory.CreateScope(); + var wechatService = scope.ServiceProvider.GetRequiredService(); + var request = new WechatShippingRequest { OpenId = orderData.openid, OrderNo = orderData.order_num }; - var result = await _wechatService.UploadShippingInfoAsync(request); + var result = await wechatService.UploadShippingInfoAsync(request); if (result.Success) { diff --git a/server/HoneyBox/src/HoneyBox.Infrastructure/Cache/RedisService.cs b/server/HoneyBox/src/HoneyBox.Infrastructure/Cache/RedisService.cs index b21a2162..916569e7 100644 --- a/server/HoneyBox/src/HoneyBox.Infrastructure/Cache/RedisService.cs +++ b/server/HoneyBox/src/HoneyBox.Infrastructure/Cache/RedisService.cs @@ -107,7 +107,11 @@ public class RedisService : IRedisService, IDisposable public async Task> GetKeysAsync(string pattern) { - if (_connection == null || !_isConnected) + if (_connection == null) + return Enumerable.Empty(); + + // 检查当前连接状态(而不是构造时的状态) + if (!_connection.IsConnected) return Enumerable.Empty(); var keys = new List(); @@ -116,6 +120,9 @@ public class RedisService : IRedisService, IDisposable foreach (var endpoint in endpoints) { var server = _connection.GetServer(endpoint); + if (server == null || !server.IsConnected) + continue; + await foreach (var key in server.KeysAsync(pattern: pattern)) { keys.Add(key.ToString());