Nginx入门指南
2023-1-6 00:1:8 Author: 利刃信安(查看原文) 阅读量:15 收藏


Nginx介绍

Nginx [engine x] 是一个高性能的 HTTP 和反向代理服务器、邮件代理服务器和通用 TCP/UDP 代理服务器,最初由Igor Sysoev编写。

很长一段时间以来,它一直在运行在许多负载重的俄罗斯网站,典型代表包括 Yandex、 Mail.Ru、 VK和 Rambler。

根据 Netcraft 的数据,2022 年 1 月,Nginx 服务或代理了最繁忙的站点中的 22.16% 。其中的成功案例包括 Dropbox、 Netflix、 Wordpress.com、 FastMail.FM。

Nginx 特点是占用内存少,并发能力强,事实上 Nginx 的并发能力确实在同类型的网页服务器中表现较好。Nginx 专为性能优化而开发,性能是其最重要的要求,Nginx 十分注重效率,有报告显示 Nginx 能支持高达 50000 个并发连接数。

Nginx安装

Nginx 官方下载地址:

http://nginx.org/en/download.html
image-20220307212626047

系统平台:CentOS Linux release 7.6.1810 (Core)

安装编译工具及库文件

yum -y install gcc-c++ libtool make openssl openssl-devel pcre pcre-devel zlib zlib-devel
[[email protected] ~]# yum -y install gcc-c++ libtool make openssl openssl-devel pcre pcre-devel zlib zlib-devel
Loaded plugins: fastestmirror, langpacks, product-id, search-disabled-repos, subscription-manager

This system is not registered with an entitlement server. You can use subscription-manager to register.

Loading mirror speeds from cached hostfile
Package gcc-c++-4.8.5-44.el7.x86_64 already installed and latest version
Package libtool-2.4.2-22.el7_3.x86_64 already installed and latest version
Package 1:make-3.82-24.el7.x86_64 already installed and latest version
Package 1:openssl-1.0.2k-24.el7_9.x86_64 already installed and latest version
Package 1:openssl-devel-1.0.2k-24.el7_9.x86_64 already installed and latest version
Package pcre-8.32-17.el7.x86_64 already installed and latest version
Package pcre-devel-8.32-17.el7.x86_64 already installed and latest version
Package zlib-1.2.7-19.el7_9.x86_64 already installed and latest version
Package zlib-devel-1.2.7-19.el7_9.x86_64 already installed and latest version
Nothing to do

安装 PCRE

PCRE 作用是让 Nginx 支持 Rewrite 功能。

下载 PCRE 安装包,下载地址:

https://onboardcloud.dl.sourceforge.net/project/pcre/pcre/8.45/pcre-8.45.tar.gz
[[email protected] tmp]# wget https://onboardcloud.dl.sourceforge.net/project/pcre/pcre/8.45/pcre-8.45.tar.gz
--2022-03-07 21:51:26--  https://onboardcloud.dl.sourceforge.net/project/pcre/pcre/8.45/pcre-8.45.tar.gz
Resolving onboardcloud.dl.sourceforge.net (onboardcloud.dl.sourceforge.net)... 202.79.184.253
Connecting to onboardcloud.dl.sourceforge.net (onboardcloud.dl.sourceforge.net)|202.79.184.253|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 2096552 (2.0M) [application/x-gzip]
Saving to: ‘pcre-8.45.tar.gz’

100%[===============================================================================>] 2,096,552   20.1KB/s   in 1m 52s 

2022-03-07 21:53:20 (18.3 KB/s) - ‘pcre-8.45.tar.gz’ saved [2096552/2096552]

解压安装包

[[email protected] tmp]# tar zxvf pcre-8.45.tar.gz 

进入安装包目录

[[email protected] tmp]# cd pcre-8.45/

编译安装

[[email protected] pcre-8.45]# ./configure
[[email protected] pcre-8.45]# make && make install

查看pcre版本

[[email protected] pcre-8.45]# pcre-config --version
8.45

安装 Nginx

下载 Nginx,下载地址:

http://nginx.org/en/download.html
http://nginx.org/download/nginx-1.21.6.tar.gz
[[email protected] pcre-8.45]# cd ~/tmp
[[email protected] tmp]# wget http://nginx.org/download/nginx-1.21.6.tar.gz

