1. 程式人生 > >linux學習54-高效能WEB服務NGINX

linux學習54-高效能WEB服務NGINX

在這裡插入圖片描述

高效能WEB服務NGINX

1. 效能影響

  • 使用者速度體驗的1-3-10原則

    1. 概念
      網際網路存在使用者速度體驗的1-3-10原則,即01秒最優,13秒較優,3~10秒比較慢,10秒以上使用者無法接受。使用者放棄一個產品的代價很低,只是換一個URL而已
    2. 參考資料
      全球最大搜索引擎 Google:慢500ms = 20% 將放棄訪問。
      全球最大的網上中文書店 亞馬遜:慢100ms = 1% 將放棄交易
  • 效能對使用者的行為的影響

    1. 79%的使用者表示不太可能再次開啟一個緩慢的網站
    2. 47%的使用者期望網頁能在2秒鐘以內載入
    3. 40%的使用者表示如果載入時間超過三秒鐘,就會放棄這個網站
    4. 頁面載入時間延遲一秒可能導致轉換損失7%,頁面瀏覽量減少11%
    5. 8秒定律:使用者訪問一個網站時,如果等待網頁開啟的時間超過8秒,會有超過30%的使用者放棄等待
  • I/O介紹
    NGINX比Apache效能優秀,與I/O模型密切相關

    1. 相關概念
      PIO:應用程式輸入輸出,磁碟讀寫資料–>經過CPU轉發–>記憶體
      DMA:直接記憶體訪問,cpu收到使用者請求,將指令傳送給DMAC(直接記憶體訪問控制器),由DMAC執行磁碟資料讀入到記憶體中,cpu不參與I/O過程,提高cpu利用率
    2. 常見I/O
      1. 網路IO
        從網絡卡上接收或傳送資料,在linux中一切皆檔案,所以會開啟一個socket檔案來讀取
      2. 磁碟IO
        每次read,都要經由兩個階段:
        1. 第一步:將資料從磁碟檔案先載入至核心記憶體空間(緩衝區),等待資料準備完成,時間較長
        2. 第二步:將資料從核心緩衝區複製到使用者空間的程序的記憶體中,時間較短
          在這裡插入圖片描述

