Home | 简体中文 | 繁体中文 | 杂文 | Github | 知乎专栏 | Facebook | Linkedin | Youtube | 打赏(Donations) | About
知乎专栏

第 34 章 Nginx

目录

34.1. Installing
34.1.1. Netkiller OSCM 一键安装 (CentOS 7)
34.1.2. Installing by apt-get under the debain/ubuntu
34.1.3. CentOS
34.1.4. installing by source
34.1.5. CentOS 7
34.1.6. Mac
34.1.7. rotate log
34.2. Nginx 命令
34.2.1. -V show version and configure options then exit
34.2.2. -t : test configuration and exit
34.2.3. test configuration, dump it and exit
34.3. nginx.conf 配置文件
34.3.1. 处理器配置
34.3.2. events 配置
34.3.3. Nginx 变量
34.4. http 配置
34.4.1. 缓冲区相关设置
34.4.2. 超时设置
34.4.3. gzip
34.4.4. server_tokens
34.4.5. ssi
34.4.6. DNS 解析
34.4.7. rewrite
34.5. server
34.5.1. listen
34.5.2. server_name 配置
34.5.3. location
34.5.4. root 通过$host智能匹配目录
34.5.5. alias
34.5.6. try_files
34.5.7. SSL 虚拟主机
34.5.8. HTTP2 配置 SSL证书
34.5.9. expires
34.5.10. access
34.5.11. autoindex
34.5.12. return
34.5.13. add_header
34.5.14. client_max_body_size 上传文件尺寸限制
34.6. upstream 负载均衡
34.6.1. weight 权重配置
34.6.2. backup 实现热备
34.7. Proxy
34.7.1. proxy_cache
34.7.2. rewrite + proxy_pass
34.7.3. request_filename + proxy_pass
34.7.4. $request_uri 与 proxy_pass 联合使用
34.7.5. try_files 与 proxy_pass 共用
34.7.6. Proxy 与 SSI
34.7.7. Host
34.7.8. expires
34.7.9. X-Forwarded-For
34.7.10. X-Sendfile
34.7.11. proxy_http_version
34.7.12. proxy_set_header
34.7.13. 隐藏头部信息
34.7.14. 忽略头
34.7.15. proxy_pass_request_headers 透传 Header
34.7.16. timeout 超时时间
34.7.17. sub_filter 文本替换
34.7.18. 站外代理
34.7.19. example
34.7.20. HTTP Auth 认证冲突
34.8. fastcgi
34.8.1. spawn-fcgi
34.8.2. php-fpm
34.9. Nginx module
34.9.1. stub_status 服务器状态采集模块
34.9.2. sub_filter 页面中查找和替换
34.9.3. auth_basic HTTP 认证模块
34.9.4. valid_referers
34.9.5. ngx_http_flv_module
34.9.6. ngx_http_mp4_module
34.9.7. limit_zone
34.9.8. image_filter
34.9.9. ngx_stream_proxy_module
34.9.10. ngx_http_mirror_module
34.9.11. limit_except
34.9.12. geoip_country_code
34.10. Example
34.10.1. Nginx + Tomcat
34.10.2. 拦截index.html
34.10.3. Session 的 Cookie 域处理
34.11. FAQ
34.11.1. 405 Not Allowed?
34.11.2. 413 Request Entity Too Large
34.11.3. 499 Client Closed Request
34.11.4. 502 Bad Gateway?
34.11.5. 504 Gateway Time-out
34.11.6. proxy_pass
34.11.7. proxy_pass SESSION 丢失问题
34.11.8. [alert] 55785#0: *11449 socket() failed (24: Too many open files) while connecting to upstream
34.11.9. server_name 与 SSI 注意事项
34.11.10. location 跨 document_root 引用,引用 document_root 之外的资源
34.11.11. nginx: [warn] duplicate MIME type "text/html" in /etc/nginx/nginx.conf
34.11.12. 127.0.0.1:8080 failed
34.11.13. failed (13: Permission denied) while connecting to upstream
34.11.14. upstream sent too big header while reading response header from upstream
34.11.15. 很目录 index.html 正常访问,其他文件都是 404
34.11.16. nginx: [warn] the "listen ... http2" directive is deprecated, use the "http2" directive instead

34.1. Installing

34.1.1. Netkiller OSCM 一键安装 (CentOS 7)

# curl -s https://raw.githubusercontent.com/oscm/shell/master/web/nginx/stable/nginx.sh | bash
			

34.1.2. Installing by apt-get under the debain/ubuntu

			
$ sudo apt-get install nginx
			
			
			
