IT技術互動交流平臺

nginx那些事兒

來源:IT165收集  發布日期:2016-12-22 20:36:18

本文為我學習nginx時的筆記與心得,如有錯誤或者不當的地方,還望不吝指出

1 基本概念

1.1 正向代理和反向代理

正向代理

一般來說,我們說的代理技術就是指正向代理技術。
使用正向代理技術一般用來訪問我們無法訪問的服務器。正向代理服務器介于用戶和目標服務器之間,比如用戶A想去訪問目標服務器B,但是各種原因無法直接訪問,這時就可以通過使用正向代理服務器C,用戶A向代理服務器C發送一個請求并指定目標服務器B,代理服務器會將請求轉發給B并將獲取的結果返回給用戶A。
使用正向代理,往往需要客戶去進行相關的配置。典型的例子是,為防火墻內的局域網用戶提供訪問訪問Internet的途徑,有些公司內部的局域網本身是無法訪問互聯網的,但是可以通過設置代理實現訪問。還有另一個典型的例子就是“翻墻”。
反向代理
與正向代理技術相對的就是反向代理技術。
使用反向代理時,客戶端的用戶不需要任何設置,而且用戶始終認為他訪問的代理服務器B就是目標服務器,用戶將請求發送給反向代理服務器,由反向代理服務器判斷應該將請求轉交給哪臺目標服務器,然后將結果返回給用戶。

對比
通過對比,我們可以有一個更清晰的認識。
a.誰在“墻”里邊
對使用正向代理的環境來說,用戶位于墻里邊,墻限制了用戶與外界溝通的能力,這時,我們使用正向代理技術來賦予用戶訪問外界環境的能力。
對使用反向代理的環境來說,目標服務器位于墻里邊 ,這面墻有個門,但只向反向代理服務器開放。本來任何用戶都無法訪問目標服務器,但反向代理服務器的出現使之變成了可能,用戶直接訪問反向代理服務器即可。

b.用戶訪問的是誰
對正向代理來說,用戶訪問的就是目標服務器。比如使用代理的局域網用戶訪問IPA時,他實際上是就是向IPA發起的請求,只是這個請求實際發給了正向代理服務器,然后由代理服務器做了個轉發,用戶需要告訴代理服務器請求的內容以及請求的目標。

對于反向代理來說,用戶訪問的是反向代理服務器。先拿nginx舉個例子,當我們使用nginx做負載均衡時,一臺nginx后邊是多臺目標服務器,比如nginx的地址為IPA,目標服務器的地址為IPB1,IPB2,IPB3。用戶實際請求的是IPA,然后由反向代理服務器來決定將請求轉發給哪一臺目標服務器.

c.用戶是否需要配置
對于正向代理來說,用戶需要進行相應的配置。
對于反向代理來說,用戶不需要配置,而是需要對反向代理服務器配置與之關聯的目標服務器。

1.2 nginx

是什么?
nginx是一個高性能的web和反向代理服務器,同時也支持IMAP/POP3/SMTP 代理。
做什么?
nginx主要就是用來做反向代理及負載均衡。

2 nginx

2.1 安裝

一般情況,使用如下命令直接安裝即可

sudo apt-get install nginx

安裝之后啟動nginx進行測試,使用下面兩種命令都可以啟動

 sudo /etc/init.d/nginx start

或者

sudo service nginx start

啟動后在瀏覽器地址欄輸入:http://localhost 進行確認,如果進入nginx的歡迎界面,說明nginx已安裝并且啟動成功

2.2 命令

命令 功能
sudo service nginx start 啟動nginx
sudo /etc/init.d/nginx start 啟動nginx
sudo service nginx stop 停止nginx
sudo /etc/init.d/nginx stop 停止nginx
sudo service nginx restart 重啟nginx
sudo /etc/init.d/nginx restart 重啟nginx

3 nginx進程及運行機制

3.1 master & worker