2. I/O模型

  • I/O模型常用概念

    1. 同步/非同步:關注的是訊息通訊機制
      1. 同步:synchronous,呼叫者等待被呼叫者返回訊息,才能繼續執行,呼叫者主動問被呼叫者執行結果
      2. 非同步:asynchronous,被呼叫者通過狀態、通知或回撥機制主動通知呼叫者被呼叫者的執行狀態
    2. 阻塞/非阻塞:關注呼叫者在等待結果返回之前所處的狀態
      1. 阻塞:blocking,指IO操作需要徹底完成後才返回到使用者空間,呼叫結果返回之前,呼叫者被掛起不能執行其他操作
      2. 非阻塞:nonblocking,指IO操作被呼叫後立即返回給使用者一個狀態值,無需等到IO操作徹底完成,最終的呼叫結果返回之前,呼叫者不會被掛起
  • I/O模型分類
    阻塞型、非阻塞型、複用型、訊號驅動型、非同步

    1. 同步阻塞IO模型
      1. 同步阻塞IO模型是最簡單的IO模型,使用者執行緒在核心進行IO操作時被阻塞
      2. 使用者執行緒通過系統呼叫read發起IO讀操作,由使用者空間轉到核心空間。核心等到資料包到達後,然後將接收的資料拷貝到使用者空間,完成read操作
      3. 使用者需要等待read將資料讀取到buffer後,才繼續處理接收的資料。整個IO請求的過程中,使用者執行緒是被阻塞的,這導致使用者在發起IO請求時,不能做任何事情,對CPU的資源利用率不夠
    2. 同步非阻塞IO模型
      1. 使用者執行緒發起IO請求時立即返回。但並未讀取到任何資料,使用者執行緒需要不斷地發起IO請求,直到資料到達後,才真正讀取到資料,繼續執行。即 “輪詢”機制,輪詢只發生在磁碟I/O第一階段,第二階段仍然處於阻塞狀態
      2. 整個IO請求的過程中,雖然使用者執行緒每次發起IO請求後可以立即返回,但是為了等到資料,仍需要不斷地輪詢、重複請求,消耗了大量的CPU的資源
      3. 是比較浪費CPU的方式,一般很少直接使用這種模型,而是在其他IO模型中使用非阻塞IO這一特性
    3. .I/O多路複用模型
      1. IO多路複用是指核心一旦發現程序指定的一個或者多個IO條件準備讀取,就通知該程序
      2. 多個連線共用一個等待機制,本模型會阻塞程序,但是程序是阻塞在select或者poll這 兩個系統呼叫上,而不是阻塞在真正的IO操作上
      3. 使用者首先將需要進行IO操作新增到select中,繼續執行做其他的工作(非同步),同時等待select系統呼叫返回。當資料到達時,IO被啟用,select函式返回。使用者執行緒正式發起read請求,讀取資料並繼續執行
      4. 從流程上來看,使用select函式進行IO請求和同步阻塞模型沒有太大的區別,甚至還多了新增監視IO,以及呼叫select函式的額外操作,效率更差。並且阻塞了兩次,但是第一次阻塞在select上時,select可以監控多個IO上是否已有IO操作準備就緒,即可達到在同一個執行緒內同時處理多個IO請求的目的。而不像阻塞IO那種,一次只能監控一個IO
      5. 雖然上述方式允許單執行緒內處理多個IO請求,但是每個IO請求的過程還是阻塞的(在select函式上阻塞),平均時間甚至比同步阻塞IO模型還要長。如果使用者執行緒只是註冊自己需要的IO請求,然後去做自己的事情,等到資料到來時再進行處理,則可以提高CPU的利用率
      6. IO多路複用是最常使用的IO模型,但是其非同步程度還不夠“徹底”,因它使用了會阻塞執行緒的select系統呼叫。因此IO多路複用只能稱為非同步阻塞IO模型,而非真正的非同步IO
    4. 訊號驅動IO模型
      1. 訊號驅動IO:signal-driven I/O
      2. 使用者程序可以通過sigaction系統呼叫註冊一個訊號處理程式,然後主程式可以繼續向下執行,當有IO操作準備就緒時,由核心通知觸發一個SIGIO訊號處理程式執行,然後將使用者程序所需要的資料從核心空間拷貝到使用者空間
      3. 此模型的優勢在於等待資料報到達期間程序不被阻塞。使用者主程式可以繼續執行,只要等待來自訊號處理函式的通知
    5. 非同步IO模型
      1. 非同步IO與訊號驅動IO最主要的區別是訊號驅動IO是由核心通知何時可以進行IO操作,而非同步IO則是由核心告訴使用者執行緒IO操作何時完成。訊號驅動IO當核心通知觸發訊號處理程式時,訊號處理程式還需要阻塞在從核心空間緩衝區拷貝資料到使用者空間緩衝區這個階段,而非同步IO直接是在第二個階段完成後,核心直接通知使用者執行緒可以進行後續操作了
      2. 相比於IO多路複用模型,非同步IO並不十分常用,不少高效能併發服務程式使用IO多路複用模型+多執行緒任務處理的架構基本可以滿足需求。目前作業系統對非同步IO的支援並非特別完善,更多的是採用IO多路複用模型模擬非同步IO的方式(IO事件觸發時不直接通知使用者執行緒,而是將資料讀寫完畢後放到使用者指定的緩衝區中)
  • I/O模型的具體實現

    1. Select
      Linux實現,對應I/O複用模型,BSD4.2最早實現,POSIX標準,一般作業系統
      1. 優點
        POSIX所規定,目前幾乎在所有的平臺上支援,其良好跨平臺支援也是它的一個優點,本質上是通過設定或者檢查存放fd標誌位的資料結構來進行下一步處理
      2. 缺點
        1. 單個程序能夠監視的檔案描述符的數量存在最大限制,在Linux上一般為1024,可以通過修改巨集定義FD_SETSIZE,再重新編譯核心實現,但是這樣也會造成效率的降低
        2. 單個程序可監視的fd數量被限制,預設是1024,修改此值需要重新編譯核心
        3. 對socket是線性掃描,即採用輪詢的方法,效率較低
        4. select 採取了記憶體拷貝方法來實現核心將 FD 訊息通知給使用者空間,這樣一個用來存放大量fd的資料結構,這樣會使得使用者空間和核心空間在傳遞該結構時複製開銷大
    2. poll
      Linux實現,對應I/O複用模型,System V unix最早實現,本質上和select沒有區別,它將使用者傳入的陣列拷貝到核心空間,然後查詢每個fd對應的裝置狀態
      1. 優點
        1. 其沒有最大連線數的限制,原因是它是基於連結串列來儲存的
        2. 大量的fd的陣列被整體複製於使用者態和核心地址空間之間,而不管這樣的複製是不是有意義
        3. poll特點是“水平觸發”,如果報告了fd後,沒有被處理,那麼下次poll時會再次報告該fd
    3. epoll
      在Linux 2.6核心中提出的select和poll的增強版本,Linux特有,對應I/O複用模型,具有訊號驅動I/O模型的某些特性
      支援水平觸發LT和邊緣觸發ET,最大的特點在於邊緣觸發,它只告訴程序哪些fd剛剛變為就需態,並且只會通知一次
      使用“事件”的就緒通知方式,通過epoll_ctl註冊fd,一旦該fd就緒,核心就會採用類似callback的回撥機制來啟用該fd,epoll_wait便可以收到通知
      1. 優點:
        1. 沒有最大併發連線的限制:能開啟的FD的上限遠大於1024(1G的記憶體能監聽約10萬個埠),具體檢視/proc/sys/fs/file-max,此值和系統記憶體大小相關
        2. 效率提升:非輪詢的方式,不會隨著FD數目的增加而效率下降;只有活躍可用的FD才會呼叫callback函式,即epoll最大的優點就在於它只管理“活躍”的連線,而跟連線總數無關
        3. 記憶體拷貝,利用mmap(Memory Mapping)加速與核心空間的訊息傳遞;即epoll使用mmap減少複製開銷
    4. Kqueue
      FreeBSD實現,對應I/O複用模型,具有訊號驅動I/O模型某些特性
    5. /dev/poll
      SUN的Solaris實現,對應I/O複用模型,具有訊號驅動I/O模型的某些特性
    6. Iocp
      Windows實現,對應第5種(非同步I/O)模型

