閱讀136 返回首頁    go 阿裏雲 go 技術社區[雲棲]


NGINX 簡明教程

原文同步至 https://waylau.com/nginx-concise-tutorial/

NGINX 是一款來自俄羅斯的HTTP 和反向代理(reverse proxy)服務器、郵件服務器,以及通用的 TCP/UDP 代理服務器,以其高性能被業界廣泛采用。本文通過最簡潔的方式,將 NGINX 核心應用做下介紹。

什麼是 NGINX

NGINX是一個免費的、開源的、高性能的 HTTP 服務器和反向代理,以及一個 IMAP/POP3 代理服務器。 NGINX以其高性能、穩定性、豐富的功能集、簡單的配置和低資源消耗而聞名。

NGINX 是為解決C10K 問題而編寫的少數服務器之一。與傳統服務器不同,NGINX 不依賴於線程來處理請求。相反,它使用更加可擴展的事件驅動(異步)架構。這種架構在負載下使用小的但更重要的是可預測的內存量。即使您不希望處理數千個並發請求,您仍然可以從 NGINX 的高性能和小內存中獲益。 NGINX 在各個方向擴展:從最小的 VPS 一直到大型服務器集群。

控製語句

NGINX 啟動後,有一個主進程(master process)和一個或多個工作進程(worker process),主進程的作用主要是讀入和檢查NGINX的配置信息,以及維護工作進程;工作進程才是真正處理客戶端請求的進程。具體要啟動多少個工作進程,可以在 NGINX 的配置文件nginx.conf中通過worker_processes指令指定。
可以通過以下這些命令來控製 NGINX:

nginx -s [ stop | quit | reopen | reload ]

其中:

  • nginx -s stop: 強製停止NGINX,不管工作進程當前是否正在處理用戶請求,都會立即退出。
  • nginx -s quit:“優雅地”退出NGINX,執行這個命令後,工作進程會將當前正在處理的請求處理完畢後,再退出。
  • nginx -s reload:重載配置信息。當NGINX的配置文件改變之後,同過執行這個命令,使更改的配置信息生效,而無需重新啟動nginx.
  • nginx -s reopen:重新打開日誌文件。

配置服務器名稱

服務器名稱是用server_name指令來定義的,並且它決定了哪一個server塊將用來處理給定的請求。可以使用精確名稱、通配符、正則表達式來定義服務器名稱。

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

server {
    listen       80;
    server_name  *.example.org;
    ...
}

server {
    listen       80;
    server_name  mail.*;
    ...
}

server {
    listen       80;
    server_name  ~^(?<user>.+)\.example\.net$;
    ...
}

當尋找一個虛擬服務器的名字,如果指定的名稱匹配多個變體,例如,通配符和正則表達式都匹配,將會按照以下的順序選擇第一個匹配的變體:

  • 精確名稱
  • 以星號(*)開頭的最長的通配符,例如“*.example.org”
  • 以星號(*)結尾的最長的通配符,例如“mail.*”
  • 第一個匹配的正則表達式(根據在配置文件中出現的順序)

配置 HTTPS 服務器

修改 conf/nginx.conf 文件,必須在配置文件 server 塊中的監聽指令 listen 後啟用 ssl 參數,並且指定服務器證書 ssl_certificate 和私鑰 ssl_certificate_key 的位置:

server {
    listen              443 ssl;
    server_name         www.example.com;
    ssl_certificate     www.example.com.crt;
    ssl_certificate_key www.example.com.key;
    ssl_protocols       TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers         HIGH:!aNULL:!MD5;
    ...
}

服務器證書是一個公共實體,它被發送給連接到服務器的每一個客戶機。私鑰是一個安全實體,應該存儲在具有受限訪問的文件中,但它必須可被nginx主進程讀取。私鑰也可以存儲在與服務器證書相同的文件中:

    ssl_certificate     www.example.com.cert;
    ssl_certificate_key www.example.com.cert;

在這種情況下,這個證書文件的訪問權限也應受到限製。雖然證書和密鑰存儲在一個文件中,但隻有證書被發送到客戶端。