解压安装包

[[email protected] tmp]# tar zxvf nginx-1.21.6.tar.gz 

进入安装包目录

[[email protected] tmp]# cd nginx-1.21.6/

编译安装

[[email protected] nginx-1.21.6]# ./configure --prefix=/root/tmp/webserver/nginx --with-http_stub_status_module --with-http_ssl_module --with-pcre=/root/tmp/pcre-8.45
[[email protected] nginx-1.21.6]# make
[[email protected] nginx-1.21.6]# make install
Configuration summary
  + using PCRE library: /root/tmp/pcre-8.45
  + using system OpenSSL library
  + using system zlib library

  nginx path prefix: "/root/tmp/webserver/nginx"
  nginx binary file: "/root/tmp/webserver/nginx/sbin/nginx"
  nginx modules path: "/root/tmp/webserver/nginx/modules"
  nginx configuration prefix: "/root/tmp/webserver/nginx/conf"
  nginx configuration file: "/root/tmp/webserver/nginx/conf/nginx.conf"
  nginx pid file: "/root/tmp/webserver/nginx/logs/nginx.pid"
  nginx error log file: "/root/tmp/webserver/nginx/logs/error.log"
  nginx http access log file: "/root/tmp/webserver/nginx/logs/access.log"
  nginx http client request body temporary files: "client_body_temp"
  nginx http proxy temporary files: "proxy_temp"
  nginx http fastcgi temporary files: "fastcgi_temp"
  nginx http uwsgi temporary files: "uwsgi_temp"
  nginx http scgi temporary files: "scgi_temp"

查看nginx版本

[[email protected] nginx-1.21.6]# /root/tmp/webserver/nginx/sbin/nginx -v
nginx version: nginx/1.21.6

到此,nginx安装完成。

nginx.conf 默认配置

[[email protected] conf]# cat nginx.conf

#user  nobody;
worker_processes  1;

#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

#pid        logs/nginx.pid;

events {
    worker_connections  1024;
}

http {
    include       mime.types;
    default_type  application/octet-stream;

    #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
    #                  '$status $body_bytes_sent "$http_referer" '
    #                  '"$http_user_agent" "$http_x_forwarded_for"';

    #access_log  logs/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    #keepalive_timeout  0;
    keepalive_timeout  65;

    #gzip  on;

    server {
        listen       80;
        server_name  localhost;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

        location / {
            root   html;
            index  index.html index.htm;
        }

        #error_page  404              /404.html;

        # redirect server error pages to the static page /50x.html
        #
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }

        # proxy the PHP scripts to Apache listening on 127.0.0.1:80
        #
        #location ~ \.php$ {
        #    proxy_pass   http://127.0.0.1;
        #}

        # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
        #
        #location ~ \.php$ {
        #    root           html;
        #    fastcgi_pass   127.0.0.1:9000;
        #    fastcgi_index  index.php;
        #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
        #    include        fastcgi_params;
        #}

        # deny access to .htaccess files, if Apache's document root
        # concurs with nginx's one
        #
        #location ~ /\.ht {
        #    deny  all;
        #}
    }

    # another virtual host using mix of IP-, name-, and port-based configuration
    #
    #server {
    #    listen       8000;
    #    listen       somename:8080;
    #    server_name  somename  alias  another.alias;

    #    location / {
    #        root   html;
    #        index  index.html index.htm;
    #    }
    #}

    # HTTPS server
    #
    #server {
    #    listen       443 ssl;
    #    server_name  localhost;

    #    ssl_certificate      cert.pem;
    #    ssl_certificate_key  cert.key;

    #    ssl_session_cache    shared:SSL:1m;
    #    ssl_session_timeout  5m;

    #    ssl_ciphers  HIGH:!aNULL:!MD5;
    #    ssl_prefer_server_ciphers  on;

    #    location / {
    #        root   html;
    #        index  index.html index.htm;
    #    }
    #}

}

检查配置文件nginx.conf的正确性

