记一次大文件下载导致的[Broken pipe]异常
架构
Docker内部署SpringCloud,使用spring-cloud-gateway做路由
问题描述
下载400M文件时下载不全,只能下载到80 ~ 120M左右,之后就结束下载。文件服务报错Broken pipe错误
排查思路
- 本地启动服务测试下载正常
- 测试环境测试正常
- 本地连接到生产环境测试正常( ̄□ ̄||)
到这里我以为是Docker容器导致的报错
- 查看容器日志(journalctl -u docker -n 200查看Docker近200条日志数据)
发现有一行内存溢出的错误
ERROR c.g.g.handler.MyExceptionHandler - reactor.netty.ReactorNetty$InternalNettyException: io.netty.util.internal.OutOfDirectMemoryError: failed to allocate 16777216 byte(s) of direct memory (used: 520093703, max: 521142272) Suppressed: re
- 检查报错位置为Gateway服务
到此所有问题都明清楚了
问题解决
增大Gateway服务的内存
疑问解答
- 为什么本地和测试环境下载正常? 本地和测试环境未设置Gateway服务内存上限,生产环境设置了最大内存空间为500M,后改为2000M
- 为什么本地连接到生产环境未出现异常? 推测为网络IO问题。生产环境中Gateway和File服务在同一个Docker容器中。网络IO远远小于Gateway往客户端写数据的速度。而本地连接到生产环境后,File和Gateway的IO与Gateway写回客户端的IO相仿,不会导致Gateway内存溢出问题