Nginx常用配置

Nginx常用命令

  1. 啟動 Nginx
poechant@ubuntu:sudo ./sbin/nginx
  1. 停止 Nginx
poechant@ubuntu:sudo ./sbin/nginx -s stoppoechant@ubuntu:sudo ./sbin/nginx -s quit
-s都是采用向 Nginx 發送信號的方式。
  1. Nginx 重載配置
poechant@ubuntu:sudo ./sbin/nginx -s reload

上述是采用向 Nginx 發送信號的方式,或者使用:

poechant@ubuntu:service nginx reload
  1. 指定配置文件
poechant@ubuntu:sudo ./sbin/nginx -c /usr/local/nginx/conf/nginx.conf
-c表示configuration,指定配置文件。
  1. 查看 Nginx 版本

有兩種可以查看 Nginx 的版本信息的參數。第一種如下:

poechant@ubuntu:/usr/local/nginx$ ./sbin/nginx -v
nginx: nginx version: nginx/1.0.0

另一種顯示的是詳細的版本信息:

poechant@ubuntu:/usr/local/nginx$ ./sbin/nginx -V
nginx: nginx version: nginx/1.0.0
nginx: built by gcc 4.3.3 (Ubuntu 4.3.3-5ubuntu4) 
nginx: TLS SNI support enabled
nginx: configure arguments: --with-http_ssl_module --with-openssl=/home/luming/openssl-1.0.0d/
  1. 檢查配置文件是否正確
poechant@ubuntu:/usr/local/nginx$ ./sbin/nginx -t
nginx: [alert] could not open error log file: open() "/usr/local/nginx/logs/error.log" failed (13: Permission denied)
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
2012/01/09 16:45:09 [emerg] 23898#0: open() "/usr/local/nginx/logs/nginx.pid" failed (13: Permission denied)
nginx: configuration file /usr/local/nginx/conf/nginx.conf test failed
如果出現如上的提示信息,表示沒有訪問錯誤日志文件和進程,可以sudo(super user do)一下:

poerchant@ubuntu:/usr/local/nginx$ sudo ./sbin/nginx -t
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
如果顯示如上,則表示配置文件正確。否則,會有相關提示。
  1. 顯示幫助信息
poechant@ubuntu:/user/local/nginx$ ./sbin/nginx -h

或者:

poechant@ubuntu:/user/local/nginx$ ./sbin/nginx -?
以上這些涵蓋了 Nginx 日常維護的所有基本操作,另外還有向 master 進程發送信號的相關命令,我們會在后續看到。

配置文件詳解

Nginx配置文件的分塊下,基本就分為以下幾塊:

main # 全局設置
events { # Nginx工作模式
    ....
}
http { # http設置
    ....
    upstream myproject { # 負載均衡服務器設置
        .....
    }
    server  { # 主機設置
        ....
        location { # URL匹配
            ....
        }
    }
    server  {
        ....
        location {
            ....
        }
    }
    ....
}

1 main模塊

下面是一個main區域,它是一個全局的設置:

user nobody nobody;
worker_processes 2;
error_log /usr/local/var/log/nginx/error.log notice;
pid /usr/local/var/run/nginx/nginx.pid;
worker_rlimit_nofile 1024;

user 來指定Nginx Worker進程運行用戶以及用戶組,默認由nobody賬號運行。

worker_processes 來指定了Nginx要開啟的子進程數。每個Nginx進程平均耗費10M~12M內存。根據經驗,一般指定1個進程就足夠了,如果是多核CPU,建議指定和CPU的數量一樣的進程數即可。我這里寫2,那么就會開啟2個子進程,總共3個進程。

error_log 來定義全局錯誤日志文件。日志輸出級別有debug、info、notice、warn、error、crit可供選擇,其中,debug輸出日志最為最詳細,而crit輸出日志最少。

pid 來指定進程id的存儲文件位置

worker_rlimit_nofile 來指定一個nginx進程可以打開的最多文件描述符數目,這里是65535,需要使用命令“ulimit -n 65535”來設置。

2 events模塊

events模塊來用指定nginx的工作模式和工作模式及連接數上限,一般是這樣:

events {
    use kqueue; #mac平臺
    worker_connections  1024;
}

use 用來指定Nginx的工作模式。Nginx支持的工作模式有select、poll、kqueue、epoll、rtsig和/dev/poll。其中select和poll都是標準的工作模式,kqueue和epoll是高效的工作模式,不同的是epoll用在Linux平臺上,而kqueue用在BSD系統中,因為Mac基于BSD,所以Mac也得用這個模式,對于Linux系統,epoll工作模式是首選。