[[email protected] ~]# /root/tmp/webserver/nginx/sbin/nginx -t
nginx: the configuration file /root/tmp/webserver/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /root/tmp/webserver/nginx/conf/nginx.conf test is successful

启动 Nginx

[[email protected] ~]# /root/tmp/webserver/nginx/sbin/nginx

Nginx 常用命令

/root/tmp/webserver/nginx/sbin/nginx -s reload            # 重新载入配置文件
/root/tmp/webserver/nginx/sbin/nginx -s reopen            # 重启 Nginx
/root/tmp/webserver/nginx/sbin/nginx -s stop              # 停止 Nginx
/root/tmp/webserver/nginx/sbin/nginx -s quit              # 停止 Nginx(推荐)

Nginx 报错 403 Forbidden

我是在在本地用虚拟机中通过yum安装nginx的,安装一切正常,但是访问时报错403 Forbidden

于是查看nginx日志,路径为/root/tmp/webserver/nginx/logs/error.log 。打开日志发现报错Permission denied,详细报错如下:

[[email protected] sbin]# cat /root/tmp/webserver/nginx/logs/error.log 
2022/03/07 22:14:41 [error] 19951#0: *1 "/root/tmp/webserver/nginx/html/index.html" is forbidden (13: Permission denied), client: 103.142.140.81, server: localhost, request: "GET / HTTP/1.1", host: "82.156.13.32"

启动用户和nginx工作用户不一致

查看nginx的启动用户,发现是nobody,而未使用root启动的

[[email protected] local]# ps aux | grep "nginx: worker process" | awk '{print $1}'
root
nobody
root

将nginx.config的user改为和启动用户一致

[[email protected] conf]# vim nginx.conf
[[email protected] conf]# cat nginx.conf

user  root;
worker_processes  1;

缺少index.html或者index.php文件

server {
        listen       80;
        server_name  localhost;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

        location / {
            root   html;
            index  index.html index.htm;
        }

如果在/root/tmp/webserver/nginx/html下面没有index.php,index.html的时候,直接文件,会报403 forbidden。

权限问题

修改web目录的读写权限,或者是把nginx的启动用户改成目录的所属用户,重启Nginx即可解决

[[email protected] nginx]# chmod 777 -R html/

SELinux设置为开启状态(enabled)

查看当前selinux的状态

[[email protected] nginx]# /usr/sbin/sestatus

将SELINUX=enforcing 修改为 SELINUX=disabled 状态

[[email protected] ~]# vim /etc/selinux/config

#SELINUX=enforcing
SELINUX=disabled

重启生效。

自定义网站跟目录

解决方案

[[email protected] ~]# cat /root/tmp/webserver/nginx/conf/nginx.conf
user  root;  # 以root用户运行nginx
worker_processes  1;

#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

#pid        logs/nginx.pid;

events {
    worker_connections  1024;
}

http {
    include       mime.types;
    default_type  application/octet-stream;

    #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
    #                  '$status $body_bytes_sent "$http_referer" '
    #                  '"$http_user_agent" "$http_x_forwarded_for"';

    #access_log  logs/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    #keepalive_timeout  0;
    keepalive_timeout  65;

    #gzip  on;

    server {
        listen       80;
        server_name  localhost;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

        location / {
            root   /root/tmp/webserver/nginx/html;  # 自定义网站根目录
            index  index.html index.htm;
        }

        #error_page  404              /404.html;

        # redirect server error pages to the static page /50x.html
        #
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }

        # proxy the PHP scripts to Apache listening on 127.0.0.1:80
        #
        #location ~ \.php$ {
        #    proxy_pass   http://127.0.0.1;
        #}

        # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
        #
        #location ~ \.php$ {
        #    root           html;
        #    fastcgi_pass   127.0.0.1:9000;
        #    fastcgi_index  index.php;
        #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
        #    include        fastcgi_params;
        #}

        # deny access to .htaccess files, if Apache's document root
        # concurs with nginx's one
        #
        #location ~ /\.ht {
        #    deny  all;
        #}
    }

    # another virtual host using mix of IP-, name-, and port-based configuration
    #
    #server {
    #    listen       8000;
    #    listen       somename:8080;
    #    server_name  somename  alias  another.alias;

    #    location / {
    #        root   html;
    #        index  index.html index.htm;
    #    }
    #}

    # HTTPS server
    #
    #server {
    #    listen       443 ssl;
    #    server_name  localhost;

    #    ssl_certificate      cert.pem;
    #    ssl_certificate_key  cert.key;

    #    ssl_session_cache    shared:SSL:1m;
    #    ssl_session_timeout  5m;

    #    ssl_ciphers  HIGH:!aNULL:!MD5;
    #    ssl_prefer_server_ciphers  on;

    #    location / {
    #        root   html;
    #        index  index.html index.htm;
    #    }
    #}

}

