Nginx伺服器 | Nginx設定服務實戰

2021-03-29 21:03:05

6vCJ3Q.jpg

When you realize you want to spend the rest of your life with somebody,you want the rest of your life to start as soon as possible.<br/>
當你意識到想和某人共度餘生時,便會恨不得下半場人生馬上開始。——《當哈利遇到莎莉》1989
基本概述

6vPGa6.jpg
或許當提前80埠和443埠的時候,我們就能想起對應的Http存取[基於HTTP協定]和Https存取[基於HTTP協定+SSL證書]。記憶中比較深刻的,就是開發微信小程式時,對應域名設定述求,必須是備案認證通過的Https的服務。因此,在設定之前,我們需要了解Nginx包含著那些模組以及設定規則,工作原理才能更好地使用Nginx以及認識Nginx。
Nginx由核心和模組組成,其中,核心的設計非常微小和簡潔,完成的工作也非常簡單,僅僅通過查詢組態檔將使用者端請求對映到一個location block(location是Nginx設定中的一個指令,用於URL匹配),而在這個location中所設定的每個指令將會啟動不同的模組去完成相應的工作。
Nginx的模組從結構上分為核心模組、基礎模組和第三方模組, HTTP模組、EVENT模組和MAIL模組等屬於核心模組,HTTP Access模組、HTTP FastCGI模組、HTTP Proxy模組和HTTP Rewrite模組屬於基本模組,而HTTP Upstream Request Hash模組、Notice模組和HTTP Access Key模組屬於第三方模組,使用者根據自己的需要開發的模組都屬於第三方模組。正是有了這麼多模組的支撐,Nginx的功能才會如此強大。
Nginx由核心和模組組成,其中,核心的設計非常微小和簡潔,完成的工作也非常簡單,僅僅通過查詢組態檔將使用者端請求對映到一個location block(location是Nginx設定中的一個指令,用於URL匹配),而在這個location中所設定的每個指令將會啟動不同的模組去完成相應的工作。
6v89RH.png

Nginx結構分析

以nginx-1.19.8版本為例:
6vmOS0.png

Nginx的原始碼主要分佈在src/目錄下,而src/目錄下主要包含三部分比較重要的模組:
6v8nJg.png

  • core:基礎核心庫和框架

6vMRAg.png
Nginx的核心原始碼,包括常用資料結構的以及Nginx 核心實現的核心程式碼。

  • event:事件驅動模型

6vQmvt.png
Nginx事件驅動模型,以及定時器的實現相關程式碼。

  • http:HTTP的模組

6vQdbT.png
Nginx 實現http 伺服器相關的程式碼。

  • mail:郵件服務模組

6vlref.png
Nginx 實現郵件代理伺服器相關的程式碼。

  • misc:整合模組

6vlowT.png
輔助程式碼,測試C++頭 的相容性,以及對Google_PerfTools 的支援。

  • os:系統模組

6vlXlR.png
不同體系統結構所提供的系統函數的封裝,提供對外統一的系統呼叫介面。

  • stream:流處理模組

6v1CkD.png
Nginx(tcp/udp)反向代理及與上游通訊的基礎模組。

Nginx 事件驅動模型