worker_connections 用于定義Nginx每個進程的最大連接數,即接收前端的最大請求數,默認是1024。最大客戶端連接數由worker_processes和worker_connections決定,即Max_clients = worker_processes * worker_connections,在作為反向代理時,Max_clients變為:Max_clients = worker_processes * worker_connections / 4。

進程的最大連接數受Linux系統進程的最大打開文件數限制,在執行操作系統命令“ulimit -n 65536”后worker_connections的設置才能生效。

3 http模塊

http模塊可以說是最核心的模塊了,它負責HTTP服務器相關屬性的配置,它里面的server和upstream子模塊,至關重要,等到反向代理和負載均衡以及虛擬目錄等會仔細說。

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 /usr/local/var/log/nginx/access.log  main;
    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    keepalive_timeout 10;
    #gzip on;
    upstream myproject {
        .....
    }
    server {
        ....
    }
}

  1. include

用來設定文件的mime類型,類型在配置文件目錄下的mime.type文件定義,來告訴nginx來識別文件類型。

  1. default_type

設定了默認的類型為二進制流,也就是當文件類型未定義時使用這種方式,例如在沒有配置asp的locate 環境時,Nginx是不予解析的,此時,用瀏覽器訪問asp文件就會出現下載窗口了。

  1. log_format

用于設置日志的格式,和記錄哪些參數,這里設置為main,剛好用于access_log來紀錄這種類型

main的類型日志如下:也可以增刪部分參數。

127.0.0.1 - - [21/Apr/2015:18:09:54 +0800] "GET /index.php HTTP/1.1" 200 87151 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.76 Safari/537.36"

  1. access_log

用來紀錄每次的訪問日志的文件地址,后面的main是日志的格式樣式,對應于log_format的main。

  1. sendfile

用于開啟高效文件傳輸模式。將tcp_nopush和tcp_nodelay兩個指令設置為on用于防止網絡阻塞。

  1. keepalive_timeout

設置客戶端連接保持活動的超時時間。在超過這個時間之后,服務器會關閉該連接。

4 server模塊

server模塊是http的子模塊,它用來定一個虛擬主機,我們先講最基本的配置,這些在后面再講。我們看一下一個簡單的server是如何做的?

server {
    listen 8080;
    server_name localhost 192.168.12.10 www.yangyi.com;
    # 全局定義,如果都是這一個目錄,這樣定義最簡單。
    root   /Users/yangyi/www;
    index  index.php index.html index.htm; 
    charset utf-8;
    access_log  usr/local/var/log/host.access.log  main;
    error_log  usr/local/var/log/host.error.log  error;
    ....
}

server 標志定義虛擬主機開始。

listen 用于指定虛擬主機的服務端口。

server_name 用來指定IP地址或者域名,多個域名之間用空格分開。

root 表示在這整個server虛擬主機內,全部的root web根目錄。注意要和locate {}下面定義的區分開來。

index 全局定義訪問的默認首頁地址。注意要和locate {}下面定義的區分開來。

charset 用于設置網頁的默認編碼格式。

access_log 用來指定此虛擬主機的訪問日志存放路徑,最后的main用于指定訪問日志的輸出格式。

5 location模塊

location模塊是nginx中用的最多的,也是最重要的模塊了,什么負載均衡啊、反向代理啊、虛擬域名啊都與它相關

location根據它字面意思就知道是來定位的,定位URL,解析URL,所以,它也提供了強大的正則匹配功能,也支持條件判斷匹配,用戶可以通過location指令實現Nginx對動、靜態網頁進行過濾處理。像我們的php環境搭建就是用到了它。

  1. 我們先來看這個,設定默認首頁和虛擬機目錄
location / {
    root   /Users/yangyi/www;
    index  index.php index.html index.htm;
}

location / 表示匹配訪問根目錄。

root 指令用于指定訪問根目錄時,虛擬主機的web目錄,這個目錄可以是相對路徑(相對路徑是相對于nginx的安裝目錄)。也可以是絕對路徑

index 用于設定我們只輸入域名后訪問的默認首頁地址,有個先后順序:index.php index.html index.htm,如果沒有開啟目錄瀏覽權限,又找不到這些默認首頁,就會報403錯誤。

  1. location 還有一種方式就是正則匹配

下面這個例子是運用正則匹配來鏈接php。我們之前搭建環境也是這樣做:

location ~ \.php$ {
    root           /Users/yangyi/www;
    fastcgi_pass   127.0.0.1:9000;
    fastcgi_index  index.php;
    include        fastcgi.conf;
}

.php$ 熟悉正則的我們直到,這是匹配.php結尾的URL,用來解析php文件。里面的root也是一樣,用來表示虛擬主機的根目錄

fastcgi_pass 鏈接的是php-fpm的地址。其他幾個參數我們以后再說。

