Home | 簡體中文 | 繁體中文 | 雜文 | 打賞(Donations) | OSChina 博客 | Facebook | Linkedin | 知乎專欄 | Search | About

第 46 章 Nginx

目錄

46.1. Installing
46.1.1. Netkiller OSCM 一鍵安裝 (CentOS 7)
46.1.2. Installing by apt-get under the debain/ubuntu
46.1.3. CentOS
46.1.3.1. spawn-fcgi script
46.1.3.2. php-fpm
46.1.3.3. fastcgi backend
46.1.4. installing by source
46.1.5. CentOS 7
46.1.6. Mac
46.1.6.1. php-fpm
46.1.7. rotate log
46.1.7.1. log shell
46.1.7.2. /etc/logrotate.d/nginx
46.2. Nginx 命令
46.2.1. -V show version and configure options then exit
46.2.2. -t : test configuration and exit
46.2.3. test configuration, dump it and exit
46.3. nginx 配置檔案
46.3.1. http 配置
46.3.2. events
46.3.3. gzip
46.3.3.1. CDN支持
46.3.4. server_tokens
46.3.5. ssi
46.3.6. server
46.3.6.1. listen
46.3.6.2. 單域名虛擬主機
46.3.6.3. ssl 虛擬主機
46.3.6.4. server_name 配置
46.3.6.5. root 通過$host智能匹配目錄
46.3.6.6. location
46.3.6.7. expires
46.3.6.7.1. 通過 add_header / more_set_headers 設置緩存
46.3.6.7.2. $request_uri
46.3.6.7.3. $request_filename
46.3.6.8. access
46.3.6.9. autoindex
46.3.6.10. try_files
46.3.6.11. add_header
46.3.6.11.1. Cache
46.3.6.11.2. Access-Control-Allow
46.3.7. HTTP2 配置 SSL證書
46.3.7.1. 自頒發證書
46.3.7.2. spdy
46.3.7.3. HTTP2
46.3.7.4. 用戶訪問 HTTP時強制跳轉到 HTTPS
46.3.7.5. SSL 雙向認證
46.3.7.5.1. 生成證書
46.3.7.5.1.1. CA
46.3.7.5.1.2. 伺服器端
46.3.7.5.1.3. 客戶端
46.3.7.5.1.4. 瀏覽器證書
46.3.7.5.1.5. SOAP 證書
46.3.7.5.1.6. 過程演示
46.3.7.5.2. Nginx 配置
46.3.7.5.3. 測試雙向認證
46.3.8. rewrite
46.3.8.1. http get 參數處理
46.3.8.2. 正則取非
46.3.9. upstream 負載均衡
46.3.9.1. weight 權重配置
46.3.9.2. backup 實現熱備
46.3.10. fastcgi
46.3.10.1. spawn-fcgi
46.3.10.2. php-fpm
46.3.10.2.1. php5-fpm
46.3.10.2.2. 編譯 php-fpm
46.3.10.2.2.1. php-fpm 狀態
46.3.10.2.3. fastcgi_pass
46.3.11. return
46.3.12. Nginx 變數
46.3.12.1. $host
46.3.12.2. http_user_agent
46.3.12.2.1. 禁止非瀏覽器訪問
46.3.12.2.2. http_user_agent 沒有設置不允許訪問
46.3.12.3. http_referer
46.3.12.3.1. valid_referers/invalid_referer
46.3.12.4. request_filename
46.3.12.5. request_uri
46.3.12.6. remote_addr
46.3.12.7. http_cookie
46.3.12.8. request_method
46.3.12.9. limit_except
46.3.12.10. invalid_referer
46.3.12.11. $request_body - HTTP POST 數據
46.3.12.11.1. 用戶日誌
46.3.12.11.2. $request_body 用於緩存
46.3.12.12. 自定義變數
46.3.12.13. if 條件判斷
46.4. Proxy
46.4.1. proxy_cache
46.4.2. rewrite + proxy_pass
46.4.3. request_filename + proxy_pass
46.4.4. $request_uri 與 proxy_pass 聯合使用
46.4.5. try_files 與 proxy_pass 共用
46.4.6. Proxy 與 SSI
46.4.7. Host
46.4.8. expires
46.4.9. X-Forwarded-For
46.4.10. X-Sendfile
46.4.11. proxy_http_version
46.4.12. proxy_set_header
46.4.13. timeout 超時時間
46.4.14. example
46.4.14.1. upstream 實例
46.4.14.2. Tomcat 實例
46.4.14.3. Nginx -> Nginx -> Tomcat
46.4.14.4. Proxy 處理 Cookie
46.4.14.5. Proxy 添加 CORS 頭
46.4.14.6. 通過 Proxy 漢化 restful 介面
46.5. Nginx module
46.5.1. stub_status
46.5.2. sub_filter 頁面中查找和替換
46.5.3. auth_basic
46.5.4. valid_referers
46.5.5. ngx_http_flv_module
46.5.6. ngx_http_mp4_module
46.5.7. limit_zone
46.5.8. image_filter
46.5.9. ngx_stream_proxy_module
46.5.10. limit_except
46.5.11. geoip_country_code
46.6. Example
46.6.1. Nginx + Tomcat
46.6.2. 攔截index.html
46.6.3. Session 的 Cookie 域處理
46.7. FAQ
46.7.1. 405 Not Allowed?
46.7.2. 502 Bad Gateway?
46.7.3. 413 Request Entity Too Large
46.7.4. 502 Bad Gateway?
46.7.5. 499 Client Closed Request
46.7.6. proxy_pass
46.7.7. proxy_pass SESSION 丟失問題
46.7.8. [alert] 55785#0: *11449 socket() failed (24: Too many open files) while connecting to upstream
46.7.9. server_name 與 SSI 注意事項
46.7.10. location 跨 document_root 引用,引用 document_root 之外的資源
46.7.11. nginx: [warn] duplicate MIME type "text/html" in /etc/nginx/nginx.conf

46.1. Installing

46.1.1. Netkiller OSCM 一鍵安裝 (CentOS 7)

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

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

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

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

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

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

46.1.3.3. fastcgi backend

				
upstream backend  {
  server   localhost:1234;
}

fastcgi_pass   backend;
				
				

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

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

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

			
			

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

46.1.7. rotate log

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

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