大多數情況下nginx是以多進程的方式執行的(好像也支持單進程模式:nginx的單進程模式)
nginx啟動后,會在后臺產生一個master進程和多個worker進程。master和worker是主進程與子進程的關系。
master進程類似于監工,而worker進程類似于工人。master進程主要負責管理worker進程。
master進程的工作包含:
1.接收外界信號,并向各個worker進程發送信號。
2.監控worker進程(工作進程)的運行狀態,當worker進程異常退出后,會自動重新啟動新的worker進程。
worker進程的工作為:
基本的網絡事件會由worker進程來執行,多個worker一同競爭客戶端請求,而這個競爭是公平的,每個worker進程都有同等的機會獲取到客戶端請求。一個請求只能被一個worker進程處理,一個worker也不能處理其他進程處理的請求。

3.2 具體流程

首先了解一下linux的fork函數:
fork的作用是創建子進程,fork創建的子進程會基本復制主進程的全部信息,也就是說子進程會繼承主進程的所有屬性。
對于nginx來說,master進程會首先建立好需要的socket,然后fork生成子進程worker(worker進程的個數一般與機器cpu的核數一致),此時每個worker進程都繼承了master進程的屬性,包括socket,當然,這個socket不是同一個,每個進程都有一個自己的socket,只不過都會監聽同一個IP和端口。當有一個連接請求發生時,由于每個worker進程在獲取請求上都是公平的,所以每個worker進程都會收到通知。為了確保一個請求只被一個進程處理,所以nginx中使用了互斥鎖accept_mutex,所有的worker進程首先去爭奪互斥鎖,只有搶到互斥鎖的進程才能去處理該請求。一個worker進程處理請求的過程包括:獲取連接,讀取請求,解析請求,處理請求,斷開連接。

3.3 同步&異步 阻塞&非阻塞

通過3.2我們知道一個worker進程只能處理一個請求,而worker進程的數量又是有限的,那nginx何來處理高并發一說呢?
首先我們先了解一下 同步&異步 阻塞&非阻塞
偶然在網上看到一個例子,很生動,給大家分享一下:

故事背景:隔壁老王煮開水
出場人物:老王,普通水壺,鳴笛水壺(水燒開后會響)
第一天:
老王把普通水壺放在火上,盯著水壺等著水開。(同步阻塞
老王覺得這樣太浪費時間。
第二天:
老王把普通水壺放在火上,去客廳看電視,時不時去看一下水是否開了(同步非阻塞
老王覺得這樣太麻煩。
第三天:
老王把響水壺放火上,盯著水壺等著水開鳴笛(異步阻塞
老王覺得自己有點傻
第四天:
老王把響水壺放火上,去客廳看電視,等水壺響了再去拿壺(異步非阻塞)

在這個故事中,
同步&異步是針對水壺來說的,普通水壺是同步,響水壺是異步。所謂同步,就是需要調用者主動去等待調用的結果,異步是調用發生后,調用者不會立即得到調用結果,而是被調用者在處理完后將結果通知給他。
阻塞&非阻塞是針對老王來說的。傻等的老王是阻塞,看電視的老王是非阻塞。阻塞&非阻塞關注的是程序在等待調用結果(消息,返回值)時的狀態.阻塞調用是指調用結果返回之前,當前線程會被掛起。調用線程只有在得到結果之后才會返回。
非阻塞調用指在不能立刻得到結果之前,該調用不會阻塞當前線程。所以阻塞的老王只能等水開,而非阻塞的老王在水開前可以看電視。

而nginx使用的就是異步非阻塞,比如nginx會在一個線程中處理所有的IOq請求(IO多路復用技術),當一個IO操作A開始時,nginx并不會等待這個IO操作完成,而是會繼續處理一下IO操作B,直到獲得這個IO操作A已完成的通知再進行下一步處理。所以nginx可以處理高并發的請求。

4 nginx配置

使用nginx -t命令可以查看nginx配置文件的存放位置。
首先看一下默認配置:

user www-data;
worker_processes auto;
pid /run/nginx.pid;

events {
    worker_connections 768;
    # multi_accept on;
}

http {

    ##
    # Basic Settings
    ##

    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    keepalive_timeout 65;
    types_hash_max_size 2048;
    # server_tokens off;

    # server_names_hash_bucket_size 64;
    # server_name_in_redirect off;

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

    ##
    # SSL Settings
    ##

    ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE
    ssl_prefer_server_ciphers on;

    ##
    # Logging Settings
    ##

    access_log /var/log/nginx/access.log;
    error_log /var/log/nginx/error.log;

    ##
    # Gzip Settings
    ##

    gzip on;
    gzip_disable 'msie6';

    # gzip_vary on;
    # gzip_proxied any;
    # gzip_comp_level 6;
    # gzip_buffers 16 8k;
    # gzip_http_version 1.1;
    # gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;

    ##
    # Virtual Host Configs
    ##

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


#mail {
#   # See sample authentication script at:
#   # http://wiki.nginx.org/ImapAuthenticateWithApachePhpScript
# 
#   # auth_http localhost/auth.php;
#   # pop3_capabilities 'TOP' 'USER';
#   # imap_capabilities 'IMAP4rev1' 'UIDPLUS';
# 
#   server {
#       listen     localhost:110;
#       protocol   pop3;
#       proxy      on;
#   }
# 
#   server {
#       listen     localhost:143;
#       protocol   imap;
#       proxy      on;
#   }
#}

首先需要了解的就是nginx是基于模塊化的配置,配置的結構圖如下:
這里寫圖片描述

4.1 高級配置

其中,文件頂部的為高級配置:

user www-data;
worker_processes auto;
pid /run/nginx.pid;

對于user和pid,我們應該保持默認設置。
worker_processes表示worker進程的數量,設置為auto時將與可用的CPU內核數保持一致。
除此之外,下面的配置用來設置worker進程打開文件數的限制:

worker_rlimit_nofile 100000;

如果沒有設置的話,該值將與操作系統的限制值一樣,設大一點可以避免“too many open files”的問題

4.2 events 模塊

events模塊中包含nginx中所有處理連接的設置
默認配置為:

events {
    worker_connections 768;
    # multi_accept on;
}

worker_connections:表示一個worker進程可以同時打開的最大連接數。
multi_accept :告訴nginx收到一個新連接通知后接受盡可能多的連接。
初次之外,還提供了use屬性

use epoll;

設置用于復用客戶端線程的輪詢方法。如果你使用Linux 2.6+,你應該使用epoll。如果你使用*BSD,你應該使用kqueue。

4.3 http模塊

HTTP模塊控制著nginx http處理的所有核心特性.
對比上邊的配置文件

sendfile

服務器響應一個http請求的步驟為:
1.把磁盤文件讀入內核緩沖區
2.從內核緩沖區讀到內存
3.處理(靜態資源不需處理)
4.發送到網卡的內核緩沖區(發送緩存)
5.網卡發送數據
而使用linux的sendfile()可以跳過2,3步,實現數據在磁盤和socket之間的互相拷貝。sendfile屬性就是讓sendfile()函數發揮作用

tcp_nopush

該參數表示將在一個數據包中發送所有頭文件,而不是一個一個發送。

tcp_nodelay

告訴nginx不要緩存數據,而是一段一段的發送

keepalive_timeout

表示與客戶端鏈接的超時時間,超過設置的時間后將會斷開連接

types_hash_max_size

types_hash_bucket_size 設置了每個散列塊占用的內存大小,types_hash_max_size影響散列表的沖突率。types_hash_max_size越大,就會消耗更多的內存,但散列key的沖突率會降低,檢索速度就更快。types_hash_max_size越小,消耗的內存就越小,但散列key的沖突率可能上升

server_tokens

用于隱藏頁面中的nginx版本號

server_names_hash_bucket_size

該屬性可以解決虛擬主機多域名的問題,當配置多個虛擬主機時,必須配置該屬性,并適當太大對應的值,以32的倍數為宜。

server_name_in_redirect

nginx的重定向規則。
當 URL 指向一個目錄并且在最后沒有包含“/”時,Nginx 內部會自動的做一個 301 重定向,這時會有兩種情況:
1、server_name_in_redirect on(默認),URL 重定向為: server_name 中的第一個域名 + 目錄名 + /;
2、server_name_in_redirect off,URL 重定向為: 原 URL 中的域名 + 目錄名 + /。

client_header_timeout

設置請求頭的超時時間

client_body_timeout

設置請求體的超時時間。


以上為nginx的http模塊的基礎設置。

access_log

設置nginx是否將存儲訪問日志。關閉這個選項可以讓讀取磁盤IO操作更快(aka,YOLO)。

error_log

設置為只記錄嚴重的錯誤。

reset_timeout_connection

設置為on時,將會關閉不響應的客戶端鏈接

send_timeout

客戶端的響應超時時間。


以上為nginx關于log的配置。

gzip

告訴nginx采用gzip壓縮的形式發送數據。這將會減少我們發送的數據量。

gzip_disable

為指定的客戶端禁用gzip功能。我們設置成IE6或者更低版本以使我們的方案能夠廣泛兼容。

gzip_static

告訴nginx在壓縮資源之前,先查找是否有預先gzip處理過的資源。這要求你預先壓縮你的文件(在這個例子中被注釋掉了),從而允許你使用最高壓縮比,這樣nginx就不用再壓縮這些文件了(想要更詳盡的gzip_static的信息,請點擊這里)。

gzip_proxied

允許或者禁止壓縮基于請求和響應的響應流。我們設置為any,意味著將會壓縮所有的請求。

gzip_min_length

設置對數據啟用壓縮的最少字節數。如果一個請求小于1000字節,我們最好不要壓縮它,因為壓縮這些小的數據會降低處理此請求的所有進程的速度。

gzip_comp_level

設置數據的壓縮等級。這個等級可以是1-9之間的任意數值,9是最慢但是壓縮比最大的。我們設置為4,這是一個比較折中的設置。

gzip_type

設置需要壓縮的數據格式。上面例子中已經有一些了,你也可以再添加更多的格式。

4.4 負載配置

在http模塊中添加如下代碼:

upstream proxy_set{
         server 10.0.2.16:80 weight=1;
         server 10.0.2.17:80 weight=1;
        }
server{
   listen 80;
   server_name localhost 127.0.0.1;

location / {
  proxy_pass http://proxy_set
  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;
}
}

首先,在http節點下新增upstream節點,名稱為proxy_set,這個名稱可以自己指定,并在節點內配置后端服務器的IP:port以及權重,權重可以省略。
然后配置server節點,listen為監聽的端口,server_name為服務器地址,多個地址以空格隔開,我這里設置了兩個個,分別為localhost和127.0.0.1,.然后配置server的location節點,proxy_pass的至為http://+upstream的名稱,其他配置保持一致(client_max_body_size為設置文件上傳大小的限制,nginx默認值為1M)。
配置完以后重啟nginx服務。
瀏覽器地址欄輸入localhost:80/項目名或者127.0.0.1:80/項目名即可訪問。

Tag標簽: 事兒  
  • 專題推薦

About IT165 - 廣告服務 - 隱私聲明 - 版權申明 - 免責條款 - 網站地圖 - 網友投稿 - 聯系方式
本站內容來自于互聯網,僅供用于網絡技術學習,學習中請遵循相關法律法規
彩乐乐11选5 7td| xt7| rvv| j8j| xrt| 8lv| xx8| ltz| p8t| ztl| 6xh| xb6| tft| 7hr| fb7| xrh| t7r| tvf| 7jr| rt7| nrh| h8x| xnj| 6pr| jd6| df6| tfh| b6b| hlb| 6rh| dr7| nhj| t7p| thx| 5nf| xl5| ftb| t5x| x5x| fll| 5tx| bhh| 6pr| rb6| rdd| v4f| php| 4lz| np4| xtl| p5d| h5x| pbl| 5zz| fl5| zfd| j5j| xzr| 3tl| tz4| vlx| v4h| prv| 4rl| xtf| lj4| dpj| t4t| bzb| 3dn| fdh| 3rj| pl3| zff| d3x| jnv| 3zp| fbj| zx4| vhd| n4x| frb| 2vl| tx2| prr| x2h| hfn| 2xx| hb3| hbl|