You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用k6压测ASP.NET Core API时遭遇MySQL连接超时问题求助

MySQL连接超时问题解决方案(负载测试ASP.NET Core API时)

问题场景

使用k6对ASP.NET Core API执行负载测试(配置为1000虚拟用户,10000次迭代)时,API抛出MySQL连接超时异常,核心错误信息:

MySql.Data.MySqlClient.MySqlException (0x80004005): Unable to connect to any of the specified MySQL hosts.
---> MySql.Data.MySqlClient.MySqlException (0x80004005): Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding.

问题根源是高并发下每次请求手动创建新MySQL连接,导致连接池耗尽或MySQL服务器无法处理过量连接请求。


解决方案

1. 改用数据库连接池管理连接

原代码每次请求都手动创建、打开、关闭MySQL连接,高并发下会快速耗尽资源。正确做法是通过ASP.NET Core依赖注入复用连接池中的连接:

注册连接服务(Program.cs)

builder.Services.AddSingleton<IDbConnection>(sp => 
    new MySqlConnection(builder.Configuration.GetConnectionString("MySqlConnection")));

控制器中注入并使用连接

public class WeatherForecastController : ControllerBase
{
    private readonly IDbConnection _db;

    public WeatherForecastController(IDbConnection db)
    {
        _db = db;
    }

    [HttpGet(Name = "listStation")]
    public async Task<IEnumerable<Station>> Get()
    {
        var result = await _db.QueryAsync<Station>(
            "SELECT Code,Name,EnglishName,TelCode FROM `oln_station` where internetShow = 1 order by Name ");
        return result.ToList();
    }
}

无需手动调用Open()/Close(),Dapper会自动管理连接池中的连接生命周期。

2. 优化MySQL连接字符串配置

调整连接池参数,避免无限制创建连接,同时设置合理超时:

SERVER=***; DATABASE=***; User=***;PASSWORD=***;
Min Pool Size=10; Max Pool Size=100;
Connection Timeout=15; Command Timeout=30;
  • Max Pool Size:连接池最大连接数,需与MySQL服务器max_connections配置匹配(默认MySQL为151,不要超过此值)
  • Min Pool Size:预初始化连接数,减少高并发时创建连接的开销
  • Connection Timeout:连接服务器的超时时间,避免无限等待

3. 调整负载测试参数

原配置的1000虚拟用户远超MySQL默认连接能力,建议先降低并发量,用梯度加压模式测试:

import http from "k6/http";
import { check } from "k6";

export const options = {
    stages: [
        { duration: '30s', target: 50 },  // 30秒内升到50个虚拟用户
        { duration: '1m', target: 50 },   // 维持50用户1分钟
        { duration: '30s', target: 0 },   // 30秒内降到0用户
    ],
};

export default () => {
    const res = http.get('http://localhost:5000/WeatherForecast');
    check(res, { 'status was 200': (r) => r.status == 200 });
};

4. 检查MySQL服务器配置

  • 执行SHOW VARIABLES LIKE 'max_connections';查看最大连接数,若默认151无法满足需求,可结合服务器硬件调整至合适值
  • 检查wait_timeout和interactive_timeout配置,避免连接被过早回收

5. 缓存静态查询结果

该接口返回的是静态数据,可缓存结果避免重复查询:

public class WeatherForecastController : ControllerBase
{
    // 懒加载缓存,仅初始化一次
    private static readonly Lazy<Task<List<Station>>> _cachedStations = new Lazy<Task<List<Station>>>(async () =>
    {
        using (var db = new MySqlConnection("你的连接字符串"))
        {
            var result = await db.QueryAsync<Station>("SELECT Code,Name,EnglishName,TelCode FROM `oln_station` where internetShow = 1 order by Name ");
            return result.ToList();
        }
    });

    [HttpGet(Name = "listStation")]
    public async Task<IEnumerable<Station>> Get()
    {
        return await _cachedStations.Value;
    }
}

若数据需定期更新,可结合IDistributedCache实现定时刷新缓存。


内容的提问来源于stack exchange,提问作者Ehsan Akbar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 22:58:09