location 還有其他用法,等講到實例的時候,再看吧。

6 upstream模塊

upstream 模塊負責負載均衡模塊,通過一個簡單的調度算法來實現客戶端IP到后端服務器的負載均衡。先學習怎么用,具體的使用實例以后再說。

upstream iyangyi.com{
    ip_hash;
    server 192.168.12.1:80;
    server 192.168.12.2:80 down;
    server 192.168.12.3:8080  max_fails=3  fail_timeout=20s;
    server 192.168.12.4:8080;
}

在上面的例子中,通過upstream指令指定了一個負載均衡器的名稱iyangyi.com。這個名稱可以任意指定,在后面需要的地方直接調用即可。里面是ip_hash這是其中的一種負載均衡調度算法,下面會著重介紹。緊接著就是各種服務器了。用server關鍵字表識,后面接ip

Nginx的負載均衡模塊目前支持4種調度算法:

  1. weight 輪詢(默認)。每個請求按時間順序逐一分配到不同的后端服務器,如果后端某臺服務器宕機,故障系統被自動剔除,使用戶訪問不受影響。weight,指定輪詢權值,weight值越大,分配到的訪問機率越高,主要用于后端每個服務器性能不均的情況下。

  2. ip_hash。每個請求按訪問IP的hash結果分配,這樣來自同一個IP的訪客固定訪問一個后端服務器,有效解決了動態網頁存在的session共享問題。

  3. fair(第三方)。比上面兩個更加智能的負載均衡算法。此種算法可以依據頁面大小和加載時間長短智能地進行負載均衡,也就是根據后端服務器的響應時間來分配請求,響應時間短的優先分配。Nginx本身是不支持fair的,如果需要使用這種調度算法,必須下載Nginx的upstream_fair模塊。

  4. url_hash(第三方)。按訪問url的hash結果來分配請求,使每個url定向到同一個后端服務器,可以進一步提高后端緩存服務器的效率。Nginx本身是不支持url_hash的,如果需要使用這種調度算法,必須安裝Nginx的hash軟件包。

在HTTP Upstream模塊中,可以通過server指令指定后端服務器的IP地址和端口,同時還可以設定每個后端服務器在負載均衡調度中的狀態。常用的狀態有:

  1. down,表示當前的server暫時不參與負載均衡。

  2. backup,預留的備份機器。當其他所有的非backup機器出現故障或者忙的時候,才會請求backup機器,因此這臺機器的壓力最輕。

  3. max_fails,允許請求失敗的次數,默認為1。當超過最大次數時,返回proxy_next_upstream 模塊定義的錯誤。

  4. fail_timeout,在經歷了max_fails次失敗后,暫停服務的時間。max_fails可以和fail_timeout一起使用。

注意:當負載調度算法為ip_hash時,后端服務器在負載均衡調度中的狀態不能是weight和backup。

基于域名的虛擬主機

有的網站訪問量大,需要負載均衡。然而并不是所有網站都如此出色,有的網站,由于訪問量太小,需要節省成本,將多個網站部署在同一臺服務器上。

例如將www.aaa.comwww.bbb.com兩個網站部署在同一臺服務器上,兩個域名解析到同一個IP地址,但是用戶通過兩個域名卻可以打開兩個完全不同的網站,互相不影響,就像訪問兩個服務器一樣,所以叫兩個虛擬主機。

配置:

server {
    listen 80 default_server;
    server_name _;
    return 444; # 過濾其他域名的請求,返回444狀態碼
}
server {
    listen 80;
    server_name www.aaa.com; # www.aaa.com域名
    location / {
        proxy_pass http://localhost:8080; # 對應端口號8080
    }
}
server {
    listen 80;
    server_name www.bbb.com; # www.bbb.com域名
    location / {
        proxy_pass http://localhost:8081; # 對應端口號8081
    }
}

在服務器8080和8081分別開了一個應用,客戶端通過不同的域名訪問,根據server_name可以反向代理到對應的應用服務器。

虛擬主機的原理是通過HTTP請求頭中的Host是否匹配server_name來實現的,有興趣的同學可以研究一下HTTP協議。

另外,server_name配置還可以過濾有人惡意將某些域名指向你的主機服務器。

建議將對虛擬主機進行配置的內容寫進另外一個文件,然后通過include指令包含進來,這樣更便于維護和管理,不會使得這個nginx.conf內容太多.

反向代理

Nginx 使用反向代理,主要是使用location模塊下的proxy_pass選項。

來個最簡單的。當我訪問 mac 上的nginx 的 centos.iyangyi.com 的內容時候, 就反向代理到虛擬機centos上的 apache 192.168.33.10 的index.html頁面。

