理解Nginx


title: “理解Nginx”

url: “https://wsk1103.github.io/”

tags:

  • 架構
  • Nginx

1. Nginx 是什麼

Nginx官網說明
nginx [engine x] is an HTTP and reverse proxy server, a mail proxy server, and a generic TCP/UDP proxy server, originally written by Igor Sysoev.
nginx [engine x]是HTTP和反向代理服務器,郵件代理服務器和通用TCP / UDP代理服務器,最初由Igor Sysoev編寫。

2. 安裝

基於centOS7 安裝

直接一鍵安裝

yum -y install nginx

ps:可能出現的問題

沒有可用軟件包 nginx。
錯誤:無須任何處理

這個時候是因爲 nginxyum 裏面是沒有的,需要使用到 epel源 ,也就是安裝 epel-release

yum install epel-release

安裝成功後再安裝 nginx

3.啓動Nginx

[root@wsk1103 nginx]# systemctl start nginx

默認端口爲 80 ,打開瀏覽器,訪問 localhost,出現 NGINX 頁面表示啓動成功

關於 nginx 命令

systemctl enable nginx         開機啓動nginx服務
systemctl disable nginx         禁止開機啓動nginx服務
systemctl is-enable nginx      查詢是否開機啓動nginx服務
systemctl start nginx              啓動nginx服務
systemctl stop nginx              停止nginx服務
systemctl reload nginx            重新加載nginx服務
systemctl restart nginx            重啓nginx服務
systemctl status nginx             查看nginx服務狀態

或者 將 systemctl 替換成 service
service nginx start             啓動nginx服務
service nginx stop                停止nginx服務

4. 文件說明

安裝完成後,配置文件 nginx.conf 位於 /etc/nginx/nginx.conf

[root@wsk1103 yum.repos.d]# cd /etc/nginx/
[root@wsk1103 nginx]# ls
conf.d                  koi-utf             scgi_params
default.d               koi-win             scgi_params.default
fastcgi.conf            mime.types          uwsgi_params
fastcgi.conf.default    mime.types.default  uwsgi_params.default
fastcgi_params          nginx.conf          win-utf
fastcgi_params.default  nginx.conf.default
1. nginx.conf,nginx.conf.default

主要的配置文件

2. conf.d,default.d

空的文件夾

3. fastcgi.conf, fastcgi.conf.default,fastcgi_params,fastcgi_params.default

fastcgi例子
Nginx 配置Fastcgi解析時會調用fastcgi_params配置文件來傳遞服務器變量,這樣CGI中可以獲取到這些變量的值。
這允許我們使單個的FCGI配置儘可能的簡單。我們可以根據實際的路徑替換 SCRIPT_FILENAMEDOCUMENT_ROOT 裏面的 documentrootdocument_root** , ** document_root 變量是硬編碼的,可能無法隨着我們的安裝(通常會報“找不到腳本”的錯誤)。如果要使用NGINX +虛擬主機+ PHP,我們應該省略 SCRIPT_NAME 變量,以便 PHP 選擇正確的 DOCUMENT_ROOT

4. koi-utf,koi-win,win-utf

這三個文件都是與編碼轉換映射文件,用於在輸出內容到客戶端時,將一種編碼轉換到另一種編碼。

5. uwsgi_params,scgi_params

fastcgi_params 一樣,傳遞哪些服務器變量,只有前綴不一樣,以 uwsgi_param 開始而非 fastcgi_param

6. mime.types,mime.types.default

文件擴展名與文件類型映射表,Nginx 根據映射關係,設置http請求響應頭的Content-Type值。當在映射表找不到時,使用nginx.conf中default-type指定的默認值。
默認配置中的指定的default-type爲application/octet-stream。

    include             /etc/nginx/mime.types;
    default_type        application/octet-stream;

訪問日誌路徑 和 錯誤日誌路徑

[root@wsk1103 wsk]# cd /var/log/nginx/

裏面有日誌 access.log(接收日誌) 和 error.log(錯誤處理日誌)