cCKxtf.png
Nginx提供支援的模型主要有Select庫,Eventport庫,Poll庫,Epoll庫,Kqueue庫,Devpoll庫以及Eventport庫等。

  • Select庫:在linux和windows平臺都基本支援的 事件驅動模型庫,並且在介面的定義也基本相同,只是部分引數的含義略有差異,最大並行限制1024,只最早期的事件驅動模型。
  • Poll庫: 在Linux 的基本驅動模型,windows不支援此驅動模型,是select的升級版,取消了最大的並行限制,在編譯nginx的時候可以使用--with-poll_module和--without-poll_module這兩個指定是否編譯select庫。
  • Epoll庫:Nginx伺服器支援的最高效能的事件驅動庫之一,是公認的非常優秀的事件驅動模型,它和select和poll有很大的區別,epoll是poll的升級版,但是與poll的效率有很大的區別.epoll的處理方式是建立一個待處理的事件列表,然後把這個列表發給核心,返回的時候在去輪訓檢查這個表,以判斷事件是否發生,epoll支援一個程序開啟的最大事件描述符的上限是系統可以開啟的檔案的最大數,同時epoll庫的IO效率不隨描述符數目增加而線性下降,因為它只會對核心上報的「活躍」的描述符進行操作。
  • Kqueue庫:用於支援BSD系列平臺的高校事件驅動模型,主要用在FreeBSD 4.1及以上版本、OpenBSD 2.0級以上版本,NetBSD級以上版本及Mac OS X 平臺上,該模型也是poll庫的變種,因此和epoll沒有本質上的區別,都是通過避免輪訓操作提供效率。
  • Devpoll庫:用於支援unix衍生平臺的高效事件驅動模型,主要在Solaris 平臺、HP/UX,該模型是sun公司在開發Solaris系列平臺的時候提出的用於完成事件驅動機制的方案,它使用了虛擬的/dev/poll裝置,開發人員將要見識的檔案描述符加入這個裝置,然後通過ioctl()呼叫來獲取事件通知,因此執行在以上系列平臺的時候請使用/dev/poll事件驅動機制。
  • Eventport庫:是sun公司在開發Solaris的時候提出的事件驅動庫,只是Solaris 10以上的版本,該驅動庫看防止核心崩潰等情況的發生。
Nginx工作原理

Nginx的模組從功能上分為三類,分別是:

  • Handlers(處理器模組): 直接處理請求,並進行輸出內容和修改headers資訊等操作。handlers處理器模組一般只能有一個。
  • Filters ->過濾器模組: 主要對其他處理器模組輸出的內容進行修改操作,最後由Nginx輸出。
  • Proxies->代理類模組: Nginx的HTTP Upstream之類的模組,這些模組主要與後端一些服務比如fastcgi等操作互動,實現服務代理和負載均衡等功能。

在Nginx的模組下,一次常規的HTTP請求和響應的過程:
cCvbkt.png
在工作方式上,Nginx分為單工作程序和多工作程序兩種模式:

  • 在單工作程序模式下,除主程序外,還有一個工作程序,工作程序是單執行緒的
  • 在多工作程序模式下,每個工作程序包含多個執行緒

Nginx預設為單工作程序模式。Nginx的模組直接被編譯進Nginx,因此屬於靜態編譯方式。啟動Nginx後,Nginx的模組被自動載入,不像在Apache一樣,首先將模組編譯為一個so檔案,然後在組態檔中指定是否進行載入。在解析組態檔時,Nginx的每個模組都有可能去處理某個請求,但是同一個處理請求只能由一個模組來完成

Nginx的Http模組

cC1TUI.png
cC3mZ9.png
Nginx常用的模組:

  • ngx_http_access_module模組:只有allow[允許存取]和deny[拒絕存取]2個值,一般用於設定和控制IP的請求,類似於網路黑名單的功能。
location / {
     root   html;
     index  index.html index.htm;
     allow 127.0.0.1;  ##允許127.0.0.1存取
     deny 127.0.0.1;    ##拒絕127.0.0.1存取
}
  • ngx_http_auth_basic_module模組:實現基於使用者的存取控制,使用basic機制進行使用者認證
location / {
     root   html;
     index  index.html index.htm;
     auth_basic  "Admin"; ##認證對話方塊的提示字串顯示的內容
     auth_basic_user_file /etc/nginx/conf/htpasswd; ##存放認證用的使用者名稱和檔案,需要用htpasswd命令生成
}

對於htpasswd的應用需要安裝httpd-tools:

yum install httpd-tools

使用命令生成:htpasswd -c /etc/nginx/conf/htpasswd nginx

