记一次大文件下载导致的[Broken pipe]异常

架构

Docker内部署SpringCloud,使用spring-cloud-gateway做路由

问题描述

下载400M文件时下载不全,只能下载到80 ~ 120M左右,之后就结束下载。文件服务报错Broken pipe错误

排查思路

  1. 本地启动服务测试下载正常
  2. 测试环境测试正常
  3. 本地连接到生产环境测试正常( ̄□ ̄||)
到这里我以为是Docker容器导致的报错
  1. 查看容器日志(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
  1. 检查报错位置为Gateway服务
到此所有问题都明清楚了

问题解决

增大Gateway服务的内存

疑问解答

  1. 为什么本地和测试环境下载正常? 本地和测试环境未设置Gateway服务内存上限,生产环境设置了最大内存空间为500M,后改为2000M
  2. 为什么本地连接到生产环境未出现异常? 推测为网络IO问题。生产环境中Gateway和File服务在同一个Docker容器中。网络IO远远小于Gateway往客户端写数据的速度。而本地连接到生产环境后,File和Gateway的IO与Gateway写回客户端的IO相仿,不会导致Gateway内存溢出问题
经验分享 程序员 微信小程序 职场和发展