按照上述配置文件配置完成之后重启nginx服务

[[email protected] sbin]# ./nginx -s reload

完美解决。

访问网站http://82.156.13.32/

image-20220307231415248

反向代理

代理

代理也被叫做网络代理,是一种比较特殊的网络服务,允许一个终端(通常指客户端)通过这个服务与另一个终端(通常指服务器端)进行非直接的连接。

例如:一些网关、路由器等网络设备都具备网络代理的功能。

代理服务有利于保障网络终端的隐私或者安全,可以在一定程度上阻止网络攻击(因为通过代理,可以隐藏真正的服务器端/客户端)。

代理服务器

preview

左边和右边的电脑在通讯时候,需要经过中间的电脑中转,而中间的那部电脑就是代理服务器。

代理请求过程

preview

客户端首先根据代理服务器所使用的代理协议,与代理服务器创建连接,接着按照协议请求对目标服务器创建连接或者获得目标服务器的指定资源(如:文件)。

正向代理

通常我们说的代理,都是指的正向代理。

preview

继续看这张图,你会发现,此处的代理服务器可以由客户端提供,也可以由服务器端提供。

当客户端主动使用代理服务器时,此时的代理叫正向代理。比如:一些网络代理工具(加速器/VPN)

正向代理:

局域网中的电脑用户想要直接访问网络是不可行的,只能通过代理服务器来访问,这种代理服务就被称为正向代理。比如FQ软件。

正向代理时,由客户端发送对某一个目标服务器的请求,代理服务器在中间将请求转发给该目标服务器,目标服务器将结果返回给代理服务器,代理服务器再将结果返回给客户端。

使用正向代理时,客户端是需要配置代理服务的地址、端口、账号密码(如有)等才可使用的。

preview

通过上图可以看到,客户端并没有直接与服务器相连。正向代理隐藏了真实的客户端地址。可以很好地保护客户端的安全性。

正向代理的适用场景

访问被禁止的资源(让客户端访问原本不能访问的服务器。可能是由于路由的原因,或者策略配置的原因,客户端不能直接访问某些服务器。为了访问这些服务器,可通过代理服务器来访问)突破网络审查(比如谷歌、youtube…)客户端IP被服务器封禁,可以绕过IP封禁突破网站的区域限制隐藏客户端的地址(对于被请求的服务器而言,代理服务器代表了客户端,所以在服务器或者网络拓扑上,看不到原始客户端)进行客户访问控制可以集中部署策略,控制客户端的访问行为(访问认证等)记录用户访问记录(上网行为管理)内部资源的控制(公司、教育网等)加速访问资源使用缓冲特性减少网络使用率(代理服务器设置一个较大的缓冲区,当有外界的信息通过时,同时也将其保存到缓冲区中,当其他用户再访问相同的信息时,则直接由缓冲区中取出信息,传给用户,以提高访问速度。)过滤内容(可以通过代理服务器统一过滤一些危险的指令/统一加密一些内容、防御代理服务器两端的一些攻击性行为)

image-20220308220513889

反向代理

服务器根据客户端的请求,从其关系的一组或多组后端服务器(如Web服务器)上获取资源,然后再将这些资源返回给客户端,客户端只会得知代理服务器的IP地址,而不知道在代理服务器后面的服务器集群的存在。

preview

反向代理整个流程:

由客户端发起对代理服务器的请求,代理服务器在中间将请求转发给某一个服务器,服务器将结果返回给代理服务器,代理服务器再将结果返回给客户端。

反向代理:

客户端无法感知代理,因为客户端访问网络不需要配置,只要把请求发送到反向代理服务器,由反向代理服务器去选择目标服务器获取数据,然后再返回到客户端。

此时反向代理服务器和目标服务器对外就是一个服务器,暴露的是代理服务器地址,隐藏了真实服务器 IP 地址。

Nginx在做反向代理时,提供性能稳定,并且能够提供配置灵活的转发功能。Nginx可以根据不同的正则匹配,采取不同的转发策略,比如图片文件结尾的走文件服务器,动态页面走web服务器,只要你正则写的没问题,又有相对应的服务器解决方案,你就可以随心所欲的玩。并且Nginx对返回结果进行错误页跳转,异常判断等。如果被分发的服务器存在异常,他可以将请求重新转发给另外一台服务器,然后自动去除异常服务器。

反向代理的适用场景

负载均衡如果服务器集群中有负荷较高者,反向代理通过URL重写,根据连线请求从负荷较低者获取与所需相同的资源或备援。可以有效降低服务器压力,增加服务器稳定性提升服务器安全性可以对客户端隐藏服务器的IP地址作为应用层防火墙,为网站提供对基于Web的攻击行为(例如DoS/DDoS)的防护,更容易排查恶意软件等加密/SSL加速:将SSL加密工作交由配备了SSL硬件加速器的反向代理来完成提供缓存服务,加速客户端访问对于静态内容及短时间内有大量访问请求的动态内容提供缓存服务数据统一压缩节约带宽为网络带宽不好的网络提供服务统一的访问权限控制统一的访问控制突破互联网的封锁突破谷歌访问封锁

preview

正向代理与反向代理的区别

最核心的不同在于代理的对象不同。

正向代理是代理客户端。反向代理是代理服务器。

代理哪端便可以隐藏哪端。

也就是说:

正向代理隐藏真实客户端反向代理隐藏真实服务端

反向代理为什么叫反向代理

从我们用户的角度来看:

代理我们发出请求的客户端被称为正向代理。

而代理我们访问的服务器,则被称为反向代理。

从代理结构的角度来看(代理服务器在两种代理中的作用均为收发请求与响应):

img

客户端与代理服务器属于一个局域网(看图左边),称为正向代理。

img

服务器端与代理服务器属于一个局域网时(看图右边),称为反向代理。

正向代理为客户端服务。反向代理为服务器端服务。

反向代理实例

alist 程序默认监听5244端口

在网站的配置文件的server字段中加入

location / {
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_redirect off;
    proxy_pass http://127.0.0.1:5244;
    # 上传的最大文件尺寸
    client_max_body_size 20000m;
}

运维故障

【Nginx】图片不完整,竟然是Nginx的锅!!


前言

最近,安全运维过程中遇到一个奇葩问题,通过浏览器访问某静态图片,只能访问大约八分之一,其余的部分无法完全加载出来。最初我们以为是某信Waf拦截导致图片无法下载,为了解决问题,增加某0 WAf路线,结果,某信异常,某0正常,问题越来越复杂,经过一系列排查(过程省略,直奔主题),最终定位是Nginx的问题。

问题定位

1.首先尝试关闭某信Waf然后查看图片情况,经确认,图片依然异常,排除某信Waf规则拦截导致图片不完整。

image-20220313172125833

2.抓包分析,发现Transfer-Encoding: chunked字段,猜测服务器给客户端返回数据过程中采用分块传输。

image-20220313172546623

3.根据分块传输原理,搜索到一些资料,增大缓冲可以解决问题。

客户端(PC浏览器或者手机浏览器)在接受到Nginx代理响应的时候,头信息通常都会带上Content-Length,一般情况下客户端会在接受完Content-Length长度的数据之后才会开始解析。而在Nginx代理上,页面处理过程中会将数据都放在缓存中,然后一次性的返回给客户端。

另外一种情况就是头信息中不存在Content-Length ,取而代之的是Tansfer-Encoding:chunked ,这个头信息的的意思是response的内容会被Nginx代理分成一块一块的发送,客户端也就不需要等到内容都传输完毕了才解析其中的内容。因为这个时候被传送的数据长度是无法预计的,所以存在Tansfer-Encoding:chunked的话也没有存在Content-Length 的意义了。