5. 正向代理和反向代理

5.1. 反向代理

指服務器以代理服務器的形式,將接受到的網絡請求轉發到內部的其他服務器上,並從該內部服務器將響應結果返回給網絡請求,這個時候請求者只知道代理服務器的IP地址,而不知道真正的服務器地址,防止真正的服務器受到不必要的攻擊。

image

反向代理的好處
  • 保護真正的後臺服務器,使黑客不知道真正的服務器的IP地址。
  • 通過緩存靜態資源,加速Web請求。
  • 實現負載均衡。

5.2. 正向代理

正向代理服務器,一個位於客戶端和後臺服務器之間的服務器,爲了從後臺服務器取得內容,客戶端向代理髮送一個請求並指定目標(後臺服務器),然後代理向後臺服務器轉交請求並將獲得的內容返回給客戶端。

image

6. Nginx 配置文件

配置文件目錄

[root@wsk1103 ~]# vi /etc/nginx/nginx.conf

文件說明

# For more information on configuration, see:
#   * Official English Documentation: http://nginx.org/en/docs/
#   * Official Russian Documentation: http://nginx.org/ru/docs/

#定義 nginx 運行的用戶和用戶組
user nginx;

#nginx 進程數,建議設置爲等於 CPU 總核心數。
#worker_processes auto這個是不建議的,最好是設置成固定數值
worker_processes auto;

#nginx 默認沒有開啓利用多核 CPU, 通過增加 worker_cpu_affinity 配置參數來充分利用多核 CPU 以下是 8 核的配置參數
#這個配置用於將 worker process 與指定 CPU 核綁定,降低由於多 CPU 核切換造成的寄存器等重建帶來的性能損耗。
worker_cpu_affinity 00000001 00000010 00000100 00001000 00010000 00100000 01000000 10000000;

#所有錯誤輸出的日誌位置
error_log /var/log/nginx/error.log;

#進程文件
pid /run/nginx.pid;