[root@cotos-pivotal nginx]# htpasswd  -c /etc/nginx/conf/htpasswd nginx
New password: 
Re-type new password: 
Adding password for user nginx
  • ngx_http_stub_status_module模組:用來檢視http的狀態資訊的,使用方式直接在location裡面加stub_status
location / {
     root   html;
     index  index.html index.htm;
     auth_basic  "Admin"; ##認證對話方塊的提示字串顯示的內容
     auth_basic_user_file /etc/nginx/conf/htpasswd; ##存放認證用的使用者名稱和檔案,需要用htpasswd命令生成
         stub_status;
}

狀態引數解析:

  • Active connections: 活動狀態的連線數;
  • accepts:已經接受的使用者端請求的總數;
  • handled:已經處理完成的使用者端請求的總數;
  • requests:使用者端發來的總的請求數;
  • Reading:處於讀取使用者端請求報文首部的連線的連線數;
  • Writing:處於向用戶端傳送響應報文過程中的連線數;
  • Waiting:處於等待使用者端發出請求的空閒連線數;
  • ngx_http_log_module模組:紀錄檔模組
  • ngx_http_gzip_module模組:壓縮模組,有利於傳輸資料的大小減少,但是cpu使用會變高。因為要對傳輸的資料進行壓縮
gzip  on;
gzip_comp_level 6;
gzip_min_length 64;
gzip_proxied any;
gzip_types text/xml text/css  application/javascript;   
  • ngx_http_ssl_module模組: 設定https連線的模組
    server {
        listen       443 ssl;
        server_name  www.ice.com;
        root /var/www/html;
        ssl on; 
        ssl_certificate /usr/local/nginx/ssl/ssl.crt;
        ssl_certificate_key /usr/local/nginx/ssl/ssl.key;
        ssl_session_cache shared:sslcache:20m;
        location / {
            index  index.html index.htm;
        }
    }
  • ngx_http_rewrite_module模組:重寫指令
rewrite regex replacement [flag]:將使用者請求的URI基於regex所描述的模式進行檢查,匹配到時將其替換為replacement指定的新的URI;
在同一級設定塊中存在多個rewrite規則,那麼會自下而下逐個檢查;被某條件規則替換完成後,會重新一輪的替換檢查,因此,隱含有迴圈機制;[flag]所表示的標誌位用於控制此迴圈機制;
其中:
  • last:如果規則有很多條。這裡重寫完成一次之後就會重新開始匹配規則,直至最後一條。也就是說。如果規則寫的不好很容易造成死迴圈,不停的重寫規則。
  • break:重寫完成之後不再從頭再次匹配規則。直接跳出迴圈
  • redirect:重寫完成後以臨時重定向方式直接返回重寫後生成的新URI給使用者端,由使用者端重新發起請求;不能以http://或https://開頭
  • permanent:重寫完成後以永久重定向方式直接返回重寫後生成的新URI給使用者端,由使用者端重新發起請求;
  • ngx_http_referer_module模組:防盜鏈

定義referer首部的合法可用值:

  • none:請求報文首部沒有referer首部
  • blocked:請求報文的referer首部沒有值
  • server_names:引數,其可以有值作為主機名或主機名模式
  • arbitrary_string:直接字串,但可使用*作萬用字元
  • regular expression:被指定的正規表示式模式匹配到的字串;要使用~打頭
valid_referers none block server_names *.pivotal.com ; 
if($invalid_referer) {return 403;  }
  • ngx_http_headers_module模組 :向由代理伺服器響應給使用者端的響應報文新增自定義設定部

完整的 Nginx組態檔:

#Setting Nginx User Group
user  root;
#Setting Nginx Processes
worker_processes  1;
#Setting Nginx Max Nofile
worker_rlimit_nofile 51200;
#Setting Nginx Events
events {
    worker_connections  51200;
}
#Setting Nginx Http
http {
    include       mime.types;
    default_type  application/octet-stream;
    #Setting Nginx FastCGI[避免504 502等]
    fastcgi_connect_timeout 600s;
    fastcgi_send_timeout 600s;
    fastcgi_read_timeout 600s;
    fastcgi_buffer_size 256k;
    fastcgi_buffers 16 256k;
    fastcgi_busy_buffers_size 512k;
    fastcgi_temp_file_write_size 512k;
    send_timeout 60000;
    client_header_buffer_size 64k;
    large_client_header_buffers 4 64k;
    sendfile        on;
    tcp_nopush     on;
    tcp_nodelay    on;
    #keepalive_timeout  0;
    keepalive_timeout  120;
      #檔案上傳最大限制50M 預設是1m
    client_max_body_size 100m;
    #gzip  on;
    #Setting  Nginx Gzip
    gzip on;
    gzip_min_length 1k;
    gzip_buffers 4 16k;
    gzip_http_version 1.0;
    gzip_comp_level 2;
    gzip_types text/plain application/x-javascript text/css application/xml;
    gzip_vary on;
      #Setting Nginx Reverse Proxy [反向代理設定 負載均衡]
      #後臺系統web層tomcat埠 monitor-8090
      upstream monitor.com{
    ip_hash;
    server localhost:8090 ;
    }
    #前臺介面web層tomcat埠proscenium-8091
    upstream proscenium.com{
    ip_hash;
    server localhost:8091;
    }
    #移動介面web層tomcat埠mobile-8092
    upstream mobile.com{
    ip_hash;
    server localhost:8092;
    }
    #後臺系統web層tomcat埠 schedule-8093
    upstream schedule.com{
      ip_hash;
      server localhost:8093;
    }
    server {
         listen       80;
         server_name  localhost;
         #處理websocket請求
         location /monitor {
         #請求轉向定義的伺服器列表
         proxy_pass  http://monitor.com/zhimeng;
         add_header Access-Control-Allow-Origin *;
         add_header Access-Control-Allow-Headers X-Requested-With;
         add_header Access-Control-Allow-Methods GET,POST,OPTIONS;
         proxy_set_header Host $host;
         proxy_set_header X-Real-IP $remote_addr;
         proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
         # 超時設定 預設300s
         proxy_read_timeout 300s;
         proxy_send_timeout 300s;
        }
        location /proscenium {
        #請求轉向定義的伺服器列表
        proxy_pass  http://proscenium.com;
        add_header Access-Control-Allow-Origin *;
        add_header Access-Control-Allow-Headers X-Requested-With;
        add_header Access-Control-Allow-Methods GET,POST,OPTIONS;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        # 超時設定 預設300s
        proxy_read_timeout 300s;
        proxy_send_timeout 300s;
       }
        location /mobile {
       #請求轉向定義的伺服器列表
       proxy_pass  http://mobile.com;
       add_header Access-Control-Allow-Origin *;
       add_header Access-Control-Allow-Headers X-Requested-With;
       add_header Access-Control-Allow-Methods GET,POST,OPTIONS;
       proxy_set_header Host $host;
       proxy_set_header X-Real-IP $remote_addr;
       proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
       # 超時設定 預設300s
       proxy_read_timeout 300s;
       proxy_send_timeout 300s;
        }
        location /schedule {
       #請求轉向定義的伺服器列表
       proxy_pass  http://schedule.com/;
       add_header Access-Control-Allow-Origin *;
       add_header Access-Control-Allow-Headers X-Requested-With;
       add_header Access-Control-Allow-Methods GET,POST,OPTIONS;
       proxy_set_header Host $host;
       proxy_set_header X-Real-IP $remote_addr;
       proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
       # 超時設定 預設300s
       proxy_read_timeout 300s;
       proxy_send_timeout 300s;
        }
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
        location /staticFile {
        alias /root/repository/staticFile;
        autoindex on;
        autoindex_exact_size on;
        autoindex_localtime on;
       }
    }
}
版權宣告:本文為博主原創文章,遵循相關版權協定,如若轉載或者分享請附上原文出處連結和連結來源。