3. Nginx介紹

NGINX是免費,開源,高效能的HTTP和反向代理伺服器,郵件代理伺服器,通用TCP/UDP代理伺服器

  • 二次開發版
    Tengine
    OpenResty(章亦春)
  • 特性
    1. 高併發,解決C10K問題(10K Connections)
    2. 模組化設計,較好的擴充套件性
    3. 高可靠性
    4. 支援熱部署:不停機更新配置檔案,升級版本,更換日誌檔案
    5. 低記憶體消耗:10000個keep-alive連線模式下的非活動連線,僅需2.5M記憶體
  • 基本功能:
    1. 靜態資源的web伺服器
      html,圖片,js,css,txt等靜態資源
    2. http協議反向代理伺服器
    3. pop3/imap4協議反向代理伺服器
    4. FastCGI(LNMP),uWSGI(python)等協議
    5. 模組化(非DSO),如zip,SSL模組
  • nginx的程式架構:master/worker結構
    1. 一個master程序:
      負載載入和分析配置檔案、管理worker程序、平滑升級
    2. 一個或多個worker程序,
      程序數量一般與cpu數有關聯,每個程序可以處理多個使用者請求
      處理並響應使用者請求
  • 快取相關的程序:
    1. cache loader:載入快取物件
    2. cache manager:管理快取物件

4. nginx模組

nginx高度模組化,1.9.11版本支援DSO機制

DSO:動態支援模組的載入或解除安裝

  • 模組分類:
    在這裡插入圖片描述
    1. 核心模組:core module
      是 Nginx 伺服器正常執行 必不可少 的模組,提供 錯誤日誌記錄 、 配置檔案解析 、 事件驅動機制 、 程序管理 等核心功能
    2. 標準模組
      提供 HTTP 協議解析相關的功能,比如: 埠配置 、 網頁編碼設定 、 HTTP響應頭設定 等等
      1. HTTP 模組: ngx_http_*
        HTTP Core modules 預設功能
        HTTP Optional modules 需編譯時指定
      2. Stream 模組:ngx_stream_*
    3. 可選HTTP模組
      主要用於擴充套件標準的 HTTP 功能,讓 Nginx 能處理一些特殊的服務,比如: Flash 多媒體傳輸 、解析 GeoIP 請求、 網路傳輸壓縮 、 安全協議 SSL 支援等
    4. Mail 模組:ngx_mail_*
      主要用於支援 Nginx 的 郵件服務 ,包括對 POP3 協議、 IMAP 協議和 SMTP協議的支援
    5. 第三方模組
      是為了擴充套件 Nginx 伺服器應用,完成開發者自定義功能,比如: Json 支援、 Lua 支援等