指令 ssl_protocolsssl_ciphers 可用於限製僅包括強版本和密碼的 SSL/TLS 連接。 默認情況下,NGINX 使 用ssl_protocols TLSv1 TLSv1.1 TLSv1.2版本和ssl_ciphers HIGH:!aNULL:!MD5密碼,因此通常不需要顯式地配置它們。需要注意的是,這些指令的默認值在不同的版本裏麵已經變更好幾次了。

作為 HTTP 負載均衡器

跨多個應用程序實例的負載均衡是優化資源利用率,最大限度地提高吞吐量,降低延遲,並確保容錯配置一個常用的技術。

NGINX 支持如下負載均衡的機製(或方法):

1. 輪詢

如果沒有指定負載均衡的方法,那麼 NGINX 默認采用的是輪詢的方式。最簡單的負載均衡配置如下:

http {
    upstream myapp1 {
        server srv1.example.com;
        server srv2.example.com;
        server srv3.example.com;
    }

    server {
        listen 80;

        location / {
            proxy_pass https://myapp1;
        }
    }
}

3個同樣實例的應用(srv1-srv3)是采用輪詢方式。所有請求被代理到一組服務myapp1,同時,NGINX 運用 HTTP 負載均衡來分發請求。

反向代理被應用在 NGINX 內,包括負載均衡針對 HTTP、HTTPS、FASTCGI、uwsgi、SCGI 以及 memcached。