192.168.33.10 中的html 是很簡單的一句輸出:

centos apache2 index.html

在hosts里新加上這個域名:

#vi /etc/hosts 
127.0.0.1 centos.iyangyi.com

在vhost目錄中新建一個conf server:

#centos.iyangyi.conf
server {
    listen 80;
    server_name centos.iyangyi.com;

    access_log /usr/local/var/log/nginx/centos.iyangyi.access.log main;
    error_log /usr/local/var/log/nginx/centos.iyangyi.error.log error;

    location / {
        proxy_pass http://192.168.33.10;
    }
}

重啟下nginx:

sudo nginx -s reload

當然。proxy 還有其他的參數,比如:proxy_set_header 用來設置header頭部信息參數轉發等,等用了可以仔細看看。

負載均衡

別被這個名字給嚇住了,以為是什么很牛逼的東西的。其實不然。也很簡單。

先簡單說下負載均衡是干嘛的?舉個例子:我們的小網站,剛開始就一臺nginx服務器,后來,隨著業務量增大,用戶增多,一臺服務器已經不夠用了,我們就又多加了幾臺服務器。那么這幾臺服務器如何調度?如何均勻的提供訪問?這就是負載均衡。

負載均衡的好處是可以集群多臺機器一起工作,并且對外的IP和域名是一樣的,外界看起來就好像一臺機器一樣。

  1. 基于 weight 權重的負載

先來一個最簡單的,weight權重的:

upstream webservers{
    server 192.168.33.11 weight=10;
    server 192.168.33.12 weight=10;
    server 192.168.33.13 weight=10;
}

server {
    listen 80;
    server_name upstream.iyangyi.com;

    access_log /usr/local/var/log/nginx/upstream.iyangyi.access.log main;
    error_log /usr/local/var/log/nginx/upstream.iyangyi.error.log error;

    location / {
        proxy_pass http://webservers;
        proxy_set_header  X-Real-IP  $remote_addr;
    }
}

我們再來繼續看幾個參數 : max_fails和fail_timeout

**max_fails : **允許請求失敗的次數,默認為1。當超過最大次數時,返回proxy_next_upstream 模塊定義的錯誤。

**fail_timeout : **在經歷了max_fails次失敗后,暫停服務的時間。max_fails可以和fail_timeout一起使用,進行健康狀態檢查。

upstream webservers{
    server 192.168.33.11 weight=10 max_fails=2 fail_timeout=30s;
    server 192.168.33.12 weight=10 max_fails=2 fail_timeout=30s;
    server 192.168.33.13 weight=10 max_fails=2 fail_timeout=30s;
}

down: 表示這臺機器暫時不參與負載均衡。相當于注釋掉了。

backup: 表示這臺機器是備用機器,是其他的機器不能用的時候,這臺機器才會被使用,俗稱備胎

upstream webservers{
    server 192.168.33.11 down;
    server 192.168.33.12 weight=10 max_fails=2 fail_timeout=30s;
    server 192.168.33.13 backup;
}
  1. 基于 ip_hash 的負載

這種分配方式,每個請求按訪問IP的hash結果分配,這樣來自同一個IP的訪客固定訪問一個后端服務器,有效解決了動態網頁存在的session共享問題。

upstream webservers{
    ip_hash;
    server 192.168.33.11 weight=1 max_fails=2 fail_timeout=30s;
    server 192.168.33.12 weight=1 max_fails=2 fail_timeout=30s;
    server 192.168.33.13 down;
}

ip_hash 模式下,最好不要設置weight參數,因為你設置了,就相當于手動設置了,將會導致很多的流量分配不均勻。

ip_hash 模式下,backup參數不可用,加了會報錯,為啥呢?因為,本身我們的訪問就是固定的了,其實,備用已經不管什么作用了。

頁面緩存

頁面緩存也是日常web 開發中很重要的一個環節,對于一些頁面,我們可以將其靜態化,保存起來,下次請求時候,直接走緩存,而不用去請求反相代理服務器甚至數據庫服務了。從而減輕服務器壓力。

nginx 也提供了簡單而強大的下重定向,反向代理的緩存功能,只需要簡單配置下,就能將指定的一個頁面緩存起來。它的原理也很簡單,就是匹配當前訪問的url, hash加密后,去指定的緩存目錄找,看有沒有,有的話就說明匹配到緩存了。

我們先來看一下一個簡單的頁面緩存的配置:

http {
    proxy_cache_path /data/nginx/cache levels=1:2 keys_zone=cache_zone:10m inactive=1d max_size=100m;
    upstream myproject {
        .....
    }
    server  {
        ....
        location ~ *\.php$ {
            proxy_cache cache_zone; #keys_zone的名字
            proxy_cache_key $host$uri$is_args$args; #緩存規則
            proxy_cache_valid any 1d;
            proxy_pass http://127.0.0.1:8080;
        }
    }
    ....
}

