nginx知識點簡單回顧

来源:http://www.cnblogs.com/f-ck-need-u/archive/2017/10/17/7683027.html
-Advertisement-
Play Games

本文目錄:1. nginx簡介2. nginx處理請求的過程簡單說明3. nginx命令4. nginx模塊及http功能速覽5. nginx配置文件簡單說明 5.1 main和events段 5.2 http段 5.2.1 配置文件概覽 5.2.2 root指令和alias指令 5.2.3 loc ...


本文目錄:
1. nginx簡介
2. nginx處理請求的過程簡單說明
3. nginx命令
4. nginx模塊及http功能速覽
5. nginx配置文件簡單說明
 5.1 main和events段
 5.2 http段
  5.2.1 配置文件概覽
  5.2.2 root指令和alias指令
  5.2.3 location容器
  5.2.4 error_page指令
  5.2.5 allow和deny
  5.2.6 add_header添加相應首部欄位
 5.3 虛擬主機和server_name指令
 5.4 虛擬主機的匹配規則
 5.5 stub_status指令獲取nginx狀態信息
6. 訪問日誌access_log
 6.1 log_format指令
 6.2 access_log指令
 6.3 日誌文件的分割
7. 配置web身份認證
8. 配置https


1. nginx簡介

nginx是一個優秀的web服務程式、反向代理程式。它採用非阻塞非同步的套接字,使用epoll方式實現事件驅動,同時採用一個master+N個worker進程(預設)的方式處理請求,這種架構使得它在併發的處理能力上極其出色,可以比較輕鬆地解決C10K問題。

2. nginx處理請求的過程簡單說明

master進程用於管理worker進程,例如接收外界信號、向worker進程發送信號、銷毀worker進程、啟動worker進程等等。

nginx之所以性能良好,完全是由它的架構決定的。每個worker進程是業務處理進程,負責監聽套接字、處理請求、響應請求、代理請求至後端伺服器等。

作為web server處理靜態資源時每個worker進程的大致流程:

(1).監聽套接字。
(2).與客戶端建立連接。
(3).處理監聽到的連接請求(載入靜態文件)。
(4).響應數據。
(5).斷開連接。

這幾個過程是每個web server都具備的能力,但對於nginx來說,由於它的非同步非阻塞,每個過程都不會阻塞(有些小過程必須阻塞的時候還是會阻塞),使得併發處理能力很好。

從監聽套接字開始說。每個worker進程都是平等的,它們都可以去監聽套接字,正常情況下不可避免地會造成爭搶和"驚群問題",而nginx採用"爭搶"accept互斥鎖的方式,只有持有accept互斥鎖的worker進程才有資格將連接請求接到自己的隊列中並完成TCP連接的建立。但每個進程是相互獨立而平等的,誰有資格去"爭搶"互斥鎖且有更大幾率爭搶成功?只要worker進程當前建立的連接數小於worker_connections指令指定的值(實際上源碼中設置的是該值的7/8),就允許爭搶互斥鎖,因為連接數超過了該值的7/8表示已經非常繁忙。除了繁忙程度限制資格,還有epoll_wait的timeout的指標,等待越久的worker進程爭搶能力越強。總之,在某一時刻,一定只有一個worker進程監聽並accept新的連接請求

當已經監聽到連接請求時,worker進程與它進行三次握手,並最終accpet到自己的記憶體池中,並和客戶端交互數據,處理客戶端發送的http請求並響應數據給客戶端。但是,nginx的高效就在於它的非同步非阻塞,無論是在TCP連接進入ESTABLISHED之前,還是等待客戶端發送請求,亦或者是等待載入本地靜態資源的I/O,以及響應數據給客戶端的任意一個過程中,nginx都是非阻塞的,在任意等待發生時都可以去處理其它事情。當等待的某個資源已經準備成功時將產生事件通知worker進程,worker進程可隨後去處理。在此過程中,由於worker進程綁定在一個CPU核心上(推薦如此做),所有的連接都放在記憶體池中,這使得上下文切換時是極其輕量的,極大地減輕了CPU消耗。從理論上來說,當每個worker綁定了一個CPU核心時,它的併發處理能力主要依賴於記憶體的大小。

實際上apache httpd的event MPM也是非同步非阻塞的,也可以採用epoll,但它採用的是多線程方式,雖然非同步,但它的非同步似乎不體現在併發能力上,而僅僅只是一些具有特殊狀態的連接(如長連接)的非同步處理,在處理過程中cpu還是不斷地需要在各線程之間大量切換,併發能力並不比worker MPM強多少,相比nginx更是遠遠不如。

3. nginx命令

[root@xuexi nginx]# nginx -h
nginx version: nginx/1.12.0
Usage: nginx [-?hvVtTq] [-s signal] [-c filename] [-p prefix] [-g directives]