5. nginx的安裝

  • 編譯安裝

    1. 獲取原始碼包,解壓
      [[email protected] sbin]$wget http://nginx.org/download/nginx-1.14.1.tar.gz
      [[email protected] sbin]$tar xvf nginx-1.14.1.tar.gz
      
    2. 安裝編譯工具
      [[email protected] sbin]$yum groupinstall "development tools"
      
    3. 安裝依賴包
      [[email protected] sbin]$yum install pcre-devel openssl-devel zlib-devel
      
    4. 編譯安裝不會自動建立系統賬號,需要手動建立
      [[email protected] sbin]$useradd -r -s /sbin/nologin nginx
      
    5. 修改原始碼檔案,隱藏必要資訊
      1. '進入解壓目錄'
      [[email protected] ~]$cd nginx-1.14.1/
      2. '編輯如下檔案,找到所示行'
      [[email protected] nginx-1.14.1]$vim src/core/nginx.h
      版本資訊
      #define NGINX_VERSION      "9.8.6"   
      服務名稱               
      #define NGINX_VER          "moli/" NGINX_VERSION
      3. '修改禁用服務資訊後,頭部資訊'
      [[email protected] nginx-1.14.1]$vim src/http/ngx_http_header_filter_module.c 
      配置檔案中修改禁止顯示版本資訊後,頭部顯示的Server內容
      static u_char ngx_http_server_string[] = "Server: moli" CRLF;
      
    6. 編譯以及安裝,配置檔案、程式檔案,日誌如果不指定會放在安裝路徑中,方便刪除
      [[email protected] nginx-1.14.1]$/configure --prefix=/usr/local/nginx / <==安裝路徑
      --conf-path=/etc/nginx/nginx.conf / 			<==主配置檔案安裝位置
      --sbin-path=/usr/sbin/nginx   					<==指明nginx程式檔案安裝路徑
      --error-log-path=/var/log/nginx/error.log /     <==錯誤日誌檔案安裝位置
      --http-log-path=/var/log/nginx/access.log /     <==訪問日誌檔案安裝位置
      --pid-path=/var/run/nginx.pid /     			<==指明pid檔案安裝位置
      --lock-path=/var/run/nginx.lock /     			<==鎖檔案安裝位置
      --http-client-body-temp-path=/var/cache/nginx/client_temp     <==客戶端body部分的臨時檔案存放路徑,伺服器允許客戶端使用put方法提交大資料時,臨時存放的磁碟路徑
      --http-proxy-temp-path=/var/cache/nginx/proxy_temp     		  <==作為代理伺服器,伺服器響應報文的臨時檔案存放路徑
      --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp     	  <==作為fastcgi代理伺服器,伺服器響應報文的臨時檔案存放路徑
      --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp     		  <==作為uwsgi代理伺服器,伺服器響應報文的臨時檔案存放路徑
      --http-scgi-temp-path=/var/cache/nginx/scgi_temp     		  <==作為scgi反代伺服器,伺服器響應報文的臨時檔案存放路徑
      --user=nginx /     			<==指明以那個身份執行worker程序,主控master程序一般由root執行
      --group=nginx /     		<==指明組執行身份
      --with-http_ssl_module /    <==加密相關模組
      --with-http_v2_module /     <==是否支援http2.0版本
      --with-http_dav_module /    <==是否支援dav
      --with-http_stub_status_module /    
      --with-threads /     	    <==是否啟用執行緒
      --with-file-aio     		<==是否啟用非同步IO
      [[email protected] nginx-1.14.1]$make && make install
      
  • rpm包安裝

    1. epel源安裝,使用yum安裝解決依賴問題,會自動建立系統賬號nginx
      [[email protected] ~]$yum -y install nginx
      
    2. 檢視建立的系統賬號
      [[email protected] ~]$getent passwd
      nginx:x:988:982:Nginx web server:/var/lib/nginx:/sbin/nologin
      
    3. 參看是否安裝時運行了指令碼
      [[email protected] ~]$ rpm -q --scripts nginx
      
    4. 啟動nginx
      1. 'nginx可以直接輸入服務名來啟動,以此方式啟動,不受systemctl控制,不能以systemctl關閉,需要以選項-s控制載入或關閉等'
      [[email protected] ~]$nginx
      [[email protected] ~]$nginx  -s  stop 
      2. '傳統方式啟動'
      [[email protected] ~]$systemctl start nginx
      
  • 檔案說明

    1. 多用途郵件擴充套件
      /etc/nginx/mime.types
    2. SCGI支援配置檔案
      /etc/nginx/scgi_params
    3. py支援配置檔案
      /etc/nginx/uwsgi_params
    4. fastcgi支援配置檔案
      /etc/nginx/fastcgi.conf
    5. 服務檔案
      /usr/lib/systemd/system/nginx.service
    6. 主程式
      /usr/sbin/nginx
    7. 服務頁面檔案
      /usr/share/nginx/html/index.html
  • nginx命令說明

    1. 語法格式
      nginx [-?hvVtTq] [-s signal] [-c filename] [-p prefix] [-g directives]
      
      預設不加任何選項為啟動nginx
    2. 選項說明
      1. -h:檢視幫助選項
      2. -v:只顯示版本資訊
      3. -V:檢視版本和編譯選項
      4. -t測試nginx語法錯誤
      5. -T:檢測並顯示配置檔案資訊
      6. -q:在檢測語法時,壓縮掉非錯誤資訊
      7. -c filename:指定配置檔案(default: /etc/nginx/nginx.conf)
      8. -s signal :傳送訊號給master程序,signal:stop, quit, reopen, reload
        示例: nginx -s stop 停止nginx(systemctl stop nginx)
        nginx -s reload 載入配置檔案
      9. -g directives :在命令列中指明全域性指令