配置負載均衡針對 HTTPS 替代 HTTP 的話,僅僅使用 https 協議即可(proxy_pass https://myapp1)。

在為 FASTCGI、uwsgi、SCGI 或 memcached 設置負載均衡時,分別使用 fastcgi_pass、uwsgi_pass、scgi_pass 和 memcached_pass 指令。

2. 最少連接

在一些請求需要更長時間才能完成的情況下,最少連接可以更公正地控製應用程序實例的負載。

使用最少連接的負載平衡,NGINX 將不會加重一個有過多請求的應用服務負擔,而是將它分發新的請求給最不繁忙的服務器。

在 NGINX 中需要通過設置least_conn來激活最少連接的負載均衡策略配置:

upstream myapp1 {
    least_conn;
    server srv1.example.com;
    server srv2.example.com;
    server srv3.example.com;
}

3. IP 哈希(會話持久)

注意,采用輪詢或者最少連接的負載均衡策略,每個客戶端的後續請求可能被分配帶不同的服務器,不能保證同一個客戶端總是指向同一個服務。如果需要告訴客戶端分配到一個特定的應用服務,換句話,就是保持客戶端的會話粘性(sticky)或者會話持久性(persitent),即總是嚐試選著同一個特定的服務器,IP 哈希 負載均衡機製可以被使用。

采用 IP 哈希的策略,客戶端的 IP 地址被用作一個哈希 key,決定哪個服務應該被選中來服務客戶端的請求。這種方式,確保了同一個客戶端來的請求將總是被指向同一個服務,除非這個服務不可用了。

配置IP 哈希負載均衡,隻需要通過設置ip_hash來激活:

upstream myapp1 {
    ip_hash;
    server srv1.example.com;
    server srv2.example.com;
    server srv3.example.com;
}

權重(weight)

可以通過使用服務器的權重來影響 NGINX 的負載均衡算法,在上述輪詢、最少請求、基於IP 哈希負載均衡配置中,服務器的權重沒有配置,意味著所有服務器的權重都是一樣的。特別是輪詢,它意味著或多或少平等的分發請求到服務器(請求夠多,並且請求以均勻方式進行處理,並完成夠快)

當配置了一個 weight 變量到一個指定的服務後,權重被作為一個 NGINX 的負載均衡的決定的一部分:

upstream myapp1 {
    server srv1.example.com weight=3;
    server srv2.example.com;
    server srv3.example.com;
}

采用上麵的配置,如果來了5個請求,3個到srv1,1個到srv2,1個到srv3。在最近的NGINX版本中,同樣可以使用權重針對最少連接和IP 哈希的負載均衡策略。

健康監測

反向代理在 NGINX 中實現了被動的健康監測,如果響應從一個特定的服務器失敗,攜帶著錯誤,NGINX 將標記這個服務器是失敗的,並將嚐試一段時間避免選擇這個服務器作為後續請求的服務器。

fail_timeoutmax_fails 用於設定指定時間內,應該發生連續不成功的數目。默認max_fail等於1,如果設置成0,相當於關閉這個服務器的健康監測。fail_timeout參數,定義多久服務器被標識失敗。過了服務器fail_timeout失敗超時間隔後,NGINX 將開始探測存活的客戶端的請求,如果探測成功,服務被標識成存活狀態。

壓縮與解壓

壓縮響應通常會顯著減少傳輸數據的大小。 然而,由於壓縮在運行時發生,所以會增加處理開銷,這可能會對性能產生負麵影響。

在向客戶端發送響應之前,NGINX 會執行壓縮,但不會“重複壓縮”已經壓縮過的響應。

啟用壓縮

要啟用壓縮,在 gzip 指令上請使用on參數:

gzip on;

默認情況下,NGINX 僅壓縮使用MIME 類型 為 text/html的響應。要壓縮其他 MIME 類型的響應,請包含gzip_types指令並列出相應的類型。

gzip_types text/plain application/xml;

要指定要壓縮的響應的最小長度,請使用gzip_min_length指令。默認值為20字節,下麵示例調整為1000:

gzip_min_length 1000;

默認情況下,NGINX 不會壓縮對代理請求的響應(來自代理服務器的請求)。請求是否來自代理服務器是由請求中Via頭字段的是否存來確定的。要配置這些響應的壓縮,請使用gzip_proxied指令。該指令具有多個參數來指定 NGINX 應壓縮哪種代理請求。例如,僅對不會在代理服務器上緩存的請求進行壓縮響應,為此,gzip_proxied指令具有指示 NGINX 在響應中檢查Cache-Control頭字段的參數,如果值是 no-cache、no-store 或 private,則壓縮響應。另外,您必須包括 expired 的參數來檢查Expires頭字段的值。這些參數在以下示例中與 auth 參數一起設置,該參數檢查Authorization頭字段的存在(授權響應特定於最終用戶,並且通常不被緩存):

gzip_proxied no-cache no-store private expired auth;

與大多數其他指令一樣,配置壓縮的指令可以包含在http上下文中,也可以包含在 serverlocation 塊中。

gzip 壓縮的整體配置可能如下所示。

server {
    gzip on;
    gzip_types      text/plain application/xml;
    gzip_proxied    no-cache no-store private expired auth;
    gzip_min_length 1000;
    ...
}

啟用解壓

某些客戶端不支持使用 gzip 編碼方法的響應。同時,可能需要存儲壓縮數據,或者即時壓縮響應並將它們存儲在緩存中。為了都能成功地服務於接受或者不接受壓縮數據的客戶端,針對後一種類型的客戶端時,NGINX 可以在將數據發送時即時解壓縮數據。

要啟用運行時解壓縮,請使用gunzip指令。

location /storage/ {
    gunzip on;
    ...
}

gunzip指令可以在與gzip指令相同的上下文中指定:

server {
    gzip on;
    gzip_min_length 1000;
    gunzip on;
    ...
}

請注意,此指令在單獨的模塊中定義(見ngx_http_gunzip_modulehttps://nginx.org/en/docs/http/ngx_http_gunzip_module.html),默認情況下可能不包含在開源 NGINX 構建中。

發送壓縮文件

要將文件的壓縮版本發送到客戶端而不是常規文件,請在適當的上下文中將gzip_static指令設置為 on。

location / {
    gzip_static on;
}

在這種情況下,為了服務/path/to/file的請求,NGINX 嚐試查找並發送文件/path/to/file.gz。如果文件不存在,或客戶端不支持 gzip,則 NGINX 將發送未壓縮版本的文件。

請注意,gzip_static指令不啟用即時壓縮。它隻是使用壓縮工具預先壓縮的文件。要在運行時壓縮內容(而不僅僅是靜態內容),請使用gzip指令。

該指令在單獨的模塊中定義(見ngx_http_gzip_static_modulehttps://nginx.org/en/docs/http/ngx_http_gzip_static_module.html),默認情況下可能不包含在開源NGINX構建中。

參考文獻

最後更新:2017-05-21 22:31:14

  上一篇:go  PostgreSQL 鎖等待監控 珍藏級SQL - 誰堵塞了誰
  下一篇:go  阿裏雲優惠,優惠多少看人品--阿裏雲幸運券來臨