Options:
  -?,-h         : this help
  -v            : 輸出版本號
  -V            : 輸出版本號以及編譯選項
  -t            : 檢查配置文件的語法
  -T            : 檢查配置文件的語法並輸出配置的內容
  -q            : 靜默模式,不輸出任何信息
  -s signal     : 向主進程發送信號:stop, quit, reopen, reload
  -p prefix     : 設置nginx的basedir(預設為編譯時的prefix)
  -c filename   : 指定配置文件
  -g directives : 提前設置全局指令

-V選項輸出編譯選項。

[root@xuexi nginx]# nginx -V
nginx version: nginx/1.12.0
built by gcc 4.4.7 20120313 (Red Hat 4.4.7-11) (GCC) 
built with OpenSSL 1.0.1e-fips 11 Feb 2013
TLS SNI support enabled
configure arguments: --prefix=/usr/local/nginx-1.12.0 --pid-path=/var/run/nginx/nginx.pid --lock-path=/var/lock/subsys/nginx.lock --user=nginx --group=nginx --with-http_ssl_module --with-http_flv_module --with-http_stub_status_module --with-http_gzip_static_module --with-pcre

(1).使用預設配置文件直接啟動nginx和指定配置文件啟動nginx

nginx -c /usr/local/nginx/conf/nginx.conf

(2).運行時重載配置文件。當nginx主進程接收到重載配置文件的命令後,它會先檢查新配置文件語法,然後載入該配置文件到記憶體中並解析。然後,主進程fork一系列新的worker進程,併發送QUIT信號給舊的worker進程(graceful stop)。舊的工作進程接收到QUIT信號後,會停止接受新的連接請求,並繼續處理舊的連接直到請求處理完成後才退出。

nginx -s reload

(3).運行時快速關閉nginx。

nginx -s stop

(4).運行時優雅關閉nginx。所有的工作進程會停止接受新的連接,並繼續服務舊的連接請求直到所有的請求完成後才退出。

nginx -s quit

(5).運行時重新打開日誌文件。

ngnix -s reopen

4. nginx模塊及http功能速覽

Nginx的代碼由一個核心和一系列的模塊組成。

核心(core functionality)主要用於提供全局應用的基本功能,創建必要的運行時環境及確保不同模塊之間平滑地進行交互等,對應於配置文件的main段和event段。核心涉及的指令官方文檔:http://nginx.org/en/docs/ngx_core_module.html

還有很多功能都通過模塊實現,nginx是高度模塊化程式。如web相關的功能模塊有"ngx_http_*_module",和mail相關的功能模塊有"ngx_mail_*_module",和tcp代理、負載均衡相關的功能模塊有"ngx_stream_*_module",這些類別的模塊中又分為很多類別的模塊,如http類別的模塊中有基本核心模塊、事件類模塊、緩存類模塊、SSL相關模塊、負載均衡類模塊upstream等等。

以下是http功能模塊類中常見的模塊。

http類模塊名模塊功能說明
ngx_http_core_module http核心模塊,對應配置文件中的http段,包含很多指令,如location指令
ngx_http_access_module 訪問控制模塊,控制網站用戶對nginx的訪問,對應於配置文件中的allow和deny等指令
ngx_http_auth_basic_module 通過用戶名和密碼認證的訪問控制,如訪問站點時需要數據用戶名和密碼,指令包括auth_basic和auth_basic_user_file
ngx_http_charset_module 設置網頁顯示字元集。指令之一為charset,如charset utf-8
ngx_http_fastcgi_module fastcgi模塊,和動態應用相關。該模塊下有非常多的子模塊。
ngx_http_flv_module 支持flv視頻流的模塊,如邊下邊播
ngx_http_mp4_module 同flv模塊
ngx_http_gzip_module 壓縮模塊,用來壓縮nginx返回的響應報文。一般只壓縮純文本內容,因為壓縮比例非常大,而圖片等不會去壓縮
ngx_http_image_filter_module 和圖片裁剪、縮略圖相關模塊,需要安裝gd-devel才能編譯該模塊
ngx_http_index_module 定義將要被作為預設主頁的文件,對應指令為index。"index index.html,index.php"
ngx_http_autoindex_module 當index指令指定的主頁文件不存在時,交給autoindex指令,將自動列出目錄中的文件autoindex {on/off}  
ngx_http_log_module 和訪問日誌相關的模塊,指令包括log_format和access_log
ngx_http_memcached_module 和memcached相關的模塊,用於從memcached伺服器中獲取相應響應數據
ngx_http_proxy_module 和代理相關,允許傳送請求到其它伺服器
ngx_http_realip_module 當nginx在反向代理的後端提供服務時,獲取到真正的客戶端地址,否則獲取的是反向代理的IP地址
ngx_http_referer_module 實現防盜鏈功能的模塊
ngx_http_rewrite_module 和URL地址重寫相關的模塊,需要安裝pcre-devel才能編譯安裝該模塊
ngx_http_scgi_module simple cgi,是cgi的替代品,和fastcgi類似,但更簡單
ngx_http_ssl_module 提供ssl功能的模塊,即實現HTTPS
ngx_http_stub_status_module 獲取nginx運行狀態信息
ngx_http_upstream 和負載均衡相關模塊

