小程序上传文件nginx返回404原因排查
现象描述
微信小程序上传图片功能,服务端时ngnix代理到netty后端。开发工具使用iphone模拟器上传文件正常。但是iPhone手机测试返回404.
android手机测试OK。
故障排查
404状态码表示地址不存在。
PC开发工具和android手机测试正常,iPhone手机返回404,地址是找的到的。
打开nginx访问日志
1 | x.x.x.x - - [18/Mar/2022:04:11:49 +0000] "POST /upload HTTP/2.0" 404 154 "https://servicewechat.com/wx0000000/0/page-frame.html" "Mozilla/5.0 (iPhone; CPU iPhone OS 15_3_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 MicroMessenger/8.0.16(0x18001023) NetType/4G Language/zh_CN" "-" |
这里显示iPhone用的时HTTP/2.0协议,难道是后端netty不支持HTTP/2.0协议导致的?
netty 是其他人负责的,不能修改。那就在nginx中删除对HTTP/2.0的支持。测试后iPhone设备测试仍返回404.
迷茫中…
过了一天,另一台android设备测试也返回404,这就不单单是iPhone的问题了。
1 | x.x.x.x - - [24/Mar/2022:06:49:24 +0000] "POST /upload HTTP/1.1" 404 556 "https://servicewechat.com/wx0000000/0/page-frame.html" "Mozilla/5.0 (Linux; Android 9; ARS-AL00 Build/HUAWEIARS-AL00; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/86.0.4240.99 XWEB/3195 MMWEBSDK/20220204 Mobile Safari/537.36 MMWEBID/8978 MicroMessenger/8.0.20.2100(0x28001451) Process/appbrand0 WeChat/arm64 Weixin NetType/WIFI Language/zh_CN ABI/arm64 MiniProgramEnv/android" "-" |
这台nginx是用docker容器运行的,没有配置error.log.
配置error.log, 再次测试后查看error.log.
1 | 2022/03/24 07:14:37 [error] 12#12: *6 open() "/usr/share/nginx/html/50x.html" failed (2: No such file or directory), cli |
这里显示nginx找不到50x.html文件。
看来是upload请求时netty返回50x状态码,这时nginx查找50x.html返回给客户端,但是nginx没有配置50x.html为文件,然后nginx转而返回404状态码给客户端,导致真正的50x状态码丢失。
真相
Netty默认配置对上传文件有64k的限制。所以测试时如果上传的图片小于64k,则流程一切正常。当上传图片大于64k时,netty出错,返回50x错误(这里没有确认核对具体返回码)。如果正确的配置了nginx,那么这时nginx就会返回netty返回的状态码,页面内容为50x.html的内容。
但是这台运行在docker中的nginx配置不够完整,没有配置error.log和50x.html界面,结果倒置nginx无法找到50x.html文件,导致返回404错误码,掩盖了真正错误的原因。