# Load dynamic modules. See /usr/share/doc/nginx/README.dynamic.
#nginx啓動時會優先加載這個目錄下的所有 .conf 文件
#該目錄裏面的文件 mod-http-image-filter.conf  mod-http-perl.conf  mod-http-xslt-filter.conf  mod-mail.conf  mod-stream.conf
include /usr/share/nginx/modules/*.conf;

events {
    #單個後臺 worker process 進程的最大併發鏈接數
    worker_connections 1024;
}

http {
    # 寫入日誌文件的日誌格式
    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  /var/log/nginx/access.log  main;

    #開啓高效文件傳輸模式,sendfile 指令指定 nginx 是否調用 sendfile 函數來輸出文件,對於普通應用設爲 on,如果用來進行下載等應用磁盤 IO 重負載應用,可設置爲 off,以平衡磁盤與網絡 I/O 處理速度,降低系統的負載。注意:如果圖片顯示不正常把這個改成 off。
    sendfile            on;
    
    #防止網絡阻塞
    tcp_nopush          on;
    
    #防止網絡阻塞
    tcp_nodelay         on;
    
    #開啓目錄列表訪問,適合下載服務器,默認關閉。
    autoindex on; 
    
    ##連接客戶端超時時間各種參數設置##
    #單位是秒,客戶端連接時時間,超時之後服務器端自動關閉該連接 如果 nginx 守護進程在這個等待的時間裏,一直沒有收到瀏覽發過來 http 請求,則關閉這個 http 連接
    keepalive_timeout   65;
    #客戶端請求頭的超時時間
    client_header_timeout 10;    
    #客戶端請求主體超時時間
    client_body_timeout 10;   
    #關閉不響應的客戶端連接。這將會釋放那個客戶端所佔有的內存空間
    reset_timedout_connection on; 
    #客戶端響應超時時間,在兩次客戶端讀取操作之間。如果在這段時間內,客戶端沒有讀取任何數據,nginx 就會關閉連接
    send_timeout 10;      
    
    #FastCGI 相關參數是爲了改善網站的性能:減少資源佔用,提高訪問速度。
    #Nginx 的 buffer 機制,對於來自 FastCGI Server 的 Response,Nginx 將其緩衝到內存中,然後依次發送到客戶端瀏覽器。緩衝區的大小由 fastcgi_buffers 和 fastcgi_buffer_size 兩個值控制。
    #連接超時
    fastcgi_connect_timeout 300;
    #發生超時
    fastcgi_send_timeout 300;
    #讀取超時
    fastcgi_read_timeout 300;
    #緩存區大小
    fastcgi_buffer_size 8k;
    #控制 nginx 最多創建 4 個大小爲 8K 的緩衝區
    fastcgi_buffers 4 8k;
    ##默認值是fastcgi_buffer的2倍
    fastcgi_busy_buffers_size 16k;
    #寫入緩存文件使用多大的數據塊,默認值是fastcgi_buffer的2倍
    fastcgi_temp_file_write_size 16k;
    
    #影響散列表的衝突率。types_hash_max_size越大,就會消耗更多的內存,但散列key的衝突率會降低,檢索速度就更快。types_hash_max_size越小,消耗的內存就越小,但散列key的衝突率可能上升。
    types_hash_max_size 2048;
    #服務器名字的 hash 表大小
    server_names_hash_bucket_size 128; 
    
    #上傳文件大小限制
    client_header_buffer_size 1k; 
    #設定請求緩,一般來說默認就夠了。發生414 (Request-URI Too Large) 錯誤時請增大這兩個參數。
    large_client_header_buffers 4 8k; 
    #客戶端上傳的body的最大值。超過最大值就會發生413(Request Entity Too Large)錯誤。默認爲1m,最好改大一點。
    client_max_body_size 8m; 
    
    #對傳輸文件壓縮-gzip 模塊設置
    #開啓 gzip 壓縮輸出
    gzip on; 
    #最小壓縮文件大小
    gzip_min_length 1k; 
    #壓縮緩衝區
    gzip_buffers 4 16k; 
    #壓縮版本
    gzip_http_version 1.1; 
    #壓縮等級,gzip 壓縮比,1 爲最小,處理最快;9 爲壓縮比最大,處理最慢,傳輸速度最快,也最消耗 CPU;
    gzip_comp_level 2; 
    #壓縮類型,默認就已經包含  application/xml; text/html
    gzip_types text/plain application/x-javascript text/css
    gzip_vary on;
    
    #文件擴展名與文件類型映射表
    include             /etc/nginx/mime.types;
    default_type        application/octet-stream;

    # Load modular configuration files from the /etc/nginx/conf.d directory.
    # See http://nginx.org/en/docs/ngx_core_module.html#include
    # for more information.
    include /etc/nginx/conf.d/*.conf;

    upstream wsk1103.github.io {
        #upstream 的負載均衡,weight 是權重,可以根據機器配置定義權重。weigth 參數表示權值,權值越高被分配到的機率越大。
        #另外還有 ip_hash 輪訓
        server 192.168.134.2 weight=1;
        server 192.168.134.3 weight=2;
        server 192.168.134.4 weight=3;
    }

    #虛擬主機的配置
    server {
        #監聽端口,默認服務
        listen *:80 | *:8000; # 監聽所有的 80 和 8000 端口
        #域名可以有多個,用空格隔開
        server_name  wsk1103.github.io wsk1103.github.com;
        #server_name .wsk1103.com  www.wsk1103.  wsk1103.*; # 使用通配符
        #server_name ~^w{3}.wsk1103.com$; # 使用正則
        #配置中,可以用正則的地方,都以~開頭
        # 當匹配到多個時,處理優先級
        # 1. 準確匹配到 server_name
        # 2. 通配符在開始時匹配到 server_name
        # 3. 通配符在結尾時匹配到 server_name
        # 4. 正則表達式匹配 server_name
        # 5. 順序加載
        
        index index.html index.htm index.php;
        root         /usr/share/nginx/html;
        # 訪問 localhost 時,重定向到 https://wsk1103.github.io
        rewrite ".*" https://wsk1103.github.io;

        # Load configuration files for the default server block.
        include /etc/nginx/default.d/*.conf;
        
        # location 的4種匹配模式,匹配優先級 ‘ = > 其他 ’
        # 1. = :用於標準 uri前,要求請求字符串與其嚴格匹配,成功則立即處理
        # 2. ^~ :用於標準 uri前,並要求一旦匹配到,立即處理,不再去匹配其他的正則 uri
        # 3. ~ :用於正則 uri前,表示 uri 包含正則表達式,並區分大小寫
        # 4. ~* :用於正則 uri前, 表示 uri 包含正則表達式,不區分大小寫

        location ~ .*.(php|java)?$ {
            fastcgi_pass 127.0.0.1:8081;
            fastcgi_index index.php;
            include fastcgi.conf;
        }
        
        #緩存時間設置
        location ~ .*.(gif|jpg|jpeg|png|bmp|swf|js|css)$ {
            expires 10d;
            #d表示天,h表示小時
        }
        
        #服務器收到請求後,首先要在服務端指定的目錄中尋找請求資源
        location /image/ {
            # 將訪問 /image/ 下的文件指向 系統定義的目錄 /home/wsk/image/ 中
            root /home/wsk/;
            autoindex on;
        }

        #對 "/" 啓用反向代理
        location / {
            #代理到本地的8081端口
            proxy_pass http://127.0.0.1:8081; 
            proxy_redirect off;
            proxy_set_header X-Real-IP $remote_addr;
            #使後端服務器可以通過 X-Forwarded-For 獲取用戶真實 IP
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            #以下是一些反向代理的配置,可選。
            proxy_set_header Host $host;
            client_max_body_size 10m; #允許客戶端請求的最大單文件字節數
            client_body_buffer_size 128k; #緩衝區緩衝用戶端請求的最大字節數,

            ##代理設置 以下設置是 nginx 和後端服務器之間通訊的設置##
            proxy_connect_timeout 90; #代理連接超時
            proxy_send_timeout 90; #代理髮送超時
            proxy_read_timeout 90; #代理接收超時
            proxy_buffering on;    #該指令開啓從後端被代理服務器的響應內容緩衝 此參數開啓後 proxy_buffers 和 proxy_busy_buffers_size 參數纔會起作用
            proxy_buffer_size 4k;  #設置代理服務器(nginx)保存用戶頭信息的緩衝區大小
            proxy_buffers 4 32k;   #設置4個緩衝區,大小限制爲 32k 
            proxy_busy_buffers_size 64k; #高負荷下緩衝大小,默認爲 proxy_buffers 的2倍
            proxy_max_temp_file_size 2048m; #默認 1024m, 該指令用於設置當網頁內容大於 proxy_buffers 時,臨時文件大小的最大值。如果文件大於這個值,它將從 upstream 服務器同步地傳遞請求,而不是緩衝到磁盤
            proxy_temp_file_write_size 512k; 這是當被代理服務器的響應過大時 nginx 一次性寫入臨時文件的數據量。
            proxy_temp_path  /var/tmp/nginx/proxy_temp;    ##定義緩衝存儲目錄,之前必須要先手動創建此目錄
            proxy_headers_hash_max_size 51200;
            proxy_headers_hash_bucket_size 6400;
        }
        
        # 404時顯示的頁面
        error_page 404 /404.html;
            location = /40x.html {
        }
        # 50*時顯示的頁面
        error_page 500 502 503 504 /50x.html;
            location = /50x.html {
        }
        
        #本地動靜分離反向代理配置
        #所有 jsp 的頁面均交由 tomcat 處理
        location ~ .(jsp|jspx|do)?$ {
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_pass http://127.0.0.1:8080;
        }
        #設定查看 nginx 狀態的地址
        location /nginxStatus {
            stub_status on;
            access_log on;
            auth_basic "nginxStatus";
            auth_basic_user_file conf/htpasswd;
            #htpasswd 文件的內容可以用 apache 提供的 htpasswd 工具來產生。
        }

    }

    # 設置HTTPS
# Settings for a TLS enabled server.
#
#    server {
#        listen       443 ssl http2 default_server;
#        listen       [::]:443 ssl http2 default_server;
#        server_name  _;
#        root         /usr/share/nginx/html;
#
#        ssl_certificate "/etc/pki/nginx/server.crt";
#        ssl_certificate_key "/etc/pki/nginx/private/server.key";
#        ssl_session_cache shared:SSL:1m;
#        ssl_session_timeout  10m;
#        ssl_ciphers HIGH:!aNULL:!MD5;
#        ssl_prefer_server_ciphers on;
#
#        # Load configuration files for the default server block.
#        include /etc/nginx/default.d/*.conf;
#
#        # 將 http 強制轉換成 https
#        if ($scheme = 'http') {
#            rewrite ^(.*)$ https://$host$uri;
#        }
#        location / {
#        }
#
#        error_page 404 /404.html;
#            location = /40x.html {
#        }
#
#        error_page 500 502 503 504 /50x.html;
#            location = /50x.html {
#        }
#    }
}

7. Nginx的Master-Worker模式

Nginx 採用的是工作模式是 多進程&多路IO複用模型(與Netty相似)。

image

流程說明:

  1. 當 Nginx 啓動後,會啓動一個 master 進程和多個相互獨立的 worker 進程。
  2. 當接收都請求時, master 最先接收到信息,然後再分配給 worker ,每一個 worker 都有機會來處理這次請求。
  3. master 進程持續監控着 worker 的運行狀態,當 worker 異常退出時,重新啓動一個新的 worker 。

PS:進程 worker 的數量一般會設置成CUP核數。如果設置過多,會導致 worker 競爭CUP,從而帶來了不必要的上下文切換(這個和java的多線程類似)。使用多進程模式,不僅能提高併發率,而且進程之間相互獨立,一個 worker 進程掛了不會影響到其他 worker 進程。

設置 worker 的數量

在 nginx.conf 裏面配置

#nginx 進程數,建議設置爲等於 CPU 總核心數。
worker_processes 8;

8. Nginx實現熱部署

通過修改配置文件 nginx.conf 後,不需要停止 Nginx,也不需要中斷請求,就能讓配置文件生效

[root@wsk1103 ~]# nginx -s reload  # 重新加載
[root@wsk1103 ~]# nginx -t     # 檢查配置
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

因爲 Nginx 是使用 master-worker 的模式,在修改配置文件 nginx.conf 後,會重新生成新的 worker 進程,並且用新的配置處理請求,而舊的 worker 進程,則是等把原來的請求處理完畢後,會自動 kill 。

9. Nginx在高併發下的高效處理

Nginx 採用了 Linux 的 epoll 模型, epoll 模型是基於事件驅動機制,它可以監控多個事件是否準備完畢,如果準備完成,那麼放入 epoll 隊列中,這個過程是異步的。 worker 只需要從 epoll 隊列循環處理即可。

Nginx 與 多進程模式 Apache 的比較

  • 事件驅動適合於I/O密集型服務,多進程或線程適合於CPU密集型服務
  • Nginx 是事件驅動,更主要是作爲反向代理,而不是服務器使用。
  • Nginx 只需要少量進程配合事件驅動,不需要像 Apache 多進程模型跑幾百個進程。
  • Nginx 處理靜態文件效果顯著,因爲讀寫文件和網絡通信都是 I/O 操作。

10. Keepalived + Nginx 實現高可用

Keepalived + Nginx 實現高可用 的思路:

  1. 請求不是直接打到 Nginx 上,而是先通過 Keepalived (虛擬IP,VIP)
  2. Keepalived 應該能監控 Nginx 的生命狀態
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章