這些模塊共同組成了nginx的http功能。

5. nginx配置文件簡單說明

nginx的配置文件有很多個,如下。其中主配置文件為nginx.conf,其他配置文件在需要的時候使用include指令將其包含到主配置文件中。

[root@xuexi ~]# ls /usr/local/nginx/conf/
fastcgi.conf  fastcgi_params  koi-utf  mime.types  nginx.conf  scgi_params  uwsgi_params  win-utf
fastcgi.conf.default  fastcgi_params.default  koi-win  mime.types.default  nginx.conf.default  scgi_params.default  uwsgi_params.default

其中".default"尾碼的是對應首碼配置文件的備份配置文件,".params"是對應首碼的參數文件。如fastcgi.conf是和fastcgi相關參數的配置文件,fastcgi.params是fastcgi的參數文件,fastcgi.conf.default是fastcgi.conf的備份文件。

關於主配置文件nginx.conf,由於Nginx高度模塊化,所以它是分段配置的,核心模塊為core,對應配置文件中的Main和Events段。此外還有其他一些模塊。配置文件中每一個指令必須以分號";"結束,否則語法錯誤。

5.1 main和events段

Main用於配置錯誤日誌、進程及許可權等相關的參數,Events用於配置IO模型,如epoll、kqueue、select或poll等,它們是必備模塊。如下配置:

#user  nobody;        # worker進程身份,預設使用編譯時指定值.語法為"user user_name [group_name]"
worker_processes  4;  # worker進程數量,該指令值依賴因素較多,例如是否CPU密集型、是否IO密集型。
                      # 在初始時設置為cpu的總核數是一個不錯的選擇。

#error_log logs/error.log;         # 錯誤日誌文件,禁用錯誤日誌"error_log /dev/null LEVEL;"
#error_log logs/error.log notice;  # 級別:debug|info|notice|warn|error|crit|alert|emerg,預設為error
#error_log  logs/error.log  info;

#pid        logs/nginx.pid;
#lock_file  logs/nginx.lock;

events {
    worker_connections  1024;   # 每個worker進程的最大連接數
    multi_accept on;            # 是否一次性將監聽到的連接全接收進來,預設為off,關閉時一次接收一條連接
    accept_mutex on             # 預設為on,開啟時表示以串列方式接入新連接,否則將通報給所有worker。
                                # 這可能會浪費資源並產生不可預計的後果,例如驚群問題
}

如果某個文件採用了相對路徑,則其相對的基準為basedir。例如編譯時--prefix指定為/usr/local/nginx,則指定pid為logs/nginx.pid時,其實際路徑為/usr/local/nginx/logs/nginx.pid。

worker_processes的值和work_connections的值決定了最大併發數量。例如上面的配置中,每個worker進程最大允許1024個連接,配置了4個worker進程,所以併發數量為1024*4=4096。但在反向代理場景中計算方法不同,因為nginx既要維持和客戶端的連接,又要維持和後端伺服器的連接,因此處理一次連接要占用2個連接,所以最大併發數計算方式為:worker_processes*worker_connections/2。此外還需註意,除了和客戶端的連接、與後端伺服器的連接,nginx可能還會打開其他的連接,這些都會占用文件描述符,從而影響併發數量的計算。最後還需註意,最大併發數量還受"允許打開的最大文件描述符數量"限制,可以使用"worker_rlimit_nofile"指令修改或直接修改操作系統的對應內核參數。

可以在main段使用worker_cpu_affinity指令綁定CPU核心。nginx通過位數識別CPU核心以及核心數,指定位數上占位符為1表示使用該核心,占位符為0表示不使用該核心。例如2核cpu的位數分別為01和10,4核的位數分別為1000,0100,0010以及0001,同理8核和16核。在結合worker_processes指令一起使用時,要註意worker進程和核心的對應方式,例如:

# 每個worker分別對應cpu0/cpu1/cpu2/cpu3
worker_processes    4;
worker_cpu_affinity 0001 0010 0100 1000;

# 有4核心,但只有兩worker,第一個worker對應cpu0/cpu2,第二個worker對應cpu1/cpu3
worker_processes    2;
worker_cpu_affinity 0101 1010;

在events段,可以使用"use"指令可以指定使用哪種I/O模型,Linux上預設是epoll,通常可以不用手動去設置,因為nginx預設會採用最佳配置。

以下是main段和events段的配置示例,大多數採用的預設值,需要修改的大致就是worker數量、每個worker最大連接數以及進程綁定cpu。

worker_processes  4;
events {
    worker_connections  1024;
}

5.2 http段

5.2.1 配置文件概覽

http段是由http相關模塊支持的。以下是預設配置項。註意,http根段下使用相對路徑是相對conf目錄的,如"include extra/.conf"表示的是conf/extra/.conf;非根段內的相對路徑如server段內使用相對路徑是相對於的。

