IIS部署API生成200万编号时返回502错误求助
问题:IIS部署下生成200万条编号时返回502 Bad Gateway错误
我有一个API用于生成编号,流程是生成编号存入列表、转换为数据表,最后通过StringBuilder传递到UI生成CSV文件。本地环境生成200万条编号耗时10-14分钟可正常完成,但部署到IIS服务器后,请求该操作会返回502 (Bad Gateway)错误。
相关API代码
[HttpPost] public ActionResult GetNumbering([FromBody] NumberingRequest request) { try { var details = numberingtools.GetNumbering(request); if (details.Count() > 0) { return Ok(new { ResponseCode = "200", ResponseMessage = "Record Found", Details = details }); } else { return Ok(new { ResponseCode = "200", ResponseMessage = "Record Found", Details = details, totalRows = 0 }); } } catch (Exception ex) { return Ok(new { ResponseCode = "404", ResponseMessage = "Something Went Wrong", ErrorDetails = ex.Message }); } }
已尝试的配置(未解决)
在program.cs中配置Kestrel:
.UseKestrel(c => { c.AddServerHeader = false; c.Limits.KeepAliveTimeout = TimeSpan.FromMinutes(10); })
同时尝试过配置API超时相关代码,均无效。
解决方案
1. 调整IIS及相关组件的超时设置
502错误大概率是IIS或反向代理(如ARR)的超时时间短于生成耗时导致的:
- IIS站点连接超时:打开IIS管理器,找到对应站点 → 高级设置 → 连接超时,设置为大于15分钟(比如20分钟)。
- ARR代理超时(若使用):若服务器部署了应用请求路由(ARR),进入IIS管理器 → 服务器节点 → 应用请求路由 → 服务器代理设置 → 超时,将“请求超时”设为1200秒(20分钟)以上。
- AspNetCore模块超时:在
web.config中添加或修改AspNetCore模块的超时配置:<aspNetCore processPath="dotnet" arguments=".\YourApp.dll" stdoutLogEnabled="false" stdoutLogFile=".\logs\stdout" hostingModel="inprocess"> <handlerSettings> <handlerSetting name="requestTimeout" value="00:20:00" /> </handlerSettings> </aspNetCore>
2. 优化内存与传输效率
200万条数据直接返回会占用大量内存且传输耗时久,建议调整输出方式:
- 流式输出CSV:不要先把所有数据存入列表再返回,直接在API中流式生成CSV内容并输出,减少内存占用。示例:
注意:需修改[HttpPost] public async Task<IActionResult> GetNumbering([FromBody] NumberingRequest request) { try { // 直接通过流输出CSV Response.Headers.Add("Content-Disposition", "attachment; filename=编号列表.csv"); Response.ContentType = "text/csv"; await using var writer = new StreamWriter(Response.Body); // 写入CSV表头 await writer.WriteLineAsync("编号列1,编号列2,..."); // 分批生成编号并写入流(需修改GetNumbering返回IEnumerable实现分批加载) foreach (var item in numberingtools.GetNumberingAsEnumerable(request)) { await writer.WriteLineAsync($"{item.Col1},{item.Col2},..."); await writer.FlushAsync(); } return new EmptyResult(); } catch (Exception ex) { return BadRequest(new { ResponseCode = "404", ResponseMessage = "生成失败", ErrorDetails = ex.Message }); } }numberingtools.GetNumbering方法,让其返回IEnumerable<T>而非已加载的完整列表,实现数据分批生成。 - 分页拆分请求:如果UI支持,将生成任务拆分为多个请求(比如每次生成10万条),前端再合并CSV文件,降低单次请求的资源压力。
3. 延长Kestrel超时设置
当前Kestrel的KeepAliveTimeout设为10分钟,短于本地生成耗时,需延长:
.UseKestrel(c => { c.AddServerHeader = false; c.Limits.KeepAliveTimeout = TimeSpan.FromMinutes(20); c.Limits.RequestHeadersTimeout = TimeSpan.FromMinutes(20); })
4. 检查服务器资源与应用池设置
- 查看服务器CPU、内存使用情况,确认生成过程中是否因资源耗尽导致进程被回收。
- 调整IIS应用池回收设置:避免在生成过程中触发回收,比如设置固定时间回收(避开业务高峰),或调高基于内存的回收阈值。
内容的提问来源于stack exchange,提问作者Ritesh Singh
相关产品推荐
相关产品推荐