下面我們來一步一步說。用到的配置參數,主要是proxy_*前綴的很多配置。

首先需要在http中加入proxy_cache_path 它用來制定緩存的目錄以及緩存目錄深度制定等。它的格式如下:

proxy_cache_path path [levels=number] keys_zone=zone_name:zone_size [inactive=time] [max_size=size]; 

path是用來指定 緩存在磁盤的路徑地址。比如:/data/nginx/cache。那以后生存的緩存文件就會存在這個目錄下。

levels用來指定緩存文件夾的級數,可以是:levels=1, levels=1:1, levels=1:2, levels=1:2:3 可以使用任意的1位或2位數字作為目錄結構分割符,如 X, X:X,或 X:X:X 例如: 2, 2:2, 1:1:2,但是最多只能是三級目錄。

那這個里面的數字是什么意思呢。表示取hash值的個數。比如:

現在根據請求地址localhost/index.php?a=4 用md5進行哈希,得到e0bd86606797639426a92306b1b98ad9

levels=1:2 表示建立2級目錄,把hash最后1位(9)拿出建一個目錄,然后再把9前面的2位(ad)拿來建一個目錄, 那么緩存文件的路徑就是/data/nginx/cache/9/ad/e0bd86606797639426a92306b1b98ad9

以此類推:levels=1:1:2表示建立3級目錄,把hash最后1位(9)拿出建一個目錄,然后再把9前面的1位(d)建一個目錄, 最后把d前面的2位(8a)拿出來建一個目錄 那么緩存文件的路徑就是/data/nginx/cache/9/d/8a/e0bd86606797639426a92306b1b98ad9

keys_zone 所有活動的key和元數據存儲在共享的內存池中,這個區域用keys_zone參數指定。zone_name指的是共享池的名稱,zone_size指的是共享池的大小。注意每一個定義的內存池必須是不重復的路徑,例如:

proxy_cache_path  /data/nginx/cache/one  levels=1      keys_zone=one:10m;
proxy_cache_path  /data/nginx/cache/two  levels=2:2    keys_zone=two:100m;
proxy_cache_path  /data/nginx/cache/three  levels=1:1:2  keys_zone=three:1000m;

inactive 表示指定的時間內緩存的數據沒有被請求則被刪除,默認inactive為10分鐘。inactive=1d 1小時。inactive=30m 30分鐘。

max_size 表示單個文件最大不超過的大小。它被用來刪除不活動的緩存和控制緩存大小,當目前緩存的值超出max_size指定的值之后,超過其大小后最少使用數據(LRU替換算法)將被刪除。max_size=10g表示當緩存池超過10g就會清除不常用的緩存文件。

clean_time 表示每間隔自動清除的時間。clean_time=1m 1分鐘清除一次緩存。

好。說完了這個很重要的參數。我們再來說在server模塊里的幾個配置參數:

proxy_cache 用來指定用哪個keys_zone的名字,也就是用哪個目錄下的緩存。上面我們指定了三個one, two,three 。比如,我現在想用one 這個緩存目錄 : proxy_cache one

proxy_cache_key 這個其實蠻重要的,它用來指定生成hash的url地址的格式。根據這個key映射成一個hash值,然后存入到本地文件。proxy_cache_key $host$uri表示無論后面跟的什么參數,都會訪問一個文件,不會再生成新的文件。 而如果proxy_cache_key $is_args$args,那么傳入的參數 localhost/index.php?a=4 與localhost/index.php?a=44 將映射成兩個不同hash值的文件。

proxy_cache_key 默認是 "$scheme$host$request_uri"。但是一般我們會把它設置成:$host$uri$is_args$args 一個完整的url路徑。

proxy_cache_valid 它是用來為不同的http響應狀態碼設置不同的緩存時間。

proxy_cache_valid  200 302  10m;
proxy_cache_valid  404      1m;

表示為http status code 為200和302的設置緩存時間為10分鐘,404代碼緩存1分鐘。 如果只定義時間:

proxy_cache_valid 5m;

那么只對代碼為200, 301和302的code進行緩存。 同樣可以使用any參數任何相響應:

proxy_cache_valid  200 302 10m;
proxy_cache_valid  301 1h;
proxy_cache_valid  any 1m; #所有的狀態都緩存1小時

好。緩存的基本一些配置講完了。也大致知道了怎么使用這些參數。現在開始實戰!我們啟動一臺vagrant linux 機器 web1 (192.168.33.11) 用作遠程代理機器,就不搞復雜的負載均衡了。