Nginx代理服务器测试后配置进行如下修改后可以完整传输

# 代理互联网地址
location /acore {
client_max_body_size    150m;
client_body_buffer_size 128k;
proxy_connect_timeout   130;
proxy_send_timeout      300;
proxy_read_timeout      1800;

# 默认开启
# proxy_buffering on;

# 以下配置以proxy_buffers配置为中心适配的缓冲大小策略,因为nginx对缓存值相互制约,
# 从proxy_buffers设置思路比较清晰,当然也可以针对不同情况选择不同的配置项为主作为开端突破口。
# 以下配置在包资源1.7m并小于proxy_buffers 2M的话是可以正常运行的
# 可以设置很小 该指令设置缓冲区大小,从代理后端服务器取得的第一部分的响应内容,会放到这里.小的响应header通常位于这部分响应内容里边.
# 默认来说,该缓冲区大小等于指令 proxy_buffers所设置的一个块区大小;可以把它设置得更小。
# 但是最大值不能超过 proxy_buffers 减一个缓冲区的大小 3X500k (1500k)
# proxy_buffer_size  128k;

# 该指令设置缓冲区的数量(最少2)和大小,从被代理的后端服务器取得的响应内容,会放置到这里. 默认情况下,一个缓冲区的大小等于内存页面大小,可能是4K也可能是8K,这取决于平台、
#数据响应包不能大于proxy_buffers总值(在不支持分块传输条件下)如果超过需要增大proxy_buffers
proxy_buffers 4 512k;

# 默认值:proxy_buffer_size * 2; (官方文档是这样的,但是如果我proxy_buffer_size不按照推荐来设置 ,proxy_buffer_size * 2没有满足此项的最小值是不能使用的)
# 此选项最小值要大于或者等于 128k(proxy_buffer_size 128k)和512k(proxy_buffers的一个区512k)的最大值 512k
# 此选项最大值小于等于proxy_buffers 减一个缓冲区的大小 3X512K(1536k)
# proxy_busy_buffers_size 512k;

# 同时如果response的内容很大的话,Nginx会接收并把他们写入到temp_file里去。大小由proxy_max_temp_file_size控制。
# 如果busy的buffer传输完了会从temp_file里面接着读数据,直到传输完毕。
# proxy_temp_file_write_size 4m;

# proxy_redirect http:// https://;
proxy_pass http://xxx.xxx.xxx/core/;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Real-Port $remote_port;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header x-agent $http_user_agent;
proxy_set_header X-Forwarded-scheme $scheme;
}

分析后真正起到作用的是

proxy_buffers 4 512k;

只要缓冲总大小4*512k=2048k大于图片大小,图片就可以完整下载。

一波三折

问题看似解决,实际上其他问题又来了,问题就是之前的缓冲大小不足的时候,某信通道异常,某0通道却是正常的,这又是怎么回事?

我们已经确定问题出在某信通道的Nginx代理上面,查看Nginx代理报错信息,信息如下:

2022/03/13 17:06:10 [crit] 92638#0: *26924337 open() "/usr/local/nginx/proxy_temp/9/40/0000005409" failed (13: Permission denied) while reading upstream, client: 0.0.0.0, server: 8.8.8.8, request: "GET /acore/download.shtml?p=image&f=pdf/img/190618new.jpg HTTP/1.1", upstream: "http://1.1.1.1:80/core//download.shtml?p=image&f=pdf/img/190618new.jpg", host: "8.8.8.8"

直接在后台服务器上用后台服务器的IP地址去访问,发现速度相当快,于是怀疑是Nginx的配置问题。

注意:当下载大的附件,或是页面中有大图片时,就会下载中断或是图片无法显示,也许你会说我用的Nginx缺省的配置也从来没有碰到过这种问题呀!我想说的是:那是因为你的网站没有大文件,至少没有大到使用Nginx的默认配置加载不出来。

诚如之前所说,问题就出在proxy_buffers上,当服务器上的文件超过该参数设置的大小时,Nginx会先将文件写入临时目录(缺省为Nginx安装目下/proxy_temp目录),缺省Nginx是以nobody身份启动的,用ls -al 命令查看proxy_temp目录,nobody是proxy_temp目录的所有者,接下来查看proxy_temp的父目录即Nginx安装目录,发现nobody没权限。