sudo /etc/init.d/nginx start
			
			

34.1.3. CentOS

http://nginx.org/packages/centos/$releasever/$basearch/

$releasever 是版本号

$basearch 处理器架构

http://nginx.org/packages/centos/6/x86_64/

			
cat > /etc/yum.repos.d/nginx.repo <<EOF
[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/centos/6/x86_64/
gpgcheck=0
enabled=1
EOF
			
			

i386

			
cat > /etc/yum.repos.d/nginx.repo <<EOF
[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/centos/5/i386/
gpgcheck=0
enabled=1
EOF
			
			
yum search nginx
============================================= Matched: nginx =============================================
nginx.x86_64 : high performance web server

yum install -y nginx
chkconfig nginx on
service nginx start
			

34.1.3.1. spawn-fcgi script

yum -y install spawn-fcgi
				

/etc/sysconfig/spawn-fcgi

移除SOCKET与OPTIONS注释, apache改为nginx

# cat /etc/sysconfig/spawn-fcgi
# You must set some working options before the "spawn-fcgi" service will work.
# If SOCKET points to a file, then this file is cleaned up by the init script.
#
# See spawn-fcgi(1) for all possible options.
#
# Example :
SOCKET=/var/run/php-fcgi.sock
OPTIONS="-u apache -g apache -s $SOCKET -S -M 0600 -C 32 -F 1 -P /var/run/spawn-fcgi.pid -- /usr/bin/php-cgi"
				
				
chkconfig spawn-fcgi on
				
				

starting spawn-fcgi

/etc/init.d/spawn-fcgi start
				

check port

# netstat -nl
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address               Foreign Address             State
tcp        0      0 0.0.0.0:22                  0.0.0.0:*                   LISTEN
tcp        0      0 :::22                       :::*                        LISTEN
Active UNIX domain sockets (only servers)
Proto RefCnt Flags       Type       State         I-Node Path
unix  2      [ ACC ]     STREAM     LISTENING     25282  /var/run/php-fcgi.sock
unix  2      [ ACC ]     STREAM     LISTENING     8227   @/com/ubuntu/upstart
				
				<para>Unix domain socket</para>
				<![CDATA[

        location ~ \.php$ {
            fastcgi_pass   unix:/var/run/php-fcgi.sock;
            fastcgi_index  index.php;
            fastcgi_param  SCRIPT_FILENAME  /var/www/nginx-default$fastcgi_script_name;
            include        fastcgi_params;
        }
				
				

TCP/IP

/usr/bin/spawn-fcgi -a 127.0.0.1 -p 9000 -u nginx -g nginx -d /www -C 32 -F 1 -P /var/run/spawn-fcgi.pid -f /usr/bin/php-cgi
				

				
        location ~ \.php$ {
            fastcgi_pass   127.0.0.1:9000;
            fastcgi_index  index.php;
            fastcgi_param  SCRIPT_FILENAME  /var/www/nginx-default$fastcgi_script_name;
            include        fastcgi_params;
        }
				
				
# netstat -tulpn | grep :9000
tcp        0      0 127.0.0.1:9000              0.0.0.0:*                   LISTEN      26877/php-cgi
				
chkconfig nginx on
				

check config

nginx -t
				

34.1.3.2. php-fpm

rpm -Uvh http://download.fedora.redhat.com/pub/epel/6/x86_64/epel-release-6-5.noarch.rpm
yum install nginx -y
				

chkconfig nginx on
				

check config

nginx -t
				
yum -y install mysql mysql-server
yum -y install php php-cgi php-mysql php-mbstring php-gd php-fastcgi
yum -y install perl-DBI perl-DBD-MySQL
				

其他 php-fpm YUM源

rpm --import http://rpms.famillecollet.com/RPM-GPG-KEY-remi
rpm -ivh http://rpms.famillecollet.com/enterprise/remi-release-6.rpm
				
# rpm -Uvh http://centos.alt.ru/repository/centos/6/i386/centalt-release-6-1.noarch.rpm
# yum update
				

34.1.3.3. fastcgi backend

				
upstream backend  {
  server   localhost:1234;
}

fastcgi_pass   backend;
				
				

34.1.4. installing by source

			
cd /usr/local/src/
wget http://www.nginx.org/download/nginx-1.0.6.tar.gz

./configure --prefix=/usr/local/server/nginx \
--with-openssl=/usr/include \
--with-pcre=/usr/include/pcre/ \
--with-http_stub_status_module \
--without-http_memcached_module \
--without-http_fastcgi_module \
--without-http_rewrite_module \
--without-http_map_module \
--without-http_geo_module \
--without-http_autoindex_module
			
			

rpm 所使用的编译参数

nginx -V
nginx: nginx version: nginx/1.0.6
nginx: built by gcc 4.4.4 20100726 (Red Hat 4.4.4-13) (GCC)
nginx: TLS SNI support enabled
nginx: configure arguments: --prefix=/etc/nginx/ --sbin-path=/usr/sbin/nginx --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwcgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --user=nginx --group=nginx --with-http_ssl_module --with-http_realip_module --with-http_addition_module --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_gzip_static_module --with-http_random_index_module --with-http_secure_link_module --with-http_stub_status_module --with-mail --with-mail_ssl_module --with-file-aio --with-ipv6
			
# nginx -V
nginx version: nginx/1.2.3
built by gcc 4.4.4 20100726 (Red Hat 4.4.4-13) (GCC)
TLS SNI support enabled
configure arguments: --prefix=/etc/nginx/ --sbin-path=/usr/sbin/nginx --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --user=nginx --group=nginx --with-http_ssl_module --with-http_realip_module --with-http_addition_module --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gzip_static_module --with-http_random_index_module --with-http_secure_link_module --with-http_stub_status_module --with-mail --with-mail_ssl_module --with-file-aio --with-ipv6 --with-cc-opt='-O2 -g'
			

34.1.5. CentOS 7

			
#!/bin/bash
rpm -ivh http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm
yum install -y nginx

cp /etc/nginx/nginx.conf{,.original}

vim /etc/nginx/nginx.conf <<VIM > /dev/null 2>&1
:%s/worker_processes  1;/worker_processes  8;/
:%s/worker_connections  1024;/worker_connections  4096;/
:%s/#gzip/server_tokens off;\r    gzip/
:%s/#gzip/gzip/
:wq
VIM

sed -i '4iworker_rlimit_nofile 65530;' /etc/nginx/nginx.conf

systemctl enable nginx
systemctl start nginx			
			
			

测试配置文件是否正确

# nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful			
			

34.1.6. Mac

安装

neo@MacBook-Pro ~ % brew install nginx 			
			

启动

neo@MacBook-Pro ~ % brew services start nginx
==> Successfully started `nginx` (label: homebrew.mxcl.nginx)
			

重启

neo@MacBook-Pro /usr/local/etc/nginx % brew services restart nginx
Stopping `nginx`... (might take a while)
==> Successfully stopped `nginx` (label: homebrew.mxcl.nginx)
==> Successfully started `nginx` (label: homebrew.mxcl.nginx)			
			

配置文件在 /usr/local/etc/nginx 下,默认使用 8080端口

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       8080;
        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;
    #    }
    #}
    include servers/*;
}

			
			

34.1.6.1. php-fpm

mac下自带的软件

neo@MacBook-Pro ~ % php -v
PHP 5.6.30 (cli) (built: Feb  7 2017 16:18:37) 
Copyright (c) 1997-2016 The PHP Group
Zend Engine v2.6.0, Copyright (c) 1998-2016 Zend Technologies
				

启动php-fpm方法如下

cd /private/etc
sudo cp php-fpm.conf.default php-fpm.conf
				

修改error_log项, 改为error_log = /usr/local/var/log/php-fpm.log

启动 php-fpm

php-fpm
				

34.1.7. rotate log

34.1.7.1. log shell

一些特别的情况下需要切割日志,请参考下面的例子

				
# cat /srv/bin/rotatelog.sh

#!/bin/bash
# run this script at 0:00

#Nginx Log Path
log_dir="/var/log/nginx"
date_dir=`date +%Y/%m/%d/%H`

mkdir -p ${log_dir}/${date_dir} > /dev/null 2>&1
mv ${log_dir}/access.log ${log_dir}/${date_dir}/access.log
mv ${log_dir}/error.log ${log_dir}/${date_dir}/error.log

kill -USR1 `cat /var/run/nginx.pid`

gzip ${log_dir}/${date_dir}/access.log &
gzip ${log_dir}/${date_dir}/error.log &
				
				

34.1.7.2. /etc/logrotate.d/nginx

如果是非源码安装,一般情况nginx都会自带日志切割处理配置文件。

				
# cat /etc/logrotate.d/nginx
/var/log/nginx/*.log {
        daily
        missingok
        rotate 52
        compress
        delaycompress
        notifempty
        create 640 root adm
        sharedscripts
        postrotate
                [ -f /var/run/nginx.pid ] && kill -USR1 `cat /var/run/nginx.pid`
        endscript
}