先在Mac本地加一個域名cache.iyangyi.com, 然后按照上面的配置在vhost 下新建一個proxy_cache.iyangyi.conf 文件:

proxy_cache_path /usr/local/var/cache levels=1:2 keys_zone=cache_zone:10m inactive=1d max_size=100m;
server  {
    listen 80;
    server_name cache.iyangyi.com;

    access_log /usr/local/var/log/nginx/cache.iyangyi.access.log main;
    error_log /usr/local/var/log/nginx/cache.iyangyi.error.log error;

    add_header X-Via $server_addr;
    add_header X-Cache $upstream_cache_status;

    location / {
        proxy_set_header  X-Real-IP  $remote_addr;
        proxy_cache cache_zone;
        proxy_cache_key $host$uri$is_args$args;
        proxy_cache_valid 200 304 1m;
        proxy_pass http://192.168.33.11;
    }
}

打開審核元素或者firebug。看network網絡請求選項,我們可以看到,Response Headers,在這里我們可以看到:

X-Cache:MISS
X-Via:127.0.0.1

X-cache 為 MISS 表示未命中,請求被傳送到后端。因為是第一次訪問,沒有緩存,所以肯定是未命中。我們再刷新下,就發現其變成了HIT, 表示命中。它還有其他幾種狀態:

MISS 未命中,請求被傳送到后端

HIT 緩存命中

EXPIRED 緩存已經過期請求被傳送到后端

UPDATING 正在更新緩存,將使用舊的應答

STALE 后端將得到過期的應答

BYPASS 緩存被繞過了

我們再去看看緩存文件夾 /usr/local/var/cache里面是否有了文件:

cache git:(master) cd a/13
?  13 git:(master) ls
5bd1af99bcb0db45c8bd601d9ee9e13a
?  13 git:(master) pwd
/usr/local/var/cache/a/13

已經生成了緩存文件。

我們在url 后面隨便加一個什么參數,看會不會新生成一個緩存文件夾及文件:http://cache.iyangyi.com/?w=ww55 。因為我們使用的生成規則是全部url轉換(proxy_cache_key $host$uri$is_args$args;)

查看 X-cache 為 MISS,再刷新 ,變成HIT。再去看一下緩存文件夾 /usr/local/var/cache。

~cache git:(master) ls
 4 a

果然又生成了一個4文件夾。

location 正則模塊

這一小節,主要來學習nginx中的URL重寫怎么做。url重寫模塊,主要是在location模塊面來實現,我們一點一點的看。

首先看下location 正則匹配的使用。還記得之前是如何用location來定位.php文件的嗎?

location ~ \.php$ {
    fastcgi_pass   127.0.0.1:9000; 
    fastcgi_index  index.php;
    include        fastcgi.conf;
}

我們用~來表示location開啟正則匹配, 這樣:location ~。還可以用這個來匹配靜態資源,緩存它們,設置過期時間:

location ~ .*\.(gif|jpg|jpeg|bmp|png|ico|txt|mp3|mp4|swf){
    expires 15d;
}
location ~ .*\.(css|js){
    expires 12h;
}

expires 用來設置HTTP應答中的Expires和Cache-Control的頭標時間,來告訴瀏覽器訪問這個靜態文件時,不用再去請求服務器,直接從本地緩存讀取就可以了

語法: expires [time|epoch|max|off]
默認值: expires off
作用域: http, server, location

可以在time值中使用正數或負數。“Expires”頭標的值將通過當前系統時間加上您設定的 time 值來獲得。可以設置的參數如下:

epoch 指定“Expires”的值為 1 January, 1970, 00:00:01 GMT。

max 指定“Expires”的值為 31 December 2037 23:59:59 GMT,“Cache-Control”的值為10年。

-1 指定“Expires”的值為 服務器當前時間 -1s,即永遠過期。

負數:Cache-Control: no-cache。

正數或零:Cache-Control: max-age = #, # 會轉換為指定時間的秒數。比如:1d、2h、3m。

off 表示不修改“Expires”和“Cache-Control”的值。

比如再看個例子: 控制圖片等過期時間為30天

location ~ \.(gif|jpg|jpeg|png|bmp|ico)$ {
    expires 30d;
}

我們還可以控制哪一個文件目錄的時間,比如控制匹配/resource/或者/mediatorModule/里所有的文件緩存設置到最長時間。

location ~ /(resource|mediatorModule)/ {
    root    /opt/demo;
    expires max;
}

URL重寫模塊

重寫模塊與很多模塊一起使用。先看一下是怎么用的,看2個例子,然后我們再一點一點講每個的使用方法:

location /download/ {
    if ($forbidden) {
        return   403;
    }
    if ($slow) {
        limit_rate  10k;
    }
    rewrite ^/(download/.*)/media/(.*)\..*$  /$1/mp3/$2.mp3 break;
    ......
}
location / {
    root   html;
    index  index.html index.htm;
    rewrite ^/bbs/(.*)$ http://192.168.18.201/forum/$1;
}

上面2個例子就是利用rewrite來完成URL重寫的。我們慢慢來看它的用法。

  1. break

break和編程語言中的用法一樣,就是跳出某個邏輯。

語法:break

默認值:none

使用字段:server, location, if

if (!-f $request_filename) {
    break;
}

上面這個例子就是在if里面使用break,意思是如果訪問的文件名不存在,就跳出。后續會有更多的例子。

  1. if

if 判斷一個條件,如果條件成立,則后面的大括號內的語句將執行,相關配置從上級繼承。

語法:if (condition) { … }

默認值:none

使用字段:server, location

可以在判斷語句中指定下列值:

一個變量的名稱;不成立的值為:空字符傳”“或者一些用“0”開始的字符串。

一個使用=或者!=運算符的比較語句。

使用符號*和模式匹配的正則表達式:

~為區分大小寫的匹配。

~*不區分大小寫的匹配(firefox匹配FireFox)。

!和!*意為“不匹配的”。

使用-f和!-f檢查一個文件是否存在。

使用-d和!-d檢查一個目錄是否存在。

使用-e和!-e檢查一個文件,目錄或者軟鏈接是否存在。

使用-x和!-x檢查一個文件是否為可執行文件。

$http_user_agent變量獲取瀏覽器的agent,使用~ 來匹配大小寫。用戶如果使用的IE 瀏覽器,就執行if里面的操作。

if ($http_user_agent ~ MSIE) {
    rewrite  ^(.*)$  /msie/$1  break;
}

$request_method變量獲取請求的方法,使用=來判斷是否等于POST 。如果復合,就執行if 里面的操作。

if ($request_method = POST ) {
    return 405;
}

$request_filename變量獲取請求的文件名,使用!-f來匹配文件,如果不是一個文件名,就執行if 里面的邏輯。

if (!-f $request_filename) {
    break;
    proxy_pass  http://127.0.0.1;
}
  1. return

這個指令結束執行配置語句并為客戶端返回狀態代碼,可以使用下列的值:204,400,402-406,408,410, 411, 413, 416與500-504。此外,非標準代碼444將關閉連接并且不發送任何的頭部。

語法:return code

默認值:none

使用字段:server, location, if

  1. rewrite

語法:rewrite regex replacement flag

默認值:none

使用字段:server, location, if

rewrite用來重寫url,有3個位置:

regex 表示用來匹配的正則

replacement 表示用來替換的

flag 是尾部的標記

flag可以是以下的值:

last - url重寫后,馬上發起一個新的請求,再次進入server塊,重試location匹配,超過10次匹配不到報500錯誤,地址欄url不變

break - url重寫后,直接使用當前資源,不再執行location里余下的語句,完成本次請求,地址欄url不變

redirect - 返回302臨時重定向,url會跳轉,爬蟲不會更新url。

permanent - 返回301永久重定向。url會跳轉。爬蟲會更新url。

為空 - URL 不會變,但是內容已經變化,也是永久性的重定向。

上面的正則表達式的一部分可以用圓括號,方便之后按照順序用$1-$9來引用。

我們來看幾個例子:

需要將/photos/123456重寫成/path/to/photos/12/1234/123456.png

可以這樣:

rewrite  "/photos/([0-9] {2})([0-9] {2})([0-9] {2})" /path/to/photos/$1/$1$2/$1$2$3.png;

下面是一些簡單的常見的重寫:

rewrite ^/js/base.core.v3.js /js/base.core.v3.dev.js redirect;
rewrite ^/js/comment.frame.js /js/comment.frame.dev.js redirect;
rewrite ^/live-static/(.*)$ http://live.bilibili.com/public/$1 last;

配置整理

在此記錄下Nginx服務器nginx.conf的配置文件說明, 部分注釋收集與網絡:

# 運行用戶
user www-data;    
# 啟動進程,通常設置成和cpu的數量相等
worker_processes  1;

# 全局錯誤日志及PID文件
error_log  /var/log/nginx/error.log;
pid        /var/run/nginx.pid;

# 工作模式及連接數上限
events {
    use epoll; #epoll是多路復用IO(I/O Multiplexing)中的一種方式,但是僅用于linux2.6以上內核,可以大大提高nginx的性能
    worker_connections 1024; #單個后臺worker process進程的最大并發鏈接數
    # multi_accept on; 
}

