做爲一名開發人員,你是否是常常碰到領導讓你上服務器去修改 Nginx 配置,然而你會以「我是開發,這個我不會」爲理由搪塞過去呢!今天就讓咱們一塊兒告別這種尷尬,向「真正」的程序員邁進!!!javascript
Nginx 是開源、高性能、高可靠的 Web 和反向代理服務器,並且支持熱部署,幾乎能夠作到 7 * 24 小時不間斷運行,即便運行幾個月也不須要從新啓動,還能在不間斷服務的狀況下對軟件版本進行熱更新。性能是 Nginx 最重要的考量,其佔用內存少、併發能力強、能支持高達 5w 個併發鏈接數,最重要的是, Nginx 是免費的並能夠商業化,配置使用也比較簡單。css
Nginx 的最重要的幾個使用場景:html
對於前端來講 Node.js 並不陌生, Nginx 和 Node.js 的不少理念相似, HTTP 服務器、事件驅動、異步非阻塞等,且 Nginx 的大部分功能使用 Node.js 也能夠實現,但 Nginx 和 Node.js 並不衝突,都有本身擅長的領域。Nginx 擅長於底層服務器端資源的處理(靜態資源處理轉發、反向代理,負載均衡等), Node.js 更擅長上層具體業務邏輯的處理,二者能夠完美組合。前端
用一張圖表示:java
本文演示的是 Linux centOS 7.x 的操做系統上安裝 Nginx ,至於在其它操做系統上進行安裝能夠網上自行搜索,都很是簡單的。node
yum install nginx -y
安裝完成後,經過 rpm -ql nginx 命令查看 Nginx 的安裝信息:webpack
# Nginx配置文件 /etc/nginx/nginx.conf # nginx 主配置文件 /etc/nginx/nginx.conf.default # 可執行程序文件 /usr/bin/nginx-upgrade /usr/sbin/nginx # nginx庫文件 /usr/lib/systemd/system/nginx.service # 用於配置系統守護進程 /usr/lib64/nginx/modules # Nginx模塊目錄 # 幫助文檔 /usr/share/doc/nginx-1.16.1 /usr/share/doc/nginx-1.16.1/CHANGES /usr/share/doc/nginx-1.16.1/README /usr/share/doc/nginx-1.16.1/README.dynamic /usr/share/doc/nginx-1.16.1/UPGRADE-NOTES-1.6-to-1.10 # 靜態資源目錄 /usr/share/nginx/html/404.html /usr/share/nginx/html/50x.html /usr/share/nginx/html/index.html # 存放Nginx日誌文件 /var/log/nginx
主要關注的文件夾有兩個:nginx
# 開機配置 systemctl enable nginx # 開機自動啓動 systemctl disable nginx # 關閉開機自動啓動 # 啓動Nginx systemctl start nginx # 啓動Nginx成功後,能夠直接訪問主機IP,此時會展現Nginx默認頁面 # 中止Nginx systemctl stop nginx # 重啓Nginx systemctl restart nginx # 從新加載Nginx systemctl reload nginx # 查看 Nginx 運行狀態 systemctl status nginx # 查看Nginx進程 ps -ef | grep nginx # 殺死Nginx進程 kill -9 pid # 根據上面查看到的Nginx進程號,殺死Nginx進程,-9 表示強制結束進程
nginx -s reload # 向主進程發送信號,從新加載配置文件,熱重啓 nginx -s reopen # 重啓 Nginxnginx -s stop # 快速關閉 nginx -s quit # 等待工做進程處理完成後關閉 nginx -T # 查看當前 Nginx 最終的配置 nginx -t # 檢查配置是否有問題
Nginx 的典型配置示例:程序員
# main段配置信息 user nginx; # 運行用戶,默認便是nginx,能夠不進行設置 worker_processes auto; # Nginx 進程數,通常設置爲和 CPU 核數同樣 error_log /var/log/nginx/error.log warn; # Nginx 的錯誤日誌存放目錄 pid /var/run/nginx.pid; # Nginx 服務啓動時的 pid 存放位置 # events段配置信息 events { use epoll; # 使用epoll的I/O模型(若是你不知道Nginx該使用哪一種輪詢方法,會自動選擇一個最適合你操做系統的) worker_connections 1024; # 每一個進程容許最大併發數 } # http段配置信息 # 配置使用最頻繁的部分,代理、緩存、日誌定義等絕大多數功能和第三方模塊的配置都在這裏設置 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; # Nginx訪問日誌存放位置 sendfile on; # 開啓高效傳輸模式 tcp_nopush on; # 減小網絡報文段的數量 tcp_nodelay on; keepalive_timeout 65; # 保持鏈接的時間,也叫超時時間,單位秒 types_hash_max_size 2048; include /etc/nginx/mime.types; # 文件擴展名與類型映射表 default_type application/octet-stream; # 默認文件類型 include /etc/nginx/conf.d/*.conf; # 加載子配置項 # server段配置信息 server { listen 80; # 配置監聽的端口 server_name localhost; # 配置的域名 # location段配置信息 location / { root /usr/share/nginx/html; # 網站根目錄 index index.html index.htm; # 默認首頁文件 deny 172.168.22.11; # 禁止訪問的ip地址,能夠爲all allow 172.168.33.44;# 容許訪問的ip地址,能夠爲all } error_page 500 502 503 504 /50x.html; # 默認50x對應的訪問頁面 error_page 400 404 error.html; # 同上 } }
用一張圖清晰的展現它的層級結構:web
指定運行 Nginx 的 woker 子進程的屬主和屬組,其中組能夠不指定。
user USERNAME [GROUP] user nginx lion; # 用戶是nginx;組是lion
指定運行 Nginx master 主進程的 pid 文件存放路徑。
pid /opt/nginx/logs/nginx.pid # master主進程的的pid存放在nginx.pid的文件
指定 worker 子進程能夠打開的最大文件句柄數。
worker_rlimit_nofile 20480; # 能夠理解成每一個worker子進程的最大鏈接數量。
指定 worker 子進程異常終止後的 core 文件,用於記錄分析問題。
worker_rlimit_core 50M; # 存放大小限制working_directory /opt/nginx/tmp; # 存放目錄
指定 Nginx 啓動的 worker 子進程數量。
worker_processes 4; # 指定具體子進程數量 worker_processes auto; # 與當前cpu物理核心數一致
將每一個 worker 子進程與咱們的 cpu 物理核心綁定。
worker_cpu_affinity 0001 0010 0100 1000; # 4個物理核心,4個worker子進程
將每一個 worker 子進程與特定 CPU 物理核心綁定,優點在於,避免同一個 worker 子進程在不一樣的 CPU 核心上切換,緩存失效,下降性能。但其並不能真正的避免進程切換。
指定 worker 子進程的 nice 值,以調整運行 Nginx 的優先級,一般設定爲負值,以優先調用 Nginx 。
worker_priority -10; # 120-10=110,110就是最終的優先級
Linux 默認進程的優先級值是120,值越小越優先;nice 定範圍爲 -20 到 +19
[備註] 應用的默認優先級值是120加上 nice 值等於它最終的值,這個值越小,優先級越高。
指定 worker 子進程優雅退出時的超時時間。
worker_shutdown_timeout 5s;timer_resolution
worker 子進程內部使用的計時器精度,調整時間間隔越大,系統調用越少,有利於性能提高;反之,系統調用越多,性能降低。
在 Linux 系統中,用戶須要獲取計時器時須要向操做系統內核發送請求,有請求就必然會有開銷,所以這個間隔越大開銷就越小。
指定 Nginx 的運行方式,前臺仍是後臺,前臺用於調試,後臺用於生產。
daemon off; # 默認是on,後臺運行模式
Nginx 使用何種事件驅動模型。
use method; # 不推薦配置它,讓nginx本身選擇method 可選值爲:select、poll、kqueue、epoll、/dev/poll、eventport
worker 子進程可以處理的最大併發鏈接數。
worker_connections 1024 # 每一個子進程的最大鏈接數爲1024
是否打開負載均衡互斥鎖。
accept_mutex on # 默認是off關閉的,這裏推薦打開
指定虛擬主機域名。
server_name name1 name2 name3 # 示例: server_name www.nginx.com;
域名匹配的四種寫法:
精確匹配:server_name www.nginx.com ; 左側通配:server_name *.nginx.com ; 右側統配:server_name www.nginx.* ; 正則匹配:server_name ~^www\.nginx\.*$ ; 匹配優先級:精確匹配 > 左側通配符匹配 > 右側通配符匹配 > 正則表達式匹配
一、配置本地 DNS 解析 vim /etc/hosts ( macOS 系統)
# 添加以下內容,其中 121.42.11.34 是阿里雲服務器IP地址 121.42.11.34 www.nginx-test.com 121.42.11.34 mail.nginx-test.com 121.42.11.34 www.nginx-test.org 121.42.11.34 doc.nginx-test.com 121.42.11.34 www.nginx-test.cn 121.42.11.34 fe.nginx-test.club
[注意] 這裏使用的是虛擬域名進行測試,所以須要配置本地 DNS 解析,若是使用阿里雲上購買的域名,則須要在阿里雲上設置好域名解析。
二、配置阿里雲 Nginx ,vim /etc/nginx/nginx.conf
# 這裏只列舉了http端中的sever端配置 # 左匹配 server { listen 80; server_name *.nginx-test.com; root /usr/share/nginx/html/nginx-test/left-match/; location / { index index.html; } } # 正則匹配 server { listen 80; server_name ~^.*\.nginx-test\..*$; root /usr/share/nginx/html/nginx-test/reg-match/; location / { index index.html; } } # 右匹配 server { listen 80; server_name www.nginx-test.*; root /usr/share/nginx/html/nginx-test/right-match/; location / { index index.html; } } # 徹底匹配 server { listen 80; server_name www.nginx-test.com; root /usr/share/nginx/html/nginx-test/all-match/; location / { index index.html; } }
三、訪問分析
當訪問 www.nginx-test.com 時,均可以被匹配上,所以選擇優先級最高的「徹底匹配」; 當訪問 mail.nginx-test.com 時,會進行「左匹配」; 當訪問 www.nginx-test.org 時,會進行「右匹配」; 當訪問 doc.nginx-test.com 時,會進行「左匹配」; 當訪問 www.nginx-test.cn 時,會進行「右匹配」; 當訪問 fe.nginx-test.club 時,會進行「正則匹配」;
指定靜態資源目錄位置,它能夠寫在 http 、 server 、 location 等配置中。
root path
例如:
location /image { root /opt/nginx/static; }
當用戶訪問 www.test.com/image/1.png 時,實際在服務器找的路徑是 /opt/nginx/static/image/1.png
[注意] root 會將定義路徑與 URI 疊加, alias 則只取定義路徑。
它也是指定靜態資源目錄位置,它只能寫在 location 中。
location /image { alias /opt/nginx/static/image/; }
當用戶訪問 www.test.com/image/1.png 時,實際在服務器找的路徑是 /opt/nginx/static/image/1.png
[注意] 使用 alias 末尾必定要添加 / ,而且它只能位於 location 中。
配置路徑。
location [ = | ~ | ~* | ^~ ] uri { ... }
匹配規則:
= 精確匹配; ~ 正則匹配,區分大小寫; ~* 正則匹配,不區分大小寫; ^~ 匹配到即中止搜索; 匹配優先級: = > ^~ > ~ > ~* > 不帶任何字符。
實例:
server { listen 80; server_name www.nginx-test.com; # 只有當訪問 www.nginx-test.com/match_all/ 時纔會匹配到/usr/share/nginx/html/match_all/index.html location = /match_all/ { root /usr/share/nginx/html index index.html } # 當訪問 www.nginx-test.com/1.jpg 等路徑時會去 /usr/share/nginx/images/1.jpg 找對應的資源 location ~ \.(jpeg|jpg|png|svg)$ { root /usr/share/nginx/images; } # 當訪問 www.nginx-test.com/bbs/ 時會匹配上 /usr/share/nginx/html/bbs/index.html location ^~ /bbs/ { root /usr/share/nginx/html; index index.html index.htm; } } location 中的反斜線 location /test { ... } location /test/ { ... }
中止處理請求,直接返回響應碼或重定向到其餘 URL ;執行 return 指令後, location 中後續指令將不會被執行。
return code [text]; return code URL; return URL;
例如:
location / { return 404; # 直接返回狀態碼 } location / { return 404 "pages not found"; # 返回狀態碼 + 一段文本 } location / { return 302 /bbs ; # 返回狀態碼 + 重定向地址 } location / { return https://www.baidu.com ; # 返回重定向地址 }
根據指定正則表達式匹配規則,重寫 URL 。
語法:rewrite 正則表達式 要替換的內容 [flag];上下文:server、location、if
示例:rewirte /images/(._.jpg)1; # $1是前面括號(._.jpg)的反向引用
flag 可選值的含義:
server{ listen 80; server_name fe.lion.club; # 要在本地hosts文件進行配置 root html; location /search { rewrite ^/(.*) https://www.baidu.com redirect; } location /images { rewrite /images/(.*) /pics/$1; } location /pics { rewrite /pics/(.*) /photos/$1; } location /photos { } }
按照這個配置咱們來分析:
語法:if (condition) {...} 上下文:server、location
示例:
if($http_user_agent ~ Chrome){ rewrite /(.*)/browser/$1 break; }
condition 判斷條件:
$variable 僅爲變量時,值爲空或以0開頭字符串都會被當作 false 處理; = 或 != 相等或不等; ~ 正則匹配; ! ~ 非正則匹配; ~* 正則匹配,不區分大小寫; -f 或 ! -f 檢測文件存在或不存在; -d 或 ! -d 檢測目錄存在或不存在; -e 或 ! -e 檢測文件、目錄、符號連接等存在或不存在; -x 或 ! -x 檢測文件能夠執行或不可執行;
實例:
server { listen 8080; server_name localhost; root html; location / { if ( $uri = "/images/" ){ rewrite (.*) /pics/ break; } } }
當訪問 localhost:8080/images/ 時,會進入 if 判斷裏面執行 rewrite 命令。
用戶請求以 / 結尾時,列出目錄結構,能夠用於快速搭建靜態資源下載網站。
autoindex.conf 配置信息:
server { listen 80; server_name fe.lion-test.club; location /download/ { root /opt/source; autoindex on; # 打開 autoindex,,可選參數有 on | off autoindex_exact_size on; # 修改成off,以KB、MB、GB顯示文件大小,默認爲on,以bytes顯示出⽂件的確切⼤⼩ autoindex_format html; # 以html的方式進行格式化,可選參數有 html | json | xml autoindex_localtime off; # 顯示的⽂件時間爲⽂件的服務器時間。默認爲off,顯示的⽂件時間爲GMT時間 } }
當訪問 fe.lion.com/download/ 時,會把服務器 /opt/source/download/ 路徑下的文件展現出來,以下圖所示:
Nginx 提供給使用者的變量很是多,可是終究是一個完整的請求過程所產生數據, Nginx 將這些數據以變量的形式提供給使用者。
下面列舉些項目中經常使用的變量:
remote_addr #客戶端 IP 地址 remote_port #客戶端端口 server_addr #服務端 IP 地址 server_port #服務端端口 server_protocol #服務端協議 binary_remote_addr #二進制格式的客戶端 IP 地址 connection #TCP 鏈接的序號,遞增 connection_request #TCP 鏈接當前的請求數量 uri #請求的URL,不包含參數 request_uri #請求的URL,包含參數 scheme #協議名, http 或 https request_method #請求方法 request_length #所有請求的長度,包含請求行、請求頭、請求體 args #所有參數字符串 arg_參數名 #獲取特定參數值 is_args #URL 中是否有參數,有的話返回 ? ,不然返回空 query_string #與 args 相同 host #請求信息中的 Host ,若是請求中沒有 Host 行,則在請求頭中找,最後使用 nginx 中設置的 server_name 。 http_user_agent #用戶瀏覽器 http_referer #從哪些連接過來的請求 http_via #每通過一層代理服務器,都會添加相應的信息 http_cookie #獲取用戶 cookie request_time #處理請求已消耗的時間 https #是否開啓了 https ,是則返回 on ,不然返回空 request_filename #磁盤文件系統待訪問文件的完整路徑 document_root #由 URI 和 root/alias 規則生成的文件夾路徑 limit_rate #返回響應時的速度上限值
實例演示 var.conf :
server{ listen 8081; server_name var.lion-test.club; root /usr/share/nginx/html; location / { return 200 " remote_addr: $remote_addr remote_port: $remote_port server_addr: $server_addr server_port: $server_port server_protocol: $server_protocol binary_remote_addr: $binary_remote_addr connection: $connection uri: $uri request_uri: $request_uri scheme: $scheme request_method: $request_method request_length: $request_length args: $args arg_pid: $arg_pid is_args: $is_args query_string: $query_string host: $host http_user_agent: $http_user_agent http_referer: $http_referer http_via: $http_via request_time: $request_time https: $https request_filename: $request_filename document_root: $document_root "; } }
當咱們訪問 http://var.lion-test.club:808... 時,因爲 Nginx 中寫了 return 方法,所以 chrome 瀏覽器會默認爲咱們下載一個文件,下面展現的就是下載的文件內容:
remote_addr: 27.16.220.84 remote_port: 56838 server_addr: 172.17.0.2 server_port: 8081 server_protocol: HTTP/1.1 binary_remote_addr: connection: 126 uri: /test/ request_uri: /test/?pid=121414&cid=sadasd scheme: http request_method: GET request_length: 518 args: pid=121414&cid=sadasd arg_pid: 121414 is_args: ? query_string: pid=121414&cid=sadasd host: var.lion-test.club http_user_agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.182 Safari/537.36 http_referer: http_via: request_time: 0.000 https: request_filename: /usr/share/nginx/html/test/ document_root: /usr/share/nginx/html
Nginx 的配置還有很是多,以上只是羅列了一些經常使用的配置,在實際項目中仍是要學會查閱文檔。
代理是在服務器和客戶端之間假設的一層服務器,代理將接收客戶端的請求並將它轉發給服務器,而後將服務端的響應轉發給客戶端。
無論是正向代理仍是反向代理,實現的都是上面的功能。
正向代理,意思是一個位於客戶端和原始服務器(origin server)之間的服務器,爲了從原始服務器取得內容,客戶端向代理髮送一個請求並指定目標(原始服務器),而後代理向原始服務器轉交請求並將得到的內容返回給客戶端。
正向代理是爲咱們服務的,即爲客戶端服務的,客戶端能夠根據正向代理訪問到它自己沒法訪問到的服務器資源。
正向代理對咱們是透明的,對服務端是非透明的,即服務端並不知道本身收到的是來自代理的訪問仍是來自真實客戶端的訪問。
反向代理(Reverse Proxy)方式是指以代理服務器來接受internet上的鏈接請求,而後將請求轉發給內部網絡上的服務器,並將從服務器上獲得的結果返回給internet上請求鏈接的客戶端,此時代理服務器對外就表現爲一個反向代理服務器。反向代理是爲服務端服務的,反向代理能夠幫助服務器接收來自客戶端的請求,幫助服務器作請求轉發,負載均衡等。
反向代理對服務端是透明的,對咱們是非透明的,即咱們並不知道本身訪問的是代理服務器,而服務器知道反向代理在爲他服務。
反向代理的優點:
那麼「動靜分離」是什麼?負載均衡又是什麼?
動靜分離是指在 web 服務器架構中,將靜態頁面與動態頁面或者靜態內容接口和動態內容接口分開不一樣系統訪問的架構設計方法,進而提示整個服務的訪問性和可維護性。
通常來講,都須要將動態資源和靜態資源分開,因爲 Nginx 的高併發和靜態資源緩存等特性,常常將靜態資源部署在 Nginx 上。若是請求的是靜態資源,直接到靜態資源目錄獲取資源,若是是動態資源的請求,則利用反向代理的原理,把請求轉發給對應後臺應用去處理,從而實現動靜分離。
使用先後端分離後,能夠很大程度提高靜態資源的訪問速度,即便動態服務不可用,靜態資源的訪問也不會受到影響。
通常狀況下,客戶端發送多個請求到服務器,服務器處理請求,其中一部分可能要操做一些資源好比數據庫、靜態資源等,服務器處理完畢後,再將結果返回給客戶端。
這種模式對於早期的系統來講,功能要求不復雜,且併發請求相對較少的狀況下還能勝任,成本也低。隨着信息數量不斷增加,訪問量和數據量飛速增加,以及系統業務複雜度持續增長,這種作法已沒法知足要求,併發量特別大時,服務器容易崩。
很明顯這是因爲服務器性能的瓶頸形成的問題,除了堆機器以外,最重要的作法就是負載均衡。
請求爆發式增加的狀況下,單個機器性能再強勁也沒法知足要求了,這個時候集羣的概念產生了,單個服務器解決不了的問題,可使用多個服務器,而後將請求分發到各個服務器上,將負載分發到不一樣的服務器,這就是負載均衡,核心是「分攤壓力」。Nginx 實現負載均衡,通常來講指的是將請求轉發給服務器集羣。
舉個具體的例子,晚高峯乘坐地鐵的時候,入站口常常會有地鐵工做人員大喇叭「請走 B 口, B 口人少車空....」,這個工做人員的做用就是負載均衡。
在配置反向代理和負載均衡等等功能以前,有兩個核心模塊是咱們必需要掌握的,這兩個模塊應該說是 Nginx 應用配置中的核心,它們分別是:upstream 、proxy_pass 。
用於定義上游服務器(指的就是後臺提供的應用服務器)的相關信息。
語法:upstream name { ...} 上下文:http
示例:
upstream back_end_server{ server 192.168.100.33:8081 }
在 upstream 內可以使用的指令:
定義上游服務器地址。
語法:server address [parameters]上下文:upstream
parameters 可選值:
限制每一個 worker 子進程與上游服務器空閒長鏈接的最大數量。
keepalive connections; 上下文:upstream
示例:[keepalive](http://mp.weixin.qq.com/s?__b...
485067&idx=1&sn=d5585b021802dfa47fb9cd8e01ddfb1d&chksm=e91b639
7de6cea81179917290cde1ff505291cee65f08d78f6a48fee90425db7e19b025fa683&scene=21#wechat_redirect) 16;
單個長鏈接能夠處理的最多 HTTP 請求個數。
語法:keepalive_requests number; 默認值:keepalive_requests 100; 上下文:upstream
空閒長鏈接的最長保持時間。
語法:keepalive_timeout time; 默認值:keepalive_timeout 60s; 上下文:upstream
upstream back_end{ server 127.0.0.1:8081 weight=3 max_conns=1000 fail_timeout=10s max_fails=2; keepalive 32; keepalive_requests 50; keepalive_timeout 30s;}
用於配置代理服務器。
語法:proxy_pass URL;上下文:location、if、limit_except
示例:
proxy_pass http://127.0.0.1:8081 proxy_pass http://127.0.0.1:8081/proxy
URL 參數原則
接下來讓咱們來看看兩種常見的 URL 用法:
這兩種用法的區別就是帶 / 和不帶 / ,在配置代理時它們的區別可大了:
不帶 / 的用法:
location /bbs/{ proxy_pass http://127.0.0.1:8080;}
分析:
帶 / 的用法:
location /bbs/{ proxy_pass http://127.0.0.1:8080/;}
分析:
這裏爲了演示更加接近實際,做者準備了兩臺雲服務器,它們的公網 IP 分別是:121.42.11.34 與 121.5.180.193 。
咱們把 121.42.11.34 服務器做爲上游服務器,作以下配置:
# /etc/nginx/conf.d/proxy.conf server{ listen 8080; server_name localhost; location /proxy/ { root /usr/share/nginx/html/proxy; index index.html; } } # /usr/share/nginx/html/proxy/index.html <h1> 121.42.11.34 proxy html </h1>
配置完成後重啓 Nginx 服務器 nginx -s reload 。
把 121.5.180.193 服務器做爲代理服務器,作以下配置:
# /etc/nginx/conf.d/proxy.conf upstream back_end { server 121.42.11.34:8080 weight=2 max_conns=1000 fail_timeout=10s max_fails=3; keepalive 32; keepalive_requests 80; keepalive_timeout 20s; } server { listen 80; server_name proxy.lion.club; location /proxy { proxy_pass http://back_end/proxy; } }
本地機器要訪問 proxy.lion.club 域名,所以須要配置本地 hosts ,經過命令:vim /etc/hosts 進入配置文件,添加以下內容:
121.5.180.193 proxy.lion.club
分析:
配置負載均衡主要是要使用 upstream 指令。
咱們把 121.42.11.34 服務器做爲上游服務器,作以下配置( /etc/nginx/conf.d/balance.conf ):
server{ listen 8020; location / { return 200 'return 8020 \nserver{ listen 8020; location / { return 200 'return 8020 \n'; } } server{ listen 8030; location / { return 200 'return 8030 \n'; } } server{ listen 8040; location / { return 200 'return 8040 \n'; } }
配置完成後:
把 121.5.180.193 服務器做爲代理服務器,作以下配置( /etc/nginx/conf.d/balance.conf ):
upstream demo_server { server 121.42.11.34:8020; server 121.42.11.34:8030; server 121.42.11.34:8040; } server { listen 80; server_name balance.lion.club; location /balance/ { proxy_pass http://demo_server; } }
配置完成後重啓 Nginx 服務器。而且在須要訪問的客戶端配置好 ip 和域名的映射關係。
# /etc/hosts121.5.180.193 balance.lion.club
在客戶端機器執行 curl http://balance.lion.club/bala... 命令:
不難看出,負載均衡的配置已經生效了,每次給咱們分發的上游服務器都不同。就是經過簡單的輪詢策略進行上游服務器分發。
接下來,咱們再來了解下 Nginx 的其它分發策略。
經過制定關鍵字做爲 hash key ,基於 hash 算法映射到特定的上游服務器中。關鍵字能夠包含有變量、字符串。
upstream demo_server { hash $request_uri; server 121.42.11.34:8020; server 121.42.11.34:8030; server 121.42.11.34:8040; server { listen 80; server_name balance.lion.club; location /balance/ { proxy_pass http://demo_server; } }
hash $request\_uri 表示使用 request_uri 變量做爲 hash 的 key 值,只要訪問的 URI 保持不變,就會一直分發給同一臺服務器。
根據客戶端的請求 ip 進行判斷,只要 ip 地址不變就永遠分配到同一臺主機。它能夠有效解決後臺服務器 session 保持的問題。
upstream demo_server { ip_hash; server 121.42.11.34:8020; server 121.42.11.34:8030; server 121.42.11.34:8040; } server { listen 80; server_name balance.lion.club; location /balance/ { proxy_pass http://demo_server; } }
各個 worker 子進程經過讀取共享內存的數據,來獲取後端服務器的信息。來挑選一臺當前已創建鏈接數最少的服務器進行分配請求。
語法:least_conn;上下文:upstream;
示例:
upstream demo_server { zone test 10M; # zone能夠設置共享內存空間的名字和大小 least_conn; server 121.42.11.34:8020; server 121.42.11.34:8030; server 121.42.11.34:8040; } server { listen 80; server_nme balance.lion.club; location /balance/ { proxy_pass http://demo_server; } }
最後你會發現,負載均衡的配置其實一點都不復雜。
緩存能夠很是有效的提高性能,所以不管是客戶端(瀏覽器),仍是代理服務器( Nginx ),乃至上游服務器都多少會涉及到緩存。可見緩存在每一個環節都是很是重要的。下面讓咱們來學習 Nginx 中如何設置緩存策略。
存儲一些以前被訪問過、並且可能將要被再次訪問的資源,使用戶能夠直接從代理服務器得到,從而減小上游服務器的壓力,加快整個訪問速度。
語法:proxy_cache zone | off ; # zone 是共享內存的名稱默認值:proxy_cache off;上下文:http、server、location
設置緩存文件的存放路徑。
語法:proxy_cache_path path [level=levels] ...可選參數省略,下面會詳細列舉默認值:proxy_cache_path off上下文:http
參數含義:
設置緩存文件的 key 。
語法:proxy_cache_key 默認值:proxy_cache_key $scheme$proxy_host$request_uri; 上下文:http、server、location
配置什麼狀態碼能夠被緩存,以及緩存時長。
語法:proxy_cache_valid [code...] time; 上下文:http、server、location
配置
proxy_cache_valid 200 304 2m;; # 說明對於狀態爲200和304的緩存文件的緩存時間是2分鐘
定義相應保存到緩存的條件,若是字符串參數的至少一個值不爲空且不等於「 0」,則將不保存該響應到緩存。
語法:proxy_no_cache string; 上下文:http、server、location 示例: proxy_no_cache $http_pragma $http_authorization;
定義條件,在該條件下將不會從緩存中獲取響應。
語法:proxy_cache_bypass string; 上下文:http、server、location
示例:
proxy_cache_bypass $http_pragma $http_authorization;
它存儲了緩存是否命中的信息,會設置在響應頭信息中,在調試中很是有用。
MISS: 未命中緩存HIT: 命中緩存EXPIRED: 緩存過時STALE: 命中了陳舊緩存REVALIDDATED: Nginx驗證陳舊緩存依然有效UPDATING: 內容陳舊,但正在更新BYPASS: X響應從原始服務器獲取
咱們把 121.42.11.34 服務器做爲上游服務器,作以下配置( /etc/nginx/conf.d/cache.conf ):
server { listen 1010; root /usr/share/nginx/html/1010; location / { index index.html; } } server { listen 1020; root /usr/share/nginx/html/1020; location / { index index.html; } }
把 121.5.180.193 服務器做爲代理服務器,作以下配置( /etc/nginx/conf.d/cache.conf ):
proxy_cache_path /etc/nginx/cache_temp levels=2:2 keys_zone=cache_zone:30m max_size=2g inactive=60m use_temp_path=off; upstream cache_server{ server 121.42.11.34:1010; server 121.42.11.34:1020; } server { listen 80; server_name cache.lion.club; location / { proxy_cache cache_zone; # 設置緩存內存,上面配置中已經定義好的 proxy_cache_valid 200 5m; # 緩存狀態爲200的請求,緩存時長爲5分鐘 proxy_cache_key $request_uri; # 緩存文件的key爲請求的URI add_header Nginx-Cache-Status $upstream_cache_status # 把緩存狀態設置爲頭部信息,響應給客戶端 proxy_pass http://cache_server; # 代理轉發 } }
緩存就是這樣配置,咱們能夠在 /etc/nginx/cache\_temp 路徑下找到相應的緩存文件。
對於一些實時性要求很是高的頁面或數據來講,就不該該去設置緩存,下面來看看如何配置不緩存的內容。
... server { listen 80; server_name cache.lion.club; # URI 中後綴爲 .txt 或 .text 的設置變量值爲 "no cache" if ($request_uri ~ \.(txt|text)$) { set $cache_name "no cache" } location / { proxy_no_cache $cache_name; # 判斷該變量是否有值,若是有值則不進行緩存,若是沒有值則進行緩存 proxy_cache cache_zone; # 設置緩存內存 proxy_cache_valid 200 5m; # 緩存狀態爲200的請求,緩存時長爲5分鐘 proxy_cache_key $request_uri; # 緩存文件的key爲請求的URI add_header Nginx-Cache-Status $upstream_cache_status # 把緩存狀態設置爲頭部信息,響應給客戶端 proxy_pass http://cache_server; # 代理轉發 } }
在學習如何配置 HTTPS 以前,咱們先來簡單回顧下 HTTPS 的工做流程是怎麼樣的?它是如何進行加密保證安全的?
下載證書的壓縮文件,裏面有個 Nginx 文件夾,把 xxx.crt 和 xxx.key 文件拷貝到服務器目錄,再進行以下配置:
server { listen 443 ssl http2 default_server; # SSL 訪問端口號爲 443 server_name lion.club; # 填寫綁定證書的域名(我這裏是隨便寫的) ssl_certificate /etc/nginx/https/lion.club_bundle.crt; # 證書地址 ssl_certificate_key /etc/nginx/https/lion.club.key; # 私鑰地址 ssl_session_timeout 10m; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # 支持ssl協議版本,默認爲後三個,主流版本是[TLSv1.2] location / { root /usr/share/nginx/html; index index.html index.htm; } }
如此配置後就能正常訪問 HTTPS 版的網站了。
先簡單回顧下跨域到底是怎麼回事。
同源策略限制了從同一個源加載的文檔或腳本如何與來自另外一個源的資源進行交互。這是一個用於隔離潛在惡意文件的重要安全機制。一般不容許不一樣源間的讀操做。
若是兩個頁面的協議,端口(若是有指定)和域名都相同,則兩個頁面具備相同的源。
下面給出了與 URL http://store.company.com/dir/... 的源進行對比的示例:
http://store.company.com/dir2/other.html 同源https://store.company.com/secure.html 不一樣源,協議不一樣http://store.company.com:81/dir/etc.html 不一樣源,端口不一樣http://news.company.com/dir/other.html 不一樣源,主機不一樣
不一樣源會有以下限制:
例如:
如今咱們只須要啓動一個 Nginx 服務器,將 server\_name 設置爲 fe.server.com 而後設置相應的 location 以攔截前端須要跨域的請求,最後將請求代理回 dev.server.com 。以下面的配置:
server { listen 80; server_name fe.server.com; location / { proxy_pass dev.server.com; } }
這樣能夠完美繞過瀏覽器的同源策略:fe.server.com 訪問 Nginx 的 fe.server.com 屬於同源訪問,而 Nginx 對服務端轉發的請求不會觸發瀏覽器的同源策略。
GZIP 是規定的三種標準 HTTP 壓縮格式之一。目前絕大多數的網站都在使用 GZIP 傳輸 HTML 、CSS 、 JavaScript 等資源文件。
對於文本文件, GZiP 的效果很是明顯,開啓後傳輸所需流量大約會降至 1/4~1/3 。
並非每一個瀏覽器都支持 gzip 的,如何知道客戶端是否支持 gzip 呢,請求頭中的 Accept-Encoding 來標識對壓縮的支持。
啓用 gzip 同時須要客戶端和服務端的支持,若是客戶端支持 gzip 的解析,那麼只要服務端可以返回 gzip 的文件就能夠啓用 gzip 了,咱們能夠經過 Nginx 的配置來讓服務端支持 gzip 。下面的 respone 中 content-encoding:gzip ,指服務端開啓了 gzip 的壓縮方式。
在 /etc/nginx/conf.d/ 文件夾中新建配置文件 gzip.conf :
# # 默認off,是否開啓gzip gzip on; # 要採用 gzip 壓縮的 MIME 文件類型,其中 text/html 被系統強制啓用; gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript; # ---- 以上兩個參數開啓就能夠支持Gzip壓縮了 ---- # # 默認 off,該模塊啓用後,Nginx 首先檢查是否存在請求靜態文件的 gz 結尾的文件,若是有則直接返回該 .gz 文件內容; gzip_static on; # 默認 off,nginx作爲反向代理時啓用,用於設置啓用或禁用從代理服務器上收到相應內容 gzip 壓縮; gzip_proxied any; # 用於在響應消息頭中添加 Vary:Accept-Encoding,使代理服務器根據請求頭中的 Accept-Encoding 識別是否啓用 gzip 壓縮; gzip_vary on; # gzip 壓縮比,壓縮級別是 1-9,1 壓縮級別最低,9 最高,級別越高壓縮率越大,壓縮時間越長,建議 4-6; gzip_comp_level 6; # 獲取多少內存用於緩存壓縮結果,16 8k 表示以 8k*16 爲單位得到; gzip_buffers 16 8k; # 容許壓縮的頁面最小字節數,頁面字節數從header頭中的 Content-Length 中進行獲取。默認值是 0,無論頁面多大都壓縮。建議設置成大於 1k 的字節數,小於 1k 可能會越壓越大; # gzip_min_length 1k; # 默認 1.1,啓用 gzip 所需的 HTTP 最低版本; gzip_http_version 1.1;
其實也能夠經過前端構建工具例如 webpack 、rollup 等在打生產包時就作好 Gzip 壓縮,而後放到 Nginx 服務器中,這樣能夠減小服務器的開銷,加快訪問速度。
關於 Nginx 的實際應用就學習到這裏,相信經過掌握了 Nginx 核心配置以及實戰配置,以後再遇到什麼需求,咱們也能輕鬆應對。接下來,讓咱們再深刻一點學習下 Nginx 的架構。
多進程結構 Nginx 的進程模型圖:
多進程中的 Nginx 進程架構以下圖所示,會有一個父進程( Master Process ),它會有不少子進程( Child Processes )。
reload 重載配置文件的流程:
Nginx 的內部結構是由核心部分和一系列的功能模塊所組成。這樣劃分是爲了使得每一個模塊的功能相對簡單,便於開發,同時也便於對系統進行功能擴展。Nginx 的模塊是互相獨立的,低耦合高內聚。
相信經過本文的學習,你應該會對 Nginx 有一個更加全面的認識。
都看到這裏了,點在看、留言、轉發朋友圈走一波吧!!
來源: https://juejin.cn/post/694260...