产生背景

在前后端分离实践中,借助于nginx的反向代理,既能解决负载问题,也能解决跨域问题,是一个完美的实现方案。最近解决写了一个多级菜单列表的接口,数据大小有200k。通过ip访问,返回数据是完整的,但是通过代理域名访问,返回只有60-80k之间的数据。

查询Nginx的error.log日志,发现下面的错误:

1
2017/04/26 18:27:46 [crit] 19851#0: *867217 open() "/var/lib/nginx/proxy/6/68/0000001686" failed (13: Permission denied) while reading upstream, client: 10.71.253.194, server: admin-develop.xxx.cc, request: "GET /v2/menu/list HTTP/1.1", upstream: "http://127.0.1.1:40212/router/menu/list", host: "admin-develop.xxx.cc"

问题分析:

nginx里对于小的反向代理请求是使用内存作中转,对于稍微大一点的,是使用文件系统来做中转。由于数据量较大,nginx临时向/var/lib/nginx/proxy目录下写入了临时数据,而执行nginx的用户没有该目录的写入权限。

解决办法:

根据nginx的运行的用户和组,给/var/lib/nginx/proxy目录给相应的用户和组,并给写权限。

其他原因

nginx请求缓存区的配置,允许客户端连接的最大请求实体大小的配置均可以影响返回结果。

1
2
3
4
5
6
7
fastcgi_buffer_size=64k;
fastcgi_buffers 4 64k;

fastcgi_busy_buffers_size 128k;
fastcgi_temp_file_write_size 128k;

client_max_body_size 32m;
  • fastcgi_buffer_size:读取fastcgi应答第一部分需要多大缓冲区,该值表示使用1个64kb的缓冲区读取应答第一部分(应答头),可以设置为fastcgi_buffers选项缓冲区大小。

  • fastcgi_buffers:指定本地需要多少和多大的缓冲区来缓冲fastcgi应答请求,假设一个php或java脚本所产生页面大小为256kb,那么会为其分配4个64kb的缓冲来缓存;若页面大于256kb,那么大于的256kb的部分会缓存到fastcgi_temp指定路径中,这并非是个好办法,内存数据处理快于硬盘,一般该值应该为站点中php/java脚本所产生页面大小中间值,如果站点大部分脚本所产生的页面大小为256kb,那么可把值设置为16 16k,4 64k等。

  • fastcgi_busy_buffers_size: 默认值是fastcgi_buffer的2倍。

  • fastcgi_temp_file_write_size:写入缓存文件使用多大的数据块,默认值是fastcgi_buffer的2倍。

  • client_max_body_size: 指令指定允许客户端连接的最大请求实体大小,它出现在请求头部的Content-Length字段. 如果请求大于指定的值,客户端将收到一个"Request Entity Too Large" (413)错误. 记住,浏览器并不知道怎样显示这个错误。

  • 此外, fastcgi_cache_path
      这个指令为Nginx配置FastCGI缓存指定一个路径,目录结构等级,关键字区域存储时间和非活动删除时间。

1
fastcgi_cache_path /var/lib/nginx/proxy levels=1:2 keys_zone=TEST:10m inactive=5m;