#設定http服務器,利用它的反向代理功能提供負載均衡支持
http {
    #設定mime類型,類型由mime.type文件定義
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;
    #設定日志格式
    access_log    /var/log/nginx/access.log;

    #sendfile 指令指定 nginx 是否調用 sendfile 函數(zero copy 方式)來輸出文件,對于普通應用,
    #必須設為 on,如果用來進行下載等應用磁盤IO重負載應用,可設置為 off,以平衡磁盤與網絡I/O處理速度,降低系統的uptime.
    sendfile        on;
    #將tcp_nopush和tcp_nodelay兩個指令設置為on用于防止網絡阻塞
    tcp_nopush      on;
    tcp_nodelay     on;
    #連接超時時間
    keepalive_timeout  65;

    #開啟gzip壓縮
    gzip  on;
    gzip_disable "MSIE [1-6]\.(?!.*SV1)";

    #設定請求緩沖
    client_header_buffer_size    1k;
    large_client_header_buffers  4 4k;

    include /etc/nginx/conf.d/*.conf;
    include /etc/nginx/sites-enabled/*;

    #設定負載均衡的服務器列表
    upstream mysvr {
        #weigth參數表示權值,權值越高被分配到的幾率越大
        #本機上的Squid開啟3128端口
        server 192.168.8.1:3128 weight=5;
        server 192.168.8.2:80  weight=1;
        server 192.168.8.3:80  weight=6;
    }

    server {
        #偵聽80端口
        listen       80;
        #定義使用www.xx.com訪問
        server_name  www.xx.com;

        #設定本虛擬主機的訪問日志
        access_log  logs/www.xx.com.access.log  main;

        #默認請求
        location / {
            root   /root;      #定義服務器的默認網站根目錄位置
            index index.php index.html index.htm;   #定義首頁索引文件的名稱

            fastcgi_pass  www.xx.com;
            fastcgi_param  SCRIPT_FILENAME  $document_root/$fastcgi_script_name; 
            include /etc/nginx/fastcgi_params;
        }

        # 定義錯誤提示頁面
        error_page   500 502 503 504 /50x.html;  
            location = /50x.html {
            root   /root;
        }

        #靜態文件,nginx自己處理
        location ~ ^/(images|javascript|js|css|flash|media|static)/ {
            root /var/www/virtual/htdocs;
            #過期30天,靜態文件不怎么更新,過期可以設大一點,如果頻繁更新,則可以設置得小一點。
            expires 30d;
        }
        #PHP 腳本請求全部轉發到 FastCGI處理. 使用FastCGI默認配置.
        location ~ \.php$ {
            root /root;
            fastcgi_pass 127.0.0.1:9000;
            fastcgi_index index.php;
            fastcgi_param SCRIPT_FILENAME /home/www/www$fastcgi_script_name;
            include fastcgi_params;
        }
        #設定查看Nginx狀態的地址
        location /NginxStatus {
            stub_status            on;
            access_log              on;
            auth_basic              "NginxStatus";
            auth_basic_user_file  conf/htpasswd;
        }
        #禁止訪問 .htxxx 文件
        location ~ /\.ht {
            deny all;
        }

    }

    #第一個虛擬服務器
    server {
        #偵聽192.168.8.x的80端口
        listen       80;
        server_name  192.168.8.x;

        #對aspx后綴的進行負載均衡請求
        location ~ .*\.aspx$ {
            root   /root;#定義服務器的默認網站根目錄位置
            index index.php index.html index.htm;#定義首頁索引文件的名稱

            proxy_pass  http://mysvr;#請求轉向mysvr 定義的服務器列表

            #以下是一些反向代理的配置可刪除.
            proxy_redirect off;

            #后端的Web服務器可以通過X-Forwarded-For獲取用戶真實IP
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            client_max_body_size 10m;    #允許客戶端請求的最大單文件字節數
            client_body_buffer_size 128k;  #緩沖區代理緩沖用戶端請求的最大字節數,
            proxy_connect_timeout 90;  #nginx跟后端服務器連接超時時間(代理連接超時)
            proxy_send_timeout 90;        #后端服務器數據回傳時間(代理發送超時)
            proxy_read_timeout 90;         #連接成功后,后端服務器響應時間(代理接收超時)
            proxy_buffer_size 4k;             #設置代理服務器(nginx)保存用戶頭信息的緩沖區大小
            proxy_buffers 4 32k;               #proxy_buffers緩沖區,網頁平均在32k以下的話,這樣設置
            proxy_busy_buffers_size 64k;    #高負荷下緩沖大小(proxy_buffers*2)
            proxy_temp_file_write_size 64k;  #設定緩存文件夾大小,大于這個值,將從upstream服務器傳
        }
    }
}

參考

WEB請求處理二:Nginx請求反向代理

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容