http {
    include       mime.types;    # nginx支持的媒體文件類型。相對路徑為同目錄conf下的其他文件
    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;   # 啟用sendfile傳輸模式,此模式是"零拷貝"
    #tcp_nopush     on;   # 只在sendfile on時有效。讓數據包擠滿到一定程度才發送出去,擠滿之前被阻塞

    #keepalive_timeout  0;   # keepalive的超時時間
    keepalive_timeout  65;

    #gzip  on;               # 是否啟用gzip壓縮響應報文

    server {                    # 定義虛擬主機
        listen       80;        # 定義監聽套接字
        server_name  localhost; # 定義主機名加功能變數名稱,即網站地址

        #charset koi8-r;        # 預設字元集

        #access_log  logs/host.access.log  main;         # 訪問日誌路徑

        location / {                        # location容器,即URI的根
            root   html;                    # 站點根目錄,即DocumentRoot,相對路徑時為<prefix>/html
            index  index.html index.htm;    # 站點主頁文件
        }

        #error_page  404    /404.html;      # 出現404 page not fount錯誤時,使用/404.html頁響應客戶端

        # redirect server error pages to the static page /50x.html
        #
        error_page   500 502 503 504  /50x.html;      # 出現50x錯誤時,使用/50x.html頁返回給客戶端
        location = /50x.html {                        # 定義手動輸入包含/50x.html時的location
            root   html;
        }

        # 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;
    #    }
    #}
}

5.2.2 root指令和alias指令

root指令設置站點根目錄,即httpd的documentroot,但又有所不同,因為nginx可以在多個上下文位置處使用root指令,例如Location容器中。

如果配置如下:

location /i/ {
    root /data/w3;
}

那麼nginx將使用文件/data/w3/i/top.gif響應請求"/i/top.gif"。

root指令僅僅只是將匹配的URI追加在root路徑後,如果要改變URI,應該使用alias指令,它會對URI進行替換。例如:

location /i/ {
    alias /data/w3/images/;
}

那麼nginx將使用文件/data/w3/images/top.gif響應請求/i/top.gif。因此,如果alias指令的路徑最後一部分包含了URI,則最好使用root指令,而非alias指令,雖然它們都能成功響應。

location /images/ {
    alias /data/w3/images/;
}

location /images/ {
    root /data/w3/;
}

它們都能使用相對路徑,相對的是prefix。例如編譯路徑為/usr/local/nginx,則"root html"指的是"/usr/local/nginx/html"。

與root和alias指令相關的變數為$document_root、$readpath_root。其中$document_root的值即是root指令、alias指令的值,而$realpath_root的值是對root、alias指令進行絕對路徑換算後的值

5.2.3 location容器

該指令對規範化後的URI進行匹配,並對匹配的路徑封裝一系列指令。 語法:

location [ = | ~ | ~* | ^~ ] uri { ... }

其中: location /uri/ {}:表示對/uri/目錄及其子目錄下的所有文件都匹配。所以"location / {}"的匹配範圍是最大的。
location = /uri/ {}:表示只對目錄或文件進行匹配,不對目錄中的文件和子目錄進行匹配。所以一般只用來做文件匹配
location ~ /uri/ {}:表示區分大小寫的正則匹配。
location *~ /uri/ {}:表示不區分大小寫的正則匹配。
location ^~ /uri/ {}:表示禁用正則匹配,即精確字元串匹配,此時正則中的元字元被解釋成普通字元。

它們的匹配優先順序規則為:nginx先檢查URI的首碼路徑,在這些路徑中找到最精確匹配請求URI的路徑。然後nginx按在配置文件中的出現順序檢查正則表達式路徑,匹配上某個路徑後即停止匹配並使用該路徑的配置,否則使用最大首碼匹配的路徑的配置

使用"="首碼可以定義URI和路徑的精確匹配。如果發現匹配,則終止路徑查找。例如請求"/"很頻繁,定義"location = /"可以提高這些請求的處理速度,因為查找過程在第一次比較以後即結束。

以下是一個優先順序的示例。

location = / {
    [ configuration A ]
}

location / {
    [ configuration B ]
}

location /documents/ {
    [ configuration C ]
}

location ^~ /images/ {
    [ configuration D ]
}

location ~* \.(gif|jpg|jpeg)$ { 
    [ configuration E ] 
}

請求"/"能匹配A和B,但最精確匹配為A。
請求"/index.html"的首碼"/"能匹配A和B,但A只能匹配"/"自身,因此最終匹配配置B。(首碼也能匹配E,但文件名無法匹配)
請求"/documents/document.html"的首碼能匹配B和C,但C更精確,因此匹配配置C。(首碼也能匹配E,但文件名無法匹配)
請求"/images/1.gif"的首碼能匹配B、D和E,且D和E都是最長路徑匹配,但^~優先順序更高,因此匹配配置D。
請求"/documents/1.jpg"的首碼能匹配B、C,同樣也能匹配E,且E比B的匹配更精確,因此最終匹配配置E。

大致可以將規則簡化為如下優先順序:

(location = uri ) > (location ^~ uri) > (location *~|~ uri) > (location uri)

等號優先順序最高,非正則匹配次之,再之後是正在匹配,它們之間有位置的先後順序,優先順序最低的是沒有使用任何符號的匹配

由此也可以知道,"location / {}"這種方式是一種特殊的uri匹配,無論什麼uri路徑,都能往這裡面裝,可以認為它是預設匹配,當其它location都匹配不上時就會匹配它。

5.2.4 error_page指令

當出現對應狀態碼的錯誤時,指定返回的URI路徑。語法為:

error_page code ... [=[response]] uri;

配置文件中的error_page部分預設為:

location / {
    root   html;
    index  index.html index.htm;
}
#error_page  404              /404.html;
error_page   500 502 503 504  /50x.html;
location = /50x.html {
    root   html;
}

上面的配置文件中,假如取消了404錯誤的error_page行註釋,當出現404錯誤時,其uri為/404.html,然後會對其進行location的匹配,由於只有"location / {}"能匹配到,所以它的目錄為/html/,即404.html文件路徑為/html/404.html。對於50x的error_page,其uri為"/50x.html",所以會對其進行location匹配,發現可以精確匹配到"location = /50x.html {}",當然"location / {}"也能匹配到,但是它的優先順序更低,所以當出現50x錯誤時,將從/html目錄下尋找50x.html,這裡正好和"location / {}"重覆了,但它們的匹配過程是不一樣的。假如改為如下配置:

location / {                         
    root   html;                     
    index  index.html index.htm;     
}
#error_page  404              /404.html;
error_page   500 502 503 504  /50x.html;
location = /50x.html {
    root   /www/a.com/;
}

出現50x錯誤時,將返回/www/a.com/50x.html文件,而不再是/html/50x.html。

5.2.5 allow和deny

這兩個指令由ngx_http_access_module模塊提供,用於允許或限制某些IP地址的客戶端訪問。nginx中的allow和deny規則很簡單,從上向下匹配,只要匹配到就停止。例如:

allow 10.0.0.8
allow 192.168.100.0/24
deny all

允許10.0.0.8和192.168.100網段的訪問,其他的都拒絕。

5.2.6 add_header添加相應首部欄位

用於在響應首部中添加欄位。例如:

server {
    add_header RealPath $realpath_root;
}

將添加一個名為RealPath的欄位,值為變數realpath_root的值。

[root@xuexi ~]# curl -I http://localhost/
HTTP/1.1 200 OK
Server: nginx/1.12.1
Date: Tue, 17 Oct 2017 08:10:14 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Tue, 17 Oct 2017 03:20:10 GMT
Connection: keep-alive
ETag: "59e576ea-264"
RealPath: /usr/local/nginx-1.12.1/html   # 此為自定義添加欄位
Accept-Ranges: bytes

5.3 虛擬主機和server_name指令

nginx使用server容器定義一個虛擬主機。在nginx中,沒有嚴格區分基於IP和基於名稱的虛擬主機,它們通過listen指令和server_name指令結合起來形成不同的虛擬主機。

例如:

# 基於IP地址的虛擬主機
server {
        listen 80;
        server_name 192.168.100.25;
        location / {
                root /www/longshuai/;
                index index.html index.htm;
        }
}
server {
        listen 80;
        server_name 192.168.100.26;
        location / {
                root /www/xiaofang/;
                index index.html index.htm;
        }
}

# 基於名稱的虛擬主機
server {
        listen 80;
        server_name www.longshuai.com;
        location / {
                root /www/longshuai/;
                index index.html index.htm;
        }
}
server {
        listen 80;
        server_name www.xiaofang.com;
        location / {
                root /www/xiaofang/;
                index index.html index.htm;
        }
}

# 基於埠的虛擬主機
server {
        listen 80;
        server_name 192.168.100.25;
        location / {
                root /www/longshuai/;
                index index.html index.htm;
        }
}
server {
        listen 8080;
        server_name 192.168.100.25;
        location / {
                root /www/xiaofang/;
                index index.html index.htm;
        }
}

其中server_name指令可以定義多個主機名,第一個名字為虛擬主機的首要主機名。例如:

server_name  example.com   www.example.com;

主機名中可以含有星號("*"),以替代名字的開始部分或結尾部分(只能是起始或結尾,如果要實現中間部分的通配,可以使用正則表達式)。例如"*.example.org"不僅匹配www.example.org,也匹配www.sub.example.org。下麵兩條指令是等價的。

server_name    example.com   *.example.com   www.example.*;
server_name   .example.com   www.example.*;

也可以在主機名中使用正則表達式,就是在名字前面補一個波浪線("~"):

server_name   www.example.com   ~^www\d+\.example\.com$;

nginx允許定義空主機名:

server {
    listen       80;
    server_name  "";
    return       444;
}

這種主機名可以讓虛擬主機處理沒有"Host"首部的請求,而不是讓指定"地址:埠"的預設虛擬主機來處理,而這正是本指令的預設設置。即使用非預設的虛擬主機處理請求頭中不含"Host"欄位的請求。一般這樣的請求處理方式是直接丟棄請求,並返回一個非標準的狀態碼來立即關閉連接,例如上面的444。

如果server塊中沒有定義server_name,nginx使用空名字作為虛擬主機名。

5.4 虛擬主機的匹配規則

通過名字查找虛擬主機時,如果一個名字可以匹配多個指定的配置,比如同時匹配上通配符和正則表達式,按下麵優先順序,使用先匹配上的虛擬主機:

  1. 確定的名稱;
  2. 最長的以星號起始的通配符名字,比如"*.example.com";
  3. 最長的以星號結束的通配符名字,比如"mail.*";
  4. 第一個匹配的正則表達式名字(按在配置文件中出現的順序)。

當開始接入請求時,(1)nginx首先判斷請求的套接字,即IP和埠號;(2)然後在listen套接字中選擇一個能匹配名稱的虛擬主機,如果沒有選出能匹配的名稱,則使用該套接字的預設虛擬主機。預設情況下,監聽套接字的預設虛擬主機為該套接字主機組中的第一個虛擬主機,但可以通過listen指令的default_server屬性手動指定。

例如下麵定義了4個虛擬主機:前3個都監聽在192.168.100.1:80上,第四個監聽在192.168.100.2:80上。

server {
    listen      192.168.100.1:80;
    server_name example.org www.example.org;
    ...
}

server {
    listen      192.168.100.1:80 default_server;
    server_name example.net www.example.net;
    ...
}

server {
    listen      192.168.100.1:80;
    server_name example.com www.example.com;
    ...
}

server {
    listen      192.168.1.2:80;
    server_name example.com www.example.com;
    ...
}

(1).從192.168.100.1:80上請求www.example.com,能匹配虛擬主機3,於是使用虛擬主機3的配置進行響應;
(2).從192.168.100.1:80上請求www.longshuai.com時,無法匹配任何虛擬主機,於是使用預設虛擬主機2的配置進行響應。如果將listen的屬性default_server去掉,則使用虛擬主機1進行響應;
(3).從192.168.100.2:80上請求www.example.com時,使用虛擬主機4進行響應;
(4).從192.168.100.2:80上請求www.example.org時,由於無法匹配該套接字上的任何主機,於是使用預設虛擬主機響應,即虛擬主機4。

5.5 stub_status指令獲取nginx狀態信息

使用ngx_http_stub_status_module模塊提供的功能可以獲取nginx運行的狀態信息。對應的指令只有一個,即stub_status。

例如,在某一個server下加上如下配置獲取該server的狀態信息。

server {
    listen 80;
    server_name www.longshuai.com;
    location / {
        root /www/longshuai/;
        index index.html index.htm;
    }
    location /status {
        stub_status on;
    }
}

還可以明確指定訪問該信息不記錄日誌,且提供訪問控制,不讓外界人隨意獲取信息。

location /status {
    stub_status on;
    access_log off;
    allow 192.168.100.0/24;
    deny all;
}

重載配置文件後,只需在瀏覽器中輸入"主機名/status"即可獲取信息。

Active connections: 291 
server accepts handled requests
 16630948 16630948 31070465 
Reading: 6 Writing: 179 Waiting: 106

狀態信息意義如下:

  • 第一行active connections:291表示當前處於活動狀態的客戶端連接數,包括正處於等待狀態的連接。
  • 第四行reading數量為6,表示nginx正在讀取請求首部的數量,即正在從socket recv buffer中讀取數據的數量;writing數量為179表示nginx正在將響應數據寫入socket send buffer以返回給客戶端的連接數量;waiting數量為106表示等待空閑客戶端發起請求的客戶端數量,包括長連接狀態的連接以及已接入但socket recv buffer還未產生可讀事件的連接,其值為active-reading-writing。
  • 第二行accepts的數量為16630948表示從服務啟動開始到現在已經接收進來的總的客戶端連接數;handled的數量為16630948表示從服務啟動以來已經處理過的連接數,一般handled的值和accepts的值相等,除非作出了連接數限定;requests的數量為服務啟動依賴總的客戶端請求數。一個連接可以有多個請求,所以可以計算出平均每個連接發出多少個請求。
  • 以下是第二行幾個參數的官方原文:
    accepts:The total number of accepted client connections.
    handled:The total number of handled connections. Generally, the parameter value is the same as accepts unless some resource limits have been reached (for example, the worker_connections limit).
    requests:The total number of client requests.
    

6. 訪問日誌access_log

  1. nginx的訪問日誌相關功能由ngx_http_log_module模塊提供,指令包括log_format、access_log和open_log_file_cache。
  2. nginx的日誌可以先緩衝到buffer中,一定時間後再寫入到日誌文件中。從buffer刷盤到本地日誌文件中時,可以進行壓縮。
  3. nginx的worker進程的運行身份需要有日誌創建的許可權,即對日誌所在目錄有寫許可權。
  4. 可以在多種上下文中定義是否開啟日誌以及日誌的格式。最常見的三個上下文是http,server,location。
  5. open_log_file_cache指令存在的意義是為了緩存日誌文件描述符。之所以提供這個指令,是因為nginx每次日誌的寫入(從緩存中刷盤到本地日誌文件中)都會打開、關閉一次日誌文件。對於日誌寫入極其頻繁的機器可以使用該指令緩存日誌文件描述符,使得在緩存有效期內都可以續寫到舊日誌文件中。

6.1 log_format指令

log_format指定日誌的格式,語法如下:log\_format name string...;。其中name指定日誌格式名稱,配置文件中name名稱不能重覆。

以下是預設提供的main格式。

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

在main後面的是一堆變數,除了這些變數之外還有其他很多變數可用,但如非特殊需求,預設的main格式就已經夠完美了。以下是變數的意義:

$remote_addr:客戶端的地址。如果nginx提供的web服務在後端,如前面有代理伺服器或負載均衡等設備時,該變數只能獲取到前端的IP地址。此時要獲取到真正客戶端地址需要使用變數$http_x_forward_for,但要求前端伺服器要開啟x_forward_for設置。
$http_x_forward_for:如上所述。
$remote_user:遠程客戶端用戶名稱。
$time_local:記錄訪問時間和時區信息。
$request:記錄用戶訪問時的url和http協議信息。如:"GET /favicon.ico HTTP/1.1"$status:記錄客戶端請求時返回的狀態碼,如成功的狀態碼為200,page not found的狀態碼為404$body_bytes_sent:記錄伺服器響應給客戶端的主體大小。
$http_referer:記錄此次請求是從哪個鏈接過來的,需要模塊ngx_http_referer_module支持,預設已裝,可以防止倒鏈問題。
$http_user_agent:記錄客戶端的瀏覽器信息。如使用什麼瀏覽器發起的請求,是否是壓力測試工具在測試等。

例如,以下是預設格式的日誌信息。

192.168.100.27 - - [23/Apr/2017:23:08:56 +0800] "GET /index.html HTTP/1.0" 200 17 "-" "ApacheBench/2.3"
192.168.100.27 - - [23/Apr/2017:23:08:56 +0800] "GET /index.html HTTP/1.0" 200 17 "-" "ApacheBench/2.3"
192.168.100.27 - - [23/Apr/2017:23:08:56 +0800] "GET /index.html HTTP/1.0" 200 17 "-" "ApacheBench/2.3"
192.168.100.27 - - [23/Apr/2017:23:08:56 +0800] "GET /index.html HTTP/1.0" 200 17 "-" "ApacheBench/2.3"
192.168.100.1 - - [23/Apr/2017:23:08:56 +0800] "GET /status HTTP/1.1" 200 109 "-" "Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko"
192.168.100.1 - - [23/Apr/2017:23:08:56 +0800] "GET /status HTTP/1.1" 200 109 "-" "Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko"
192.168.100.1 - - [23/Apr/2017:23:08:56 +0800] "GET /status HTTP/1.1" 200 109 "-" "Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko"
192.168.100.27 - - [23/Apr/2017:23:08:57 +0800] "GET /index.html HTTP/1.0" 200 17 "-" "ApacheBench/2.3"
192.168.100.27 - - [23/Apr/2017:23:08:57 +0800] "GET /index.html HTTP/1.0" 200 17 "-" "ApacheBench/2.3"
192.168.100.27 - - [23/Apr/2017:23:08:57 +0800] "GET /index.html HTTP/1.0" 200 17 "-" "ApacheBench/2.3"

6.2 access_log指令

access_log主要用於定義使用什麼格式的日誌,日誌存放路徑。語法如下:

access_log path [format [buffer=size] [gzip[=level]] [flush=time] [if=condition]];
access_log off;

path指定路徑,path里可以使用變數。format指定日誌格式,不寫時或者配置文件中未配置access_log指令時,預設為combined。buffer=size指定日誌緩衝區大小(預設64K),flush=time指定日誌刷盤的時間,if=condition指定某些條件,gzip=level指定日誌刷盤前先壓縮的壓縮級別(預設gzip=1)。

當指定了buffer或者gzip任意一個時,都會使用buffer先緩衝日誌,然後再刷盤。

例如

access_log /spool/logs/nginx-access.log gzip buffer=32k;

6.3 日誌文件的分割

預設nginx不會自動分割日誌,也不支持在配置文件中使用cronolog以及rotatelogs(apache支持,因為支持管道傳遞)。要實現nginx的日誌分割,需要通過移動舊日誌、生成新日誌來實現。

mv old_log new_log
# 然後
nginx -s reload
# 或者
nginx -s reopen
# 或者
kill -s USR1 master_pid

pid可以通過pid文件獲得。

kill -s USR1 $(cat /var/run/nginx/nginx.pid)

要實現自動分割,需要使用腳本,並設置定時任務。

cat /usr/local/nginx/logs/cut_longhsuai.sh
#!/bin/bash

# cut the access log for www.longshuai.com

basedir=/usr/local/nginx
old_log_path=$basedir/logs/access.log
log_save_path=$basedir/logs
save_log_name=access_$(date -d "yesterday" +"%Y%m%d").log

[ -f "$old_log_path" ] || exit 1
/bin/mv $old_log_path $log_save_path/$save_log_name
$basedir/sbin/nginx -s reopen

再添加定時任務計劃。

chmod +x /usr/local/nginx/logs/cut_longshuai.sh

crontab -e
00 00 * * * /bin/sh /usr/local/nginx/logs/cut_longshuai.sh &>/dev/null

7. 配置web身份認證

需要輸入用戶名和密碼才能訪問站點的功能為web身份認證功能。nginx中由ngx_http_auth_basic_module模塊提供該功能。指令包括auth_basic和auth_basic_user_file。這兩個指令可以在http根段、server段、location段使用。

auth_basic string | off
auth_basic_user_file path/to/user_passwd_file        # 密碼文件使用相對路徑時是相對conf目錄的

passwd_file的格式為:

user1:passwd1
user2:passwd2

需要註意的是,密碼文件不能使用明文密碼的方式。該類文件一般使用apache提供的工具htpasswd生成,該工具在httpd-tools包中,具體用法見htpasswd命令。也可以使用openssl passwd生成相關密碼然後複製到密碼文件中。以下是一個示例:

server {
    listen 80;
    server_name www.longshuai.com  www1.longshuai.com;
    location / {
        root /www/longshuai/;
        index index.html index.htm;
        auth_basic "Auth your name";
        auth_basic_user_file /usr/local/nginx/htpasswd;
    }
}

然後使用htpasswd生成密碼文件/usr/local/nginx/conf/htpasswd。

yum -y install httpd-tools
htpasswd -b -c -m /usr/local/nginx/conf/htpasswd Jim 123456
htpasswd -b -m /usr/local/nginx/conf/htpasswd Tom 123456

-b選項是表示batch模式,不用交互輸入密碼。-c表示創建密碼文件,只能為第一個用戶使用該選項,否則後面使用會覆蓋前面

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 一.環境:: ubuntu 16.04 二.安裝過程: 2.1 去微信官網獲取最新的windows64位版本的微信開發工具 https://servicewechat.com/wxa-dev-logic/download_redirect?type=x64&from=mpwiki 2.2 安裝win ...
  • 1》Nginx概述: 很多人對apache非常熟悉,Nginx與Apache類似,屬於WEB容器,同時也是一款高性能的HTTP和反向代理軟體,它們之間最大的差別是Apache的處理速 度很慢,而且占用很多記憶體資源,而Nginx卻恰恰相反,在功能實現上,Apache的所有模塊都是支持動靜態編譯,而Ng ...
  • 一、keil 5安裝park文件的方法 1.安裝keil 5後,會彈出如下的park文件安裝界面,分別顯示了安裝的park文件、實例、設備以及開發板。點擊Parks->Check For Update會自動更新最新的Park文件。 此外也可以點擊keil中的Park Installer快捷按鈕進入p ...
  • 一、聲明: 本文采用操作系統版本: Centos 7 Linux系統 版本源:CentOS-7-x86_64-DVD-1708.iso 官網下載地址:http://isoredirect.centos.org/centos/7/isos/x86_64/CentOS-7-x86_64-DVD-1708 ...
  • 本系列文章主要介紹linux下主流的開源郵件系統postfix的搭建過程,構建一個通過postfix虛擬用戶管理的完整的郵件系統 本文接著上文的環境,進行postfix郵件發信端和dovecot郵件收信端的部署,之後部署基於瀏覽器的extmail圖形管理端,使管理員可以通過網頁對郵件虛擬用戶進行管理 ...
  • 在“求佛保佑伺服器不宕機”、“殺程式員祭天”的環境下,程式員每天可謂是戰戰兢兢,接到電話和簡訊都嚇得瑟瑟發抖,為了我們的安全,及時發現伺服器運行問題已不僅僅是運維的問題了。本文總結了常見的伺服器監控指標,希望各位開發人員都搞一個腳本運行著以保障自己的生命安全。 ...
  • 本系列文章主要介紹linux下主流的開源郵件系統postfix的搭建過程,構建一個通過postfix虛擬用戶管理的完整的郵件系統, 該系統包括以下組件: 郵件收髮端postfix,dovecot, 郵件管理端:extmail,extman 安全認證:cyrus-sasl 防病毒,防垃圾 本文主要介紹 ...
  • Expect是在Tcl基礎上創建起來的,它還提供了一些Tcl所沒有的命令,它可以用來做一些linux下無法做到交互的一些命令操作,在遠程管 理方面發揮很大的作用。 spawn命令激活一個Unix程式來進行互動式的運行。 send命令向進程發送字元串。 expect 命令等待進程的某些字元串。 exp ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...