docs/PerformanceImprovements-v16.21.0.md
用户报告在生产环境中偶发 API 响应超时(>5秒)的问题。经过深入分析,发现主要由以下两个关键性能瓶颈导致:
Users reported intermittent API response timeouts (>5 seconds) in production. After deep analysis, we identified two critical performance bottlenecks:
问题 / 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.csSenparc.Weixin.MP/Containers/JsApiTicketContainer.csSenparc.Weixin.MP/Containers/OAuthAccessTokenContainer.csSenparc.Weixin.MP/Containers/WxCardApiTicketContainer.csSenparc.Weixin.WxOpen/Containers/AccessTokenContainer.csSenparc.Weixin.Work/Containers/AccessTokenContainer.csSenparc.Weixin.Work/Containers/ProviderTokenContainer.csSenparc.Weixin.Work/Containers/JsApiTicketContainer.csSenparc.Weixin.Open/Containers/ComponentContainer.csSenparc.Weixin.Open/Containers/AuthorizerContainer.cs修复方案 / Solution:
// 之前 / 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:
问题 / 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.csSenparc.Weixin.AspNet/RegisterServices/SenparcWeixinRegisterServiceExtension.cs修复方案 / Solution:
// 之前 / 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:
✅ 完全向后兼容。现有代码无需修改。
Fully backward compatible. No code changes required.
// 以下代码在新版本中继续正常工作 / 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:
// 推荐使用异步方法 / Recommended: Use async methods
await AccessTokenContainer.RegisterAsync(appId, appSecret, name);
新版本增强了错误处理机制:
New version enhances error handling:
注册错误不再影响启动 / Registration errors no longer affect startup
异步错误捕获 / Async error capture
SenparcTrace.SendCustomLog 记录异常SenparcTrace.SendCustomLog to record exceptions升级后,建议进行以下测试:
After upgrading, we recommend the following tests:
启动性能测试 / Startup Performance Test
# 测量应用启动时间 / Measure application startup time
time dotnet run
并发性能测试 / Concurrent Performance Test
# 使用压力测试工具 / Use stress testing tools
ab -n 10000 -c 100 http://your-api-endpoint/
监控日志 / Monitor Logs
感谢社区用户 @bbhxwl 报告此性能问题。
Thanks to community user @bbhxwl for reporting this performance issue.
发布日期 / Release Date: 2026-01-22
版本 / Version: v16.21.0