Home | 简体中文 | 繁体中文 | 杂文 | 知乎专栏 | Github | OSChina 博客 | 云社区 | 云栖社区 | Facebook | Linkedin | 视频教程 | 打赏(Donations) | About
知乎专栏多维度架构

第 45 章 Nginx

目录

45.1. Installing
45.1.1. Netkiller OSCM 一键安装 (CentOS 7)
45.1.2. Installing by apt-get under the debain/ubuntu
45.1.3. CentOS
45.1.3.1. spawn-fcgi script
45.1.3.2. php-fpm
45.1.3.3. fastcgi backend
45.1.4. installing by source
45.1.5. CentOS 7
45.1.6. Mac
45.1.6.1. php-fpm
45.1.7. rotate log
45.1.7.1. log shell
45.1.7.2. /etc/logrotate.d/nginx
45.2. Nginx 命令
45.2.1. -V show version and configure options then exit
45.2.2. -t : test configuration and exit
45.2.3. test configuration, dump it and exit
45.3. nginx.conf 配置文件
45.3.1. 处理器配置
45.3.2. events 配置
45.3.3. http 配置
45.3.3.1. 缓冲区相关设置
45.3.3.2. 超时设置
45.3.3.3. gzip
45.3.3.3.1. CDN支持
45.3.3.4. server_tokens
45.3.3.5. ssi
45.3.4. Nginx 变量
45.3.4.1. $host
45.3.4.2. http_user_agent
45.3.4.2.1. 禁止非浏览器访问
45.3.4.2.2. http_user_agent 没有设置不允许访问
45.3.4.3. http_referer
45.3.4.3.1. valid_referers/invalid_referer
45.3.4.4. request_filename
45.3.4.5. request_uri
45.3.4.6. remote_addr
45.3.4.7. http_cookie
45.3.4.8. request_method
45.3.4.9. limit_except
45.3.4.10. invalid_referer
45.3.4.11. $request_body - HTTP POST 数据
45.3.4.11.1. 用户日志
45.3.4.11.2. $request_body 用于缓存
45.3.4.12. 自定义变量
45.3.4.13. if 条件判断
45.3.5. server
45.3.5.1. listen
45.3.5.2. 单域名虚拟主机
45.3.5.3. ssl 虚拟主机
45.3.5.4. server_name 配置
45.3.5.5. location
45.3.5.5.1. 禁止访问特定目录
45.3.5.5.2. 引用document_root之外的资源
45.3.5.5.3. 处理扩展名
45.3.5.5.4. location 中关闭日志
45.3.5.6. root 通过$host智能匹配目录
45.3.5.7. expires
45.3.5.7.1. 通过 add_header / more_set_headers 设置缓存
45.3.5.7.2. $request_uri
45.3.5.7.3. $request_filename
45.3.5.8. access
45.3.5.9. autoindex
45.3.5.10. try_files
45.3.5.11. add_header
45.3.5.11.1. Cache
45.3.5.11.2. Access-Control-Allow
45.3.5.12. client_max_body_size 上传文件尺寸限制
45.3.5.13. return
45.3.6. rewrite
45.3.6.1. 处理泛解析
45.3.6.2. 处理扩展名
45.3.6.3. http get 参数处理
45.3.6.4. 正则取非
45.3.6.5. 去掉扩展名
45.3.6.6. 添加扩展名
45.3.7. HTTP2 配置 SSL证书
45.3.7.1. 自颁发证书
45.3.7.2. spdy
45.3.7.3. HTTP2
45.3.7.4. 用户访问 HTTP时强制跳转到 HTTPS
45.3.7.5. SSL 双向认证
45.3.7.5.1. 生成证书
45.3.7.5.2. Nginx 配置
45.3.7.5.3. 测试双向认证
45.3.8. upstream 负载均衡
45.3.8.1. weight 权重配置
45.3.8.2. backup 实现热备
45.3.9. Proxy
45.3.9.1. proxy_cache
45.3.9.2. rewrite + proxy_pass
45.3.9.3. request_filename + proxy_pass
45.3.9.4. $request_uri 与 proxy_pass 联合使用
45.3.9.5. try_files 与 proxy_pass 共用
45.3.9.6. Proxy 与 SSI
45.3.9.7. Host
45.3.9.8. expires
45.3.9.9. X-Forwarded-For
45.3.9.10. X-Sendfile
45.3.9.11. proxy_http_version
45.3.9.12. proxy_set_header
45.3.9.13. proxy_pass_request_headers 透传 Header
45.3.9.14. timeout 超时时间
45.3.9.15. example
45.3.9.15.1. 代理特定目录
45.3.9.15.2. upstream 实例
45.3.9.15.3. Tomcat 实例
45.3.9.15.4. Nginx -> Nginx -> Tomcat
45.3.9.15.5. Proxy 处理 Cookie
45.3.9.15.6. Proxy 添加 CORS 头
45.3.9.15.7. 通过 Proxy 汉化 restful 接口
45.3.9.15.8. HTTP2 proxy_pass http://
45.3.9.15.9. IPFS
45.3.10. fastcgi
45.3.10.1. spawn-fcgi
45.3.10.2. php-fpm
45.3.10.2.1. php5-fpm
45.3.10.2.2. 编译 php-fpm
45.3.10.2.3. fastcgi_pass
45.3.10.2.4. nginx example
45.4. Nginx module
45.4.1. stub_status
45.4.2. sub_filter 页面中查找和替换
45.4.3. auth_basic
45.4.3.1. 使用 htpasswd 生几个密码文件
45.4.3.2. 使用 openssl 生成密码
45.4.4. valid_referers
45.4.5. ngx_http_flv_module
45.4.6. ngx_http_mp4_module
45.4.7. limit_zone
45.4.8. image_filter
45.4.9. ngx_stream_proxy_module
45.4.10. ngx_http_mirror_module
45.4.11. limit_except
45.4.12. geoip_country_code
45.5. Example
45.5.1. Nginx + Tomcat
45.5.2. 拦截index.html
45.5.3. Session 的 Cookie 域处理
45.6. FAQ
45.6.1. 405 Not Allowed?
45.6.2. 502 Bad Gateway?
45.6.3. 413 Request Entity Too Large
45.6.4. 502 Bad Gateway?
45.6.5. 499 Client Closed Request
45.6.6. proxy_pass
45.6.7. proxy_pass SESSION 丢失问题
45.6.8. [alert] 55785#0: *11449 socket() failed (24: Too many open files) while connecting to upstream
45.6.9. server_name 与 SSI 注意事项
45.6.10. location 跨 document_root 引用,引用 document_root 之外的资源
45.6.11. nginx: [warn] duplicate MIME type "text/html" in /etc/nginx/nginx.conf
45.6.12. 127.0.0.1:8080 failed

45.1. Installing

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

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

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

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

45.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
			

45.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
				
				

Unix domain socket

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
				

45.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
				

45.1.3.3. fastcgi backend

				
upstream backend  {
  server   localhost:1234;
}

fastcgi_pass   backend;
				
				

45.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'
			

45.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			
			

45.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/*;
}

			
			

45.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
				

45.1.7. rotate log

45.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 &
				
				

45.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
}