6. nginx配置

  • 配置檔案
    1. 主配置檔案:
      /etc/nginx/nginx.conf
    2. 子配置檔案
      include conf.d/*.conf
    3. 主配置檔案的配置指令格式
      directive value [value2 …];
    4. 注意
      1. 指令必須以分號結尾
      2. 支援使用配置變數
        1. 內建變數:由Nginx模組引入,可直接引用
        2. 自定義變數:由使用者使用set命令定義
          set variable_name value;
        3. 引用變數:$variable_name
  • 主配置檔案結構:分為4個語句塊
    include /usr/share/nginx/modules/*.conf;  <==此目錄下的配置內容,可以生效
    1. '主語句塊'
    main block:        <==主配置段,即全域性配置段,對http,mail都有效
    			event {
    							...
    				}   <==事件驅動相關的配置
    2. 'http語句塊'
    http {
    			...
    	} http/https 協議相關配置段
    	include /etc/nginx/conf.d/*.conf;  <==關於http的配置檔案,放在此目錄也可以生效
    3. '郵件語句塊'
    mail {
    			...
    	} mail 協議相關配置段,預設沒有
    4. 'stream語句塊'
    stream {
    			...
    	} stream 伺服器相關配置段,預設沒有
    
  • http協議相關的配置結構
    http {
    	...
    	... 各server的公共配置
    	server { 每個server用於定義一個虛擬主機
    			...
    			}
    	server {
    			...
    			server_name 虛擬主機名
    			root 主目錄
    			alias 路徑別名
    			location [OPERATOR] URL { 指定URL的特性
    					  ...
    					  if CONDITION {
    					  ...
    					  }
    			}
    	}
    }
    

6.1 Main 全域性配置段常見的配置指令分類

正常執行必備的配置:例如nginx以什麼身份執行
優化效能相關的配置:例如併發連線數設定
用於除錯及定位問題相關的配置:日誌檔案
事件驅動相關的配置:例如設定I/O模型
幫助文件
http://nginx.org/en/docs/

  1. 正常執行必備的配置,必須放在主語句塊中
    1. user username [group];
      指定worker程序的執行身份,如組不指定,預設和使用者名稱同名,修改的使用者要保證有訪問頁面檔案的許可權,如果不指定使用者,預設為nobody
      user nginx;
      
    2. pid /PATH/TO/PID_FILE;
      指定儲存nginx主程序PID的檔案路徑, PID檔案隨服務停止刪除
      pid /run/nginx.pid;
      
    3. include file | mask;
      指明包含進來的其它配置檔案片斷
      include mime.types;
      include vhosts/*.conf;
      
    4. load_module file ;
      載入動態模組
      模組載入配置檔案: /usr/share/nginx/modules/*.conf
      指明要裝載的動態模組路徑: /usr/lib64/nginx/modules
      load_module modules/ngx_mail_module.so;
      
  2. 效能優化相關的配置
    1. worker_processes number | auto;
      worker程序的數量;通常應該為當前主機的cpu的物理核心數,auto表示自動匹配cpu核心數
      支援環境: main

      worker_processes auto;
      
    2. worker_cpu_affinity auto [cpumask] ;
      cpu親源性設定,繫結cpu有利於使用cpu快取
      [cpumask] : 00000001(0號CPU)
      支援環境: main

      1. '8個cpu,分別繫結寫法如下'
      [[email protected]ai7-1 ~]$vim /etc/nginx/nginx.conf
      worker_cpu_affinity 0001 0010 0100 1000 10000 100000 1000000 10000000;
      2. '檢視繫結效果'
      [[email protected] ~]$watch -n1 'ps  axo pid,cmd,psr |grep nginx'
      3. '利用其它主機測試'
      [[email protected] ~]$ab -c 100 -n 2000 http://192.168.50.101
      
    3. worker_priority number;
      指定worker程序的nice值,設定worker程序優先順序:[-20,19]
      支援環境: main

      1. '將nice值設定為-10'
      [[email protected] ~]$vim /etc/nginx/nginx.conf
      worker_priority -10;
      2. '查詢優先順序ni引數'
      [[email protected] ~]$watch -n1 'ps  axo pid,cmd,psr,ni |grep nginx'
      21518  nginx: worker process     0   -10
      
    4. worker_rlimit_nofile number;
      worker程序所能夠開啟的檔案數量上限,如65535
      支援環境: main

      [[email protected] ~]$vim /etc/nginx/nginx.conf
      worker_rlimit_nofile number 51200;
      
  3. 事件驅動相關的配置,在events語句塊中可以設定很多效能相關設定
    1. worker_connections number;
      每個worker程序所能夠開啟的最大併發連線數數量(預設值為512),太小發揮不了伺服器效能,影響併發,太大超出伺服器效能,超出極限後會宕機
      總最大併發數:worker_processes * worker_connections
      支援環境:events
      [[email protected] ~]$vim /etc/nginx/nginx.conf
      events {
          worker_connections 1024;
      }
      
    2. use method;
      指明併發連線請求的處理方法 ,預設自動選擇最優方法
      支援環境:events
      use epoll;
      
    3. accept_mutex on | off;
      處理新的連線請求的方法;on指由各個worker輪流處理新請求,Off指每個新請求的到達都會通知(喚醒)所有的worker程序,但只有一個程序可獲得連線,造成“驚群”,影響效能
  4. 除錯和定位問題
    1. daemon on|off;
      是否以守護程序方式執行nignx,預設是守護程序方式,修改後啟動nignx會在前臺執行
      支援環境: main
    2. master_process on|off;
      是否以master/worker模型執行nginx;預設為on,off 將不啟動worker
      支援環境: main
      1. '預設狀態下開啟程序狀態'
      [[email protected] ~]$pstree -p |grep nginx
                 |-nginx(18721)-+-nginx(21518   <==18721為master程序
      2. '設定為off'
      [[email protected] conf.d]$vim /etc/nginx/nginx.conf
      master_process off
      3. '修改後開啟程序狀態'
      [[email protected] ~]$pstree -p |grep nginx
                 |-nginx(27054)                 <==只有一層master,沒有workter
      
    3. error_log file [level] ;
      錯誤日誌檔案及其級別;出於除錯需要,可設定為debug;但debug僅在編譯時使用了--with-debug選項時才有效
      支援環境: main, http, mail, stream, server, location
      1. file定義儲存日誌路徑
        /path/logfile: 記錄到檔案中
        stderr:傳送到標準錯誤
        syslog:server-address[,parameter=values] 傳送到syslog
        memory:size:存到迴圈儲存器中,可以通過size指定大小
      2. level日誌級別
        debug|info|notice|warn|error|crit|alter|emerg

6.2 http協議的相關配置

6.2.1 ngx_http_core_module模組

  • 與套接字相關的配置
    1. server { … }
      設定虛擬伺服器的配置
      Context: http
      1. '設定虛擬機器web頁面'
      [[email protected] data]$mkdir websiter{1,2}
      [[email protected] data]$echo /data/website2/index.html > websiter2/index.html
      [[email protected] data]$echo /data/websiter/index.html > websiter1/index.html
      2. '配置一個虛擬主機,在http塊的子配置檔案中設定,格式如下,不需要加http{,服務會自動匹配'
      [[email protected] ~]$vim /etc/nginx/conf.d/vhosts.conf
      server {
              listen 80;
              server_name www.a.com www.b.com;
              root /data/websiter1;
      }
      server {
              listen 80  default_server;    <==將主配置檔案中預設頁面刪掉,在自定義虛擬機器加上default_server,就會成為新的預設頁,沒有指定預設頁將以配置檔案順序顯示
              server_name www.c.com ;
              root /data/websiter2;
      }
      3. '在另外一臺主機上測試'
      '修改hosts檔案,模擬DNS解析,DNS解析過程會帶主機頭,雖然最後都解析為同一個IP地址,但會根據主機頭判斷需要返回的頁面結果'
      [[email protected] ~]$vim /etc/hosts
      192.168.50.101 www.a.com  www.b.com www.c.com
      '測試'
      [[email protected] ~]$curl www.a.com
      /data/websiter/index.html
      [[email protected] ~]$curl www.c.com
      /data/websiter2/index.html
      
    2. listen PORT|address[:port]|unix:/PATH/TO/SOCKET_FILE
      虛擬機器監聽埠,可以直接寫埠,也可以指定伺服器IP:埠,還可以監聽本地套接字
      支援環境: server
      1. 語法
        listen address[:port] [default_server] [ssl] [http2 | spdy] [backlog=number] [rcvbuf=size] [sndbuf=size];
      2. 引數
        default_server:設定為預設虛擬主機
        ssl:限制僅能夠通過ssl連線提供服務
        backlog=number:超過併發連線數後,新請求進入後援佇列的長度
        rcvbuf=size: 接收緩衝區大小
        sndbuf=size: 傳送緩衝區大小
    3. server_name name …;
      虛擬主機的主機名稱後可跟多個由空白字元分隔的字串
      支援環境:server
      1. 語法
        支援*通配任意長度的任意字元
        server_name  *.c.com   www.c.* ;
        
        支援~起始的字元做正則表示式模式匹配,效能原因慎用
        server_name ~^b.*\.a\.com$;
        
      2. 匹配優先順序機制從高到低
        1. 左側*萬用字元 如:*.a.com
        2. 右側*萬用字元 如:www.a.*
        3. 正則表示式 如: ~^.*\.magedu\.com$
        4. default_server
    4. tcp_nodelay on | off;
      在keepalived模式下的連線是否啟用同步寫入,當為off時,延遲傳送,合併多個請求後再發送,預設On時,不延遲傳送
      支援環境:http, server, location
    5. sendfile on | off;
      是否啟用sendfile功能,在核心中封裝報文直接傳送,預設Off(迴應報文時不需要送到使用者空間來封裝,減少I/O次數,提高效能)
    6. server_tokens on | off | build | string
      build|string商業版支援,可以修改nginx資訊,或者社群版原始碼編譯自定義
      是否在響應報文的Server首部顯示nginx版本
      支援環境:http、server、location
  • 定義路徑相關的配置
    1. root
      設定web資源的路徑對映;用於指明請求的URL所對應的文件的目錄路徑
      支援環境:http, server, location, if in location
      1. '指定虛擬機器web頁面路徑'
      [[email protected] ~]$vim /etc/nginx/conf.d/vhosts.conf
      server {
      ...
      root /data/website1;
      }
      2. '在目錄下建立一個新的目錄,並建立web頁面,測試如下'
      [[email protected] ~]$mkdir /data/website1/news
      [[email protected] ~]$echo news > /data/website1/news/index.html
      [[email protected] ~]$curl www.a.com/news/
      news
      3. '在目錄下建立一個軟連線'
      [[email protected] websiter1]$ln -s /nginx/test  bbs
      4. '在另一臺主機上測試,可以返回結果,支援軟連線'
      [[email protected] ~]$curl www.a.com/bbs/
      
    2. location [ = | ~ | ~* | ^~ ] uri { ... }
      在一個server中location配置段可存在多個,用於實現從uri到檔案系統的路徑對映;ngnix會根據使用者請求的URI來檢查定義的所有location,並找出一個最佳匹配,而後應用其配置
      支援環境:server, location
      1. 示例
        1. '定義配置檔案'
        server {
        		server_name www.a.com;
        		location /news {   <==定義Uri為news
        					root /data2/newsdir;   <==定義Uri的根目錄
        		}  
        }
        2. '建立測試頁'
        [[email protected] ~]$mkdir -pv /data2/newsdir/news
        [[email protected] ~]$echo testnews > /data2/newsdir/news/index.html
        3. '測試,訪問news,實際訪問地址為/data2/newsdir/news,也就是說可以單獨定義每個url的根目錄'
        [[email protected] ~]$curl www.a.com/news/
        testnews
        
      2. uri前符號說明
        1. =對URI做精確匹配;
          server {
          		server_name www.a.com;
          		location = /news {     <==使用等號定義Uri為news
          					root /data2/newsdir;   <==定義Uri的根目錄
          		}  
          }
          測試訪問news目錄下2018目錄,會報錯,精確匹配不會顯示uri下的目錄,只能
          [[email protected] ~]$curl www.a.com/news/2018
          
        2. ^~對URI的最左邊部分做匹配檢查,不區分字元大小寫
        3. ~對URI做正則表示式模式匹配,區分字元大小寫
        4. ~*對URI做正則表示式模式匹配,不區分字元大小寫
          location ~* \.(gif|jpg|jpeg)$ {   <==以gif|jpg|jpeg結尾的資源
          		root /data2/newsdir ;
          
        5. 不帶符號 匹配起始於此uri的所有的uri
      3. 匹配優先順序從高到低:
        =、 ^~、 ~、~*、不帶符號
    3. alias path;
      路徑別名,文件對映的另一種機制;僅能用於location上下文
      1. 示例:/bbs 後建議不要加 /,如果加/,那麼alias後的路徑也要以/結尾
        設定示例,訪問www.a.com/bbs相當於檢視www.a.com/web/forum/
        location /bbs {
        		alias /web/forum/;
        } 			
        
      2. 注意:location中使用root指令和alias指令的意義不同
        1. root:給定的路徑對應於location中的/uri 左側的/
        2. alias:給定的路徑對應於location中的/uri 的完整路徑
    4. index file ...;
      指定預設網頁檔案,此指令由ngx_http_index_module模組提供
      支援環境:server, location
    5. error_page code ... [=[response]] uri;
      定義錯誤頁,以指定的響應狀態碼進行響應,此指令由ngx_http_index_module模組提供
      支援環境:http, server, location, if in location
      1. '定義配置'
      [[email protected] conf.d]$vim /etc/nginx/conf.d/vhosts.conf
      server {
              listen 80;
              server_name www.a.com ;
              root /data/websiter1;
              error_page 404 =302 /error_404.html;    <==定義返回的錯誤頁面,修改錯誤碼為200
      2. '建立錯誤頁面內容'
      [[email protected] ~]$echo 404 error > /data/websiter1/error_404.html
      3. '測試'
      [[email protected] ~]$curl -i http://www.a.com/xxx.html
      HTTP/1.1 302 OK     <==返回的錯誤碼顯示為302
      404 error           <==錯誤頁面
      
    6. try_files file ... uri;
      按順序檢查檔案是否存在,返回第一個找到的檔案或資料夾(結尾加斜線表示為資料夾),如果所有檔案或資料夾都找不到,會進行一個內部重定向到最後一個引數。只有最後一個引數可以引起一個內部重定向,之前的引數只設置內部URI的指向。最後一個引數是回退URI且必須存在,否則會出現內部500錯誤
      支援環境:server, location
      訪問/images時,搜尋$uri路徑,如果不存在則回退/images/fish.jpg,回退URI必須為uri路徑
      [[email protected] ~]$vim /etc/nginx/conf.d/vhosts.conf
       server {       
              server_name www.a.com www.b.com;
              root /data/websiter1;        
              location /images {      
                      try_files $uri  /images/fish.jpg ;
              }
      }        
      
  • 定義客戶端請求的相關配置
    1. keepalive_timeout ;
      定義客戶端保持連線超時時長,0表示禁止長連線,預設為75s
      在ngx_http_upstream_module中也有此項設定是定義反向代理的轉發給後端伺服器時的超時
      支援環境:http,server,location
      keepalive_timeout 0;
      
    2. keepalive_requests number;
      在一次長連線上所允許請求的資源的最大數量,預設為100
      支援環境:http, server, location
    3. keepalive_disable none | browser ...;
      對哪種瀏覽器禁用長連線
      支援環境:http, server, location
    4. send_timeout time;
      向客戶端傳送響應報文的超時時長,此處是指兩次寫操作之間的間隔時長,而非整個響應過程的傳輸時長
      支援環境:http, server, location
    5. client_body_buffer_size size;
      用於接收每個客戶端請求報文的body部分的緩衝區大小;預設為16k;超出此大小時,其將被暫存到磁碟上的由下面client_body_temp_path指令所定義的位置
      支援環境:http, server, location
    6. client_body_temp_path path [level1 [level2 [level3]]];
      設定儲存客戶端請求報文的body部分的臨時儲存路徑及子目錄結構和數量
      支援環境:http, server, location
      1. '配置檔案設定格式,表示設定三級目錄, 1 2 2表示三級目錄每級所佔位數'
      client_body_temp_path   /var/tmp/client_body  1 2 2
      2. '假設快取資料為index.html,其雜湊結果如下所示'
      [[email protected] websiter1]$md5sum  index.html 
      0d6a914877e53e2957172f5e46bb5755  index.html
      3. '存放目錄為3級目錄,共有16*256*256=1048576個目錄'
      一級目錄取最後一位
      5(一級目錄佔一個16位數,範圍在0-f)
      二級目錄取倒數2-3位
      75(二級目錄佔兩個16位數,範圍在00-ff)
      三級目錄取倒數4-5位
      b5(三級目錄佔兩個16位數,範圍在00-ff)
      
    7. limit_rate rate;
      限制響應給客戶端的傳輸速率,單位是bytes/second,預設值0表示無限制
      支援環境:http, server, location, if in location
      limit_rate 10240
      
    8. limit_except method ... { ... },僅用於location
      限制客戶端使用除了指定的請求方法之外的其它方法
      支援環境:location
      1. method描述
        GET, HEAD, POST, PUT, DELETE,MKCOL, COPY, MOVE, OPTIONS, PROPFIND, PROPPATCH, LOCK, UNLOCK, PATCH
      2. 示例:除了GET 之外其它方法僅允許192.168.1.0/24網段主機使用
        location / {
        	limit_except GET {
        	allow 192.168.1.0/24;
        	deny all;
        	}
        }
        
  • 檔案操作優化的配置
    1. aio on | off | threads[=pool];
      是否啟用非同步檔案I/O功能
      支援環境:http, server, location
    2. directio size | off;
      當檔案大於等於給定大小時,例如directio 4m,同步(直接)寫磁碟,而非寫快取
      支援環境:http, server, location
    3. open_file_cache off; open_file_cache max=N [inactive=time];
      是否開啟快取功能
      支援環境:http, server, location
      1. nginx可以快取以下三種資訊:
        1. 檔案元資料:檔案的描述符、檔案大小和最近一次的修改時間
        2. 開啟的目錄結構
        3. 沒有找到的或者沒有許可權訪問的檔案的相關資訊
      2. 引數描述
        1. max=N
          可快取的快取項上限;達到上限後會使用LRU演算法實現管理
        2. inactive=time
          快取項的非活動時長,在此處指定的時長內未被命中的或命中的次數少於open_file_cache_min_uses指令所指定的次數的快取項即為非活動項,將被刪除
        3. off:表示禁用
      3. 示例
        open_file_cache          max=1000 inactive=20s;
        open_file_cache_valid    30s;
        open_file_cache_min_uses 2;
        open_file_cache_errors   on;
        
    4. open_file_cache_errors on | off;
      是否快取查詢時發生錯誤的檔案一類的資訊,預設值為off
      支援環境:http, server, location
    5. open_file_cache_min_uses number;
      open_file_cache指令的inactive引數指定的時長內,至少被命中此處指定的次數方可被歸類為活動項,預設值為1
      支援環境:http, server, location
    6. open_file_cache_valid time;
      快取項有效性的檢查頻率,預設值為60s
      支援環境:http, server, location

6.2.2 ngx_http_access_module模組

可實現基於ip的訪問控制功能

  • allow address | CIDR | unix: | all;
    允許訪問指定的網路或地址,如果指定unix:,表示執行UNIX-domain所有套接字
    支援環境:http, server, location, limit_except
  • deny address | CIDR | unix: | all;
    允許訪問指定的網路或地址
    支援環境:http, server, location, limit_except
  • 示例:自上而下檢查,一旦匹配,將生效,所以條件嚴格的置前
    location / {
    deny 192.168.1.1;
    allow 192.168.1.0/24;
    allow 10.1.1.0/16;
    allow 2001:0db8::/32;
    deny all;
    }
    

6.2.3 ngx_http_auth_basic_module模組

實現基於使用者的訪問控制,使用basic機制進行使用者認證

  • auth_basic string | off;
    啟用使用“HTTP基本身份驗證”協議驗證使用者名稱和密碼,預設為off
    支援環境:http, server, location, limit_except
  • auth_basic_user_file file;
    指定以下列格式儲存使用者名稱和密碼的檔案進行驗證
    支援環境:http, server, location, limit_except
  • 使用者口令檔案格式:
    1. 明文文字:格式name:password:comment
      # comment
      name1:password1
      name2:password2:comment
      name3:password3
      
    2. 加密文字:由htpasswd命令實現,命令由httpd-tools所提供
      1. '工具來源'
      [[email protected] websiter1]$rpm -qf /usr/bin/htpasswd 
      httpd-tools-2.4.6-80.el7.centos.x86_64
      2. '生成第一個使用者口令檔案,需要加-c選項'
      [[email protected] websiter1]$htpasswd -cm  /etc/nginx/conf.d/.httpuser  user1
      3. '檢視生成的使用者口令'
      [[email protected] websiter1]$cat /etc/nginx/conf.d/.httpuser 
      user1:$apr1$DwtBgJYJ$KW3UEzDSOtsC5jnHji6Yb.
      4. '生成第二個使用者口令,不能加-c,會覆蓋前面的使用者資訊'
      [[email protected] websiter1]$htpasswd -m  /etc/nginx/conf.d/.htt