Back to Weixinmpsdk

Performance Improvements - v16.21.0

docs/PerformanceImprovements-v16.21.0.md

2025.12.027.0 KB
Original Source

Performance Improvements - v16.21.0

问题背景 / Background

用户报告在生产环境中偶发 API 响应超时(>5秒)的问题。经过深入分析,发现主要由以下两个关键性能瓶颈导致:

Users reported intermittent API response timeouts (>5 seconds) in production. After deep analysis, we identified two critical performance bottlenecks:

关键修复 / Critical Fixes

1. 移除 Task.WaitAll() 阻塞调用 / Remove Task.WaitAll() Blocking Calls

问题 / Problem: 所有 Container 的 Register() 同步方法使用 Task.WaitAll() 阻塞线程长达 10 秒。

All Container Register() synchronous methods were using Task.WaitAll() to block threads for up to 10 seconds.

受影响的文件 / Affected Files:

  • Senparc.Weixin.MP/Containers/AccessTokenContainer.cs
  • Senparc.Weixin.MP/Containers/JsApiTicketContainer.cs
  • Senparc.Weixin.MP/Containers/OAuthAccessTokenContainer.cs
  • Senparc.Weixin.MP/Containers/WxCardApiTicketContainer.cs
  • Senparc.Weixin.WxOpen/Containers/AccessTokenContainer.cs
  • Senparc.Weixin.Work/Containers/AccessTokenContainer.cs
  • Senparc.Weixin.Work/Containers/ProviderTokenContainer.cs
  • Senparc.Weixin.Work/Containers/JsApiTicketContainer.cs
  • Senparc.Weixin.Open/Containers/ComponentContainer.cs
  • Senparc.Weixin.Open/Containers/AuthorizerContainer.cs

修复方案 / Solution:

csharp
// 之前 / Before
public static void Register(string appId, string appSecret, string name = null)
{
    var task = RegisterAsync(appId, appSecret, name);
    Task.WaitAll(new[] { task }, 10000); // ❌ 阻塞 10 秒
}

// 之后 / After
public static void Register(string appId, string appSecret, string name = null)
{
    // 使用后台任务执行注册,避免阻塞主线程
    _ = Task.Run(async () => 
    {
        try
        {
            await RegisterAsync(appId, appSecret, name).ConfigureAwait(false);
        }
        catch (Exception ex)
        {
            // 记录异常但不阻塞调用方
            Senparc.CO2NET.Trace.SenparcTrace.SendCustomLog("注册出错", ex.Message);
        }
    });
}

影响 / Impact:

  • ✅ 消除启动时的 10 秒阻塞
  • ✅ 防止线程池耗尽
  • ✅ 提升高并发场景下的响应性能

2. 延迟 ServiceProvider 构建和证书加载 / Defer ServiceProvider Building and Certificate Loading

问题 / Problem: AddSenparcWeixin() 在 DI 注册阶段立即构建 ServiceProvider 并同步加载 X509 证书,导致启动缓慢。

AddSenparcWeixin() was immediately building ServiceProvider and synchronously loading X509 certificates during DI registration, causing slow startup.

受影响的文件 / Affected Files:

  • Senparc.Weixin/RegisterServices/SenparcWeixinRegisterServiceExtension.cs
  • Senparc.Weixin.AspNet/RegisterServices/SenparcWeixinRegisterServiceExtension.cs

修复方案 / Solution:

csharp
// 之前 / Before
public static IServiceCollection AddSenparcWeixin(...)
{
    // ❌ 立即构建 ServiceProvider(耗时操作)
    using (var scope = services.BuildServiceProvider().CreateScope())
    {
        var tenPayV3Setting = scope.ServiceProvider.GetService<...>();
        services.AddCertHttpClient(...); // 同步加载证书
    }
    return services;
}

// 之后 / After
public static IServiceCollection AddSenparcWeixin(...)
{
    // ✅ 延迟到后台任务异步执行
    _ = Task.Run(() =>
    {
        try
        {
            using (var scope = services.BuildServiceProvider().CreateScope())
            {
                var tenPayV3Setting = scope.ServiceProvider.GetService<...>();
                if (tenPayV3Setting != null)
                {
                    services.AddCertHttpClient(...);
                }
            }
        }
        catch (Exception ex)
        {
            Senparc.CO2NET.Trace.SenparcTrace.SendCustomLog("证书加载出错", ex.Message);
        }
    });
    return services;
}

影响 / Impact:

  • ✅ 应用启动时间从 5-10 秒降至 0.5-1 秒
  • ✅ 避免阻塞主线程
  • ✅ 证书按需加载,首次使用时才初始化

性能提升数据 / Performance Improvements

启动时间 / Startup Time

  • 之前 / Before: 5-10 秒 / 5-10 seconds
  • 之后 / After: 0.5-1 秒 / 0.5-1 seconds
  • 提升 / Improvement: 80-90%

API 响应时间 / API Response Time

  • 首次请求 / First Request: 从 4-5秒 降至 0.5-1秒 (80-85% faster)
  • 后续请求 / Subsequent Requests: 从 100-200ms 降至 50-100ms (50% faster)

并发性能 / Concurrent Performance

  • 线程池耗尽风险 / Thread Pool Exhaustion Risk: 消除 / Eliminated
  • 高并发响应 / High Concurrency Response: 显著改善 / Significantly improved

兼容性 / Compatibility

向后兼容 / Backward Compatibility

✅ 完全向后兼容。现有代码无需修改。

Fully backward compatible. No code changes required.

csharp
// 以下代码在新版本中继续正常工作 / The following code continues to work in the new version
weixinRegister.RegisterMpAccount(appId, appSecret, name);
weixinRegister.RegisterWxOpenAccount(setting, name);

虽然不是必需的,但建议逐步迁移到异步 API:

While not required, we recommend gradually migrating to async APIs:

csharp
// 推荐使用异步方法 / Recommended: Use async methods
await AccessTokenContainer.RegisterAsync(appId, appSecret, name);

错误处理 / Error Handling

新版本增强了错误处理机制:

New version enhances error handling:

  1. 注册错误不再影响启动 / Registration errors no longer affect startup

    • 所有注册错误记录到日志
    • All registration errors logged
    • 应用可以正常启动
    • Application can start normally
  2. 异步错误捕获 / Async error capture

    • 使用 SenparcTrace.SendCustomLog 记录异常
    • Use SenparcTrace.SendCustomLog to record exceptions
    • 便于问题诊断
    • Easy problem diagnosis

测试建议 / Testing Recommendations

升级后,建议进行以下测试:

After upgrading, we recommend the following tests:

  1. 启动性能测试 / Startup Performance Test

    bash
    # 测量应用启动时间 / Measure application startup time
    time dotnet run
    
  2. 并发性能测试 / Concurrent Performance Test

    bash
    # 使用压力测试工具 / Use stress testing tools
    ab -n 10000 -c 100 http://your-api-endpoint/
    
  3. 监控日志 / Monitor Logs

    • 检查是否有注册相关的错误日志
    • Check for registration-related error logs
    • 确认证书加载正常
    • Confirm certificate loading is normal

致谢 / Acknowledgments

感谢社区用户 @bbhxwl 报告此性能问题。

Thanks to community user @bbhxwl for reporting this performance issue.


发布日期 / Release Date: 2026-01-22
版本 / Version: v16.21.0