Gogs使用nginx反代时拉取超大仓库报fatal: index-pack failed的解决方法
公司UAT服务器故障,备份文件后重装了系统。将nginx配置还原并启动Gogs后,尝试拉取一个文件数多容量大的仓库时,终端报错:
error: RPC failed; curl 18 transfer closed with outstanding read data remaining
fatal: The remote end hung up unexpectedly
fatal: early EOF
fatal: index-pack failed
在国内外网站查了很久资料,基本都提示是网络问题,有建议在Git配置项中关闭压缩、增加上传缓冲区的:
git config --global http.postBuffer 524288000
git config --global core.compression 0
或是建议只拉取最近的提交的:
git clone --depth 1 <repo_URI>
成功后再补充后续数据:
git fetch --unshallow
还有建议增加弱网优化配置或换网络的。
git config --global http.lowSpeedLimit 0
git config --global http.lowSpeedTime 999999
很遗憾,这些配置均无法解决问题。但既然提示了可能是网络有关的问题,则有必要基于网络通信的全流程查看一下问题。
首先贯彻分治法的原则,先测试问题出在哪个环节。直接使用Gogs本地地址在服务器上进行仓库克隆。
git clone http://127.0.0.1:3000/xxx/xxx.git
克隆成功完成,因此即可断定,问题一定出在nginx端。在查看了nginx的error.log之后,一段很明显的错误信息指示了问题最终的原因:
2022/03/24 09:00:55 [crit] 129923#0: *12212 open() "/usr/xxx/nginx/proxy_temp/1/01/0000000011" failed (13: Permission denied) while reading upstream, client: 10.130.0.19, server: xxx.cn, request: "POST /git/xxx/xxx.git/git-upload-pack HTTP/1.1", upstream: "http://127.0.0.1:3000/xxx/xxx.git/git-upload-pack", host: "xxx.cn"
因此,问题的根源是nginx在大请求中为了保证通信效率,使用了缓冲区进行数据收发,但在使用缓冲区目录中的文件进行操作写入时,因为无权限进而导致网络请求失败。查看进程信息之后也印证了这个结果:
nobody 33361 69816 0 09:13 ? 00:00:08 nginx: worker process
root 69816 1 0 3月23 ? 00:00:00 nginx: master process sbin/nginx
root 123433 96635 0 10:56 pts/0 00:00:00 grep --color=auto nginx
后经询问,是负责处理服务器恢复的同事漏掉了配置文件的第一行:
user root;
将该配置补上并更新nginx配置再次测试,问题解决。
综上所述,别人的解决方案不一定适合自己,还需要基于自身经验从头开始全面详细的排查问题,才能找到最终的原因。