问题解决

可以使用两种方式解决这个问题,如下所示。

设置任何人都可以写proxy_temp目录,重启Nginx即可解决。直接更改proxy_buffers的值,将其修改为大于图片和文件的大小,重启Nginx。

如果是以第一种方式解决问题的话,比如proxy_temp目录是/usr/local/nginx/proxy_temp,用如下命令将/usr/local/nginx/proxy_temp目录设置为任何人都可以写,问题解决。

chmod -R 777 /usr/local/nginx/proxy_temp/

如果问题还存在,那就用如下命令将/usr/local/nginx/目录设置为任何人都可以执行,问题解决。

chmod -R 755 /usr/local/nginx/

如果是使用第二种方式解决问题的话,就可以直接修改nginx.conf文件,如下所示。

# 代理互联网地址
location /acore {
client_max_body_size    150m;
client_body_buffer_size 128k;
proxy_connect_timeout   130;
proxy_send_timeout      300;
proxy_read_timeout      1800;

# 默认开启
# proxy_buffering on;

# 以下配置以proxy_buffers配置为中心适配的缓冲大小策略,因为nginx对缓存值相互制约,
# 从proxy_buffers设置思路比较清晰,当然也可以针对不同情况选择不同的配置项为主作为开端突破口。
# 以下配置在包资源1.7m并小于proxy_buffers 2M的话是可以正常运行的
# 可以设置很小 该指令设置缓冲区大小,从代理后端服务器取得的第一部分的响应内容,会放到这里.小的响应header通常位于这部分响应内容里边.
# 默认来说,该缓冲区大小等于指令 proxy_buffers所设置的一个块区大小;可以把它设置得更小。
# 但是最大值不能超过 proxy_buffers 减一个缓冲区的大小 3X500k (1500k)
# proxy_buffer_size  128k;

# 该指令设置缓冲区的数量(最少2)和大小,从被代理的后端服务器取得的响应内容,会放置到这里. 默认情况下,一个缓冲区的大小等于内存页面大小,可能是4K也可能是8K,这取决于平台、
#数据响应包不能大于proxy_buffers总值(在不支持分块传输条件下)如果超过需要增大proxy_buffers
proxy_buffers 4 512k;

# 默认值:proxy_buffer_size * 2; (官方文档是这样的,但是如果我proxy_buffer_size不按照推荐来设置 ,proxy_buffer_size * 2没有满足此项的最小值是不能使用的)
# 此选项最小值要大于或者等于 128k(proxy_buffer_size 128k)和512k(proxy_buffers的一个区512k)的最大值 512k
# 此选项最大值小于等于proxy_buffers 减一个缓冲区的大小 3X512K(1536k)
# proxy_busy_buffers_size 512k;

# 同时如果response的内容很大的话,Nginx会接收并把他们写入到temp_file里去。大小由proxy_max_temp_file_size控制。
# 如果busy的buffer传输完了会从temp_file里面接着读数据,直到传输完毕。
# proxy_temp_file_write_size 4m;

# proxy_redirect http:// https://;
proxy_pass http://xxx.xxx.xxx/core/;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Real-Port $remote_port;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header x-agent $http_user_agent;
proxy_set_header X-Forwarded-scheme $scheme;
}

写在最后

问题原因已经很明确了,图片传输过程中,采用分块传输,缓冲区大小不足,导致文件下载不完整。由于某信通道和某0通道代理服务器配置存在差异,导致某信异常,某0正常,配置修改后,给定/usr/local/nginx/执行权限后,两个通道均正常。

配置差异如下:



文章来源: http://mp.weixin.qq.com/s?__biz=MzU1Mjk3MDY1OA==&mid=2247499804&idx=1&sn=889c31d18c8eeddf0a888bd348b9e39d&chksm=fbfb70d1cc8cf9c76ee91ad0cce65e2e3ab0257a49b63333e7750467a332b50d4a7c5c993f5b#rd
如有侵权请联系:admin#unsafe.sh