<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          全面了解 Nginx

          共 36520字,需瀏覽 74分鐘

           ·

          2021-05-27 12:31

          作者:Lion

          https://juejin.cn/post/6942607113118023710


          Nginx 概述


          Nginx 是開源、高性能、高可靠的 Web 和反向代理服務(wù)器,而且支持熱部署,幾乎可以做到 7 * 24 小時不間斷運行,即使運行幾個月也不需要重新啟動,還能在不間斷服務(wù)的情況下對軟件版本進行熱更新。性能是 Nginx 最重要的考量,其占用內(nèi)存少、并發(fā)能力強、能支持高達 5w 個并發(fā)連接數(shù),最重要的是, Nginx 是免費的并可以商業(yè)化,配置使用也比較簡單。


          Nginx 特點


          • 高并發(fā)、高性能;

          • 模塊化架構(gòu)使得它的擴展性非常好;

          • 異步非阻塞的事件驅(qū)動模型這點和 Node.js 相似;

          • 相對于其它服務(wù)器來說它可以連續(xù)幾個月甚至更長而不需要重啟服務(wù)器使得它具有高可靠性;

          • 熱部署、平滑升級;

          • 完全開源,生態(tài)繁榮。


          Nginx 作用


          Nginx 的最重要的幾個使用場景:

          • 靜態(tài)資源服務(wù),通過本地文件系統(tǒng)提供服務(wù);

          • 反向代理服務(wù),延伸出包括緩存、負(fù)載均衡等;

          • API 服務(wù),OpenResty;


          對于前端來說 Node.js 并不陌生,Nginx 和 Node.js 的很多理念類似,HTTP 服務(wù)器、事件驅(qū)動、異步非阻塞等,且 Nginx 的大部分功能使用 Node.js 也可以實現(xiàn),但 Nginx 和 Node.js 并不沖突,都有自己擅長的領(lǐng)域。Nginx 擅長于底層服務(wù)器端資源的處理(靜態(tài)資源處理轉(zhuǎn)發(fā)、反向代理,負(fù)載均衡等),Node.js 更擅長上層具體業(yè)務(wù)邏輯的處理,兩者可以完美組合。

          用一張圖表示:


          Nginx 安裝


          本文演示的是 Linux CentOS 7.x 的操作系統(tǒng)上安裝 Nginx,至于在其它操作系統(tǒng)上進行安裝可以網(wǎng)上自行搜索,都非常簡單的。

          使用 yum 安裝 Nginx:

          yum install nginx -y

          安裝完成后,通過 rpm -ql nginx 命令查看 Nginx 的安裝信息:

          # Nginx 配置文件
          /etc/nginx/nginx.conf # Nginx 主配置文件
          /etc/nginx/nginx.conf.default

          # 可執(zhí)行程序文件
          /usr/bin/nginx-upgrade
          /usr/sbin/nginx

          # Nginx 庫文件
          /usr/lib/systemd/system/nginx.service # 用于配置系統(tǒng)守護進程
          /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

          # 靜態(tài)資源目錄
          /usr/share/nginx/html/404.html
          /usr/share/nginx/html/50x.html
          /usr/share/nginx/html/index.html

          # 存放 Nginx 日志文件
          /var/log/nginx

          主要關(guān)注的文件夾有兩個:

          • /etc/nginx/conf.d/ 是子配置項存放處,/etc/nginx/nginx.conf 主配置文件會默認(rèn)把這個文件夾中所有子配置項都引入;

          • /usr/share/nginx/html/ 靜態(tài)文件都放在這個文件夾,也可以根據(jù)你自己的習(xí)慣放在其他地方。


          Nginx 常用命令


          systemctl 系統(tǒng)命令:

          # 開機配置
          systemctl enable nginx # 開機自動啟動
          systemctl disable nginx # 關(guān)閉開機自動啟動

          # 啟動 Nginx
          systemctl start nginx # 啟動Nginx成功后,可以直接訪問主機IP,此時會展示Nginx默認(rèn)頁面

          # 停止 Nginx
          systemctl stop nginx

          # 重啟 Nginx
          systemctl restart nginx

          # 重新加載 Nginx
          systemctl reload nginx

           # 查看 Nginx 運行狀態(tài)
          systemctl status nginx

          # 查看 Nginx 進程
          ps -ef | grep nginx

          # 殺死 Nginx 進程
          kill -9 pid # 根據(jù)上面查看到的 Nginx 進程號,殺死 Nginx 進程,-9 表示強制結(jié)束進程

          Nginx 應(yīng)用程序命令:

          nginx -s reload  # 向主進程發(fā)送信號,重新加載配置文件,熱重啟
          nginx -s reopen  # 重啟 Nginx
          nginx -s stop    # 快速關(guān)閉
          nginx -s quit    # 等待工作進程處理完成后關(guān)閉
          nginx -T         # 查看當(dāng)前 Nginx 最終的配置
          nginx -t         # 檢查配置是否有問題


          Nginx 核心配置


          配置文件結(jié)構(gòu)

          Nginx 的典型配置示例:

          # main 段配置信息
          user  nginx;                        # 運行用戶,默認(rèn)即是 Nginx,可以不進行設(shè)置
          worker_processes  auto;             # Nginx 進程數(shù),一般設(shè)置為和 CPU 核數(shù)一樣
          error_log  /var/log/nginx/error.log warn;   # Nginx 的錯誤日志存放目錄
          pid        /var/run/nginx.pid;      # Nginx 服務(wù)啟動時的 pid 存放位置

          # events 段配置信息
          events {
              use epoll;     # 使用 epoll 的 I/O 模型(如果你不知道 Nginx 該使用哪種輪詢方法,會自動選擇一個最適合你操作系統(tǒng)的)
              worker_connections 1024;   # 每個進程允許最大并發(fā)數(shù)
          }

          # http 段配置信息
          # 配置使用最頻繁的部分,代理、緩存、日志定義等絕大多數(shù)功能和第三方模塊的配置都在這里設(shè)置
          http { 
              # 設(shè)置日志模式
              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;   # 減少網(wǎng)絡(luò)報文段的數(shù)量
              tcp_nodelay         on;
              keepalive_timeout   65;   # 保持連接的時間,也叫超時時間,單位秒
              types_hash_max_size 2048;

              include             /etc/nginx/mime.types;      # 文件擴展名與類型映射表
              default_type        application/octet-stream;   # 默認(rèn)文件類型

              include /etc/nginx/conf.d/*.conf;   # 加載子配置項
              
              # server段配置信息
              server {
               listen       80;       # 配置監(jiān)聽的端口
               server_name  localhost;    # 配置的域名
                
               # location段配置信息
               location / {
                root   /usr/share/nginx/html;  # 網(wǎng)站根目錄
                index  index.html index.htm;   # 默認(rèn)首頁文件
                deny 172.168.22.11;   # 禁止訪問的 ip 地址,可以為 all
                allow 172.168.33.44;# 允許訪問的 ip 地址,可以為 all
               }
               
               error_page 500 502 503 504 /50x.html;  # 默認(rèn) 50x 對應(yīng)的訪問頁面
               error_page 400 404 error.html;   # 同上
              }
          }


          • main 全局配置,對全局生效;

          • events 配置影響 Nginx 服務(wù)器與用戶的網(wǎng)絡(luò)連接;

          • http 配置代理,緩存,日志定義等絕大多數(shù)功能和第三方模塊的配置;

          • server 配置虛擬主機的相關(guān)參數(shù),一個 http 塊中可以有多個 server 塊;

          • location 用于配置匹配的 uri ;

          • upstream 配置后端服務(wù)器具體地址,負(fù)載均衡配置不可或缺的部分。


          用一張圖清晰的展示它的層級結(jié)構(gòu):


          配置文件 main 段核心參數(shù)

          user

          指定運行 Nginx 的 woker 子進程的屬主和屬組,其中組可以不指定。
          user USERNAME [GROUP]

          user nginx lion; # 用戶是 Nginx;組是 lion

          pid

          指定運行 Nginx master 主進程的 pid 文件存放路徑。

          pid /opt/nginx/logs/nginx.pid # master主進程的的 pid 存放在 nginx.pid 的文件


          worker_rlimit_nofile_number

          指定 worker 子進程可以打開的最大文件句柄數(shù)。

          worker_rlimit_nofile 20480; # 可以理解成每個 worker 子進程的最大連接數(shù)量。


          worker_rlimit_core

          指定 worker 子進程異常終止后的 core 文件,用于記錄分析問題。

          worker_rlimit_core 50M; # 存放大小限制
          working_directory /opt/nginx/tmp; # 存放目錄


          worker_processes_number

          指定 Nginx 啟動的 worker 子進程數(shù)量。

          worker_processes 4; # 指定具體子進程數(shù)量
          worker_processes auto; # 與當(dāng)前 CPU 物理核心數(shù)一致


          worker_cpu_affinity

          將每個 worker 子進程與我們的 CPU 物理核心綁定。

          worker_cpu_affinity 0001 0010 0100 1000; # 4個物理核心,4個 worker 子進程



          將每個 worker 子進程與特定 CPU 物理核心綁定,優(yōu)勢在于,避免同一個 worker 子進程在不同的 CPU 核心上切換,緩存失效,降低性能。但其并不能真正的避免進程切換。

          worker_priority

          指定 worker 子進程的 nice 值,以調(diào)整運行 Nginx 的優(yōu)先級,通常設(shè)定為負(fù)值,以優(yōu)先調(diào)用 Nginx 。

          worker_priority -10; # 120-10=110,110 就是最終的優(yōu)先級

          Linux 默認(rèn)進程的優(yōu)先級值是 120,值越小越優(yōu)先;nice 定范圍為 -20 到 +19 。

          [備注] 應(yīng)用的默認(rèn)優(yōu)先級值是 120 加上 nice 值等于它最終的值,這個值越小,優(yōu)先級越高。

          worker_shutdown_timeout

          指定 worker 子進程優(yōu)雅退出時的超時時間。

          worker_shutdown_timeout 5s;


          timer_resolution

          worker 子進程內(nèi)部使用的計時器精度,調(diào)整時間間隔越大,系統(tǒng)調(diào)用越少,有利于性能提升;反之,系統(tǒng)調(diào)用越多,性能下降。

          timer_resolution 100ms;

          在 Linux 系統(tǒng)中,用戶需要獲取計時器時需要向操作系統(tǒng)內(nèi)核發(fā)送請求,有請求就必然會有開銷,因此這個間隔越大開銷就越小。

          daemon

          指定 Nginx 的運行方式,前臺還是后臺,前臺用于調(diào)試,后臺用于生產(chǎn)。

          daemon off; # 默認(rèn)是 on,后臺運行模式


          配置文件 events 段核心參數(shù)

          use

          Nginx 使用何種事件驅(qū)動模型。

          use method; # 不推薦配置它,讓 Nginx 自己選擇

          method 可選值為:select、poll、kqueue、epoll、/dev/poll、eventport


          worker_connections

          worker 子進程能夠處理的最大并發(fā)連接數(shù)。
          worker_connections 1024 # 每個子進程的最大連接數(shù)為 1024

          accept_mutex

          是否打開負(fù)載均衡互斥鎖。

          accept_mutex on # 默認(rèn)是 off 關(guān)閉的,這里推薦打開


          server_name 指令

          指定虛擬主機域名。

          server_name name1 name2 name3

          # 示例:
          server_name www.nginx.com;

          域名匹配的四種寫法:

          • 精確匹配:server_name www.nginx.com ;

          • 左側(cè)通配:server_name *.nginx.com ;

          • 右側(cè)統(tǒng)配:server_name www.nginx.* ;

          • 正則匹配:server_name ~^www\.nginx\.*$ ;


          匹配優(yōu)先級:精確匹配 > 左側(cè)通配符匹配 > 右側(cè)通配符匹配 > 正則表達式匹配

          server_name 配置實例:

          1、配置本地 DNS 解析 vim /etc/hosts (macOS 系統(tǒng))
          # 添加如下內(nèi)容,其中 121.42.11.34 是阿里云服務(wù)器 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 解析,如果使用阿里云上購買的域名,則需要在阿里云上設(shè)置好域名解析。

          2、配置阿里云 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;
           }
          }

          3、訪問分析

          • 當(dāng)訪問 www.nginx-test.com 時,都可以被匹配上,因此選擇優(yōu)先級最高的“完全匹配”;

          • 當(dāng)訪問 mail.nginx-test.com 時,會進行“左匹配”;

          • 當(dāng)訪問 www.nginx-test.org 時,會進行“右匹配”;

          • 當(dāng)訪問 doc.nginx-test.com 時,會進行“左匹配”;

          • 當(dāng)訪問 www.nginx-test.cn 時,會進行“右匹配”;

          • 當(dāng)訪問 fe.nginx-test.club 時,會進行“正則匹配”;


          root

          指定靜態(tài)資源目錄位置,它可以寫在 http、server、location 等配置中。
          root path

          例如:
          location /image {
           root /opt/nginx/static;
          }

          當(dāng)用戶訪問 www.test.com/image/1.png 時,實際在服務(wù)器找的路徑是 /opt/nginx/static/image/1.png
          [注意] root 會將定義路徑與 URI 疊加,alias 則只取定義路徑。

          alias

          它也是指定靜態(tài)資源目錄位置,它只能寫在 location 中。

          location /image {
           alias /opt/nginx/static/image/;
          }

          當(dāng)用戶訪問 www.test.com/image/1.png 時,實際在服務(wù)器找的路徑是 /opt/nginx/static/image/1.png

          [注意] 使用 alias 末尾一定要添加 / ,并且它只能位于 location 中。

          location

          配置路徑。

          location [ = | ~ | ~* | ^~ ] uri {
           ...
          }

          匹配規(guī)則:

          • = 精確匹配;

          • ~ 正則匹配,區(qū)分大小寫;

          • ~* 正則匹配,不區(qū)分大小寫;

          • ^~ 匹配到即停止搜索;


          匹配優(yōu)先級:= > ^~ > ~ > ~* > 不帶任何字符。

          實例:

          server {
            listen 80;
            server_name www.nginx-test.com;
            
            # 只有當(dāng)訪問 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
            }
            
            # 當(dāng)訪問 www.nginx-test.com/1.jpg 等路徑時會去 /usr/share/nginx/images/1.jpg 找對應(yīng)的資源
            location ~ \.(jpeg|jpg|png|svg)$ {
             root /usr/share/nginx/images;
            }
            
            # 當(dāng)訪問 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/ {
           ...
          }


          • 不帶 / 當(dāng)訪問 www.nginx-test.com/test 時, Nginx 先找是否有 test 目錄,如果有則找 test 目錄下的 index.html;如果沒有 test 目錄,Nginx 則會找是否有 test 文件。

          • 帶 / 當(dāng)訪問 www.nginx-test.com/test 時,Nginx 先找是否有 test 目錄,如果有則找 test 目錄下的 index.html,如果沒有它也不會去找是否存在 test 文件。


          return

          停止處理請求,直接返回響應(yīng)碼或重定向到其他 URL ;執(zhí)行 return 指令后,location 中后續(xù)指令將不會被執(zhí)行。
          return code [text];
          return code URL;
          return URL;

          例如:
          location / {
           return 404; # 直接返回狀態(tài)碼
          }

          location / {
           return 404 "pages not found"# 返回狀態(tài)碼 + 一段文本
          }

          location / {
           return 302 /bbs ; # 返回狀態(tài)碼 + 重定向地址
          }

          location / {
           return https://www.baidu.com ; # 返回重定向地址
          }

          rewrite

          根據(jù)指定正則表達式匹配規(guī)則,重寫 URL。

          語法:rewrite 正則表達式 要替換的內(nèi)容 [flag];

          上下文:server、location、if

          示例:rewirte /images/(.*\.jpg)$ /pic/$1# $1是前面括號(.*\.jpg)的反向引用

          flag 可選值的含義:

          • last 重寫后的 URL 發(fā)起新請求,再次進入 server 段,重試 location 的中的匹配;

          • break 直接使用重寫后的 URL ,不再匹配其它 location 中語句;

          • redirect 返回 302 臨時重定向;

          • permanent 返回 301 永久重定向;


          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 {
            
            }
          }
          按照這個配置我們來分析:

          • 當(dāng)訪問 fe.lion.club/search 時,會自動幫我們重定向到 https://www.baidu.com。

          • 當(dāng)訪問 fe.lion.club/images/1.jpg 時,第一步重寫 URL 為 fe.lion.club/pics/1.jpg,找到 pics 的 location,繼續(xù)重寫 URL 為 fe.lion.club/photos/1.jpg,找到 /photos 的 location 后,去 html/photos 目錄下尋找 1.jpg 靜態(tài)資源。


          if 指令

          語法:if (condition) {...}

          上下文:server、location

          示例:
          if($http_user_agent ~ Chrome){
            rewrite /(.*)/browser/$1 break;
          }

          condition 判斷條件:

          • $variable 僅為變量時,值為空或以 0 開頭字符串都會被當(dāng)做 false 處理;

          • = 或 != 相等或不等;

          • ~ 正則匹配;

          • ! ~ 非正則匹配;

          • ~* 正則匹配,不區(qū)分大小寫;

          • -f 或 ! -f 檢測文件存在或不存在;

          • -d 或 ! -d 檢測目錄存在或不存在;

          • -e 或 ! -e 檢測文件、目錄、符號鏈接等存在或不存在;

          • -x 或 ! -x 檢測文件可以執(zhí)行或不可執(zhí)行;


          實例:

          server {
            listen 8080;
            server_name localhost;
            root html;
            
            location / {
             if ( $uri = "/images/" ){
               rewrite (.*) /pics/ break;
              }
            }
          }

          當(dāng)訪問 localhost:8080/images/ 時,會進入 if 判斷里面執(zhí)行 rewrite 命令。

          autoindex

          用戶請求以 / 結(jié)尾時,列出目錄結(jié)構(gòu),可以用于快速搭建靜態(tài)資源下載網(wǎng)站。
          autoindex.conf 配置信息:

          server {
            listen 80;
            server_name fe.lion-test.club;
            
            location /download/ {
              root /opt/source;
              
              autoindex on; # 打開 autoindex,,可選參數(shù)有 on | off
              autoindex_exact_size on; # 修改為 off,以 KB、MB、GB 顯示文件大小,默認(rèn)為 on,以 bytes 顯示出?件的確切??
              autoindex_format html; # 以 html 的方式進行格式化,可選參數(shù)有 html | json | xml
              autoindex_localtime off; # 顯示的?件時間為?件的服務(wù)器時間。默認(rèn)為 off,顯示的?件時間為GMT時間
            }
          }

          當(dāng)訪問 fe.lion.com/download/ 時,會把服務(wù)器 /opt/source/download/ 路徑下的文件展示出來,如下圖所示:


          變量

          Nginx 提供給使用者的變量非常多,但是終究是一個完整的請求過程所產(chǎn)生數(shù)據(jù), Nginx 將這些數(shù)據(jù)以變量的形式提供給使用者。

          下面列舉些項目中常用的變量:


          實例演示 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
          "
          ;
           }
          }

          當(dāng)我們訪問 http://var.lion-test.club:8081/test?pid=121414&amp;cid=sadasd 時,由于 Nginx 中寫了 return 方法,因此 chrome 瀏覽器會默認(rèn)為我們下載一個文件,下面展示的就是下載的文件內(nèi)容:
          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 的配置還有非常多,以上只是羅列了一些常用的配置,在實際項目中還是要學(xué)會查閱文檔。


          Nginx 應(yīng)用核心概念


          代理是在服務(wù)器和客戶端之間假設(shè)的一層服務(wù)器,代理將接收客戶端的請求并將它轉(zhuǎn)發(fā)給服務(wù)器,然后將服務(wù)端的響應(yīng)轉(zhuǎn)發(fā)給客戶端。

          不管是正向代理還是反向代理,實現(xiàn)的都是上面的功能。


          正向代理

          正向代理,意思是一個位于客戶端和原始服務(wù)器(origin server)之間的服務(wù)器,為了從原始服務(wù)器取得內(nèi)容,客戶端向代理發(fā)送一個請求并指定目標(biāo)(原始服務(wù)器),然后代理向原始服務(wù)器轉(zhuǎn)交請求并將獲得的內(nèi)容返回給客戶端。

          正向代理是為我們服務(wù)的,即為客戶端服務(wù)的,客戶端可以根據(jù)正向代理訪問到它本身無法訪問到的服務(wù)器資源。

          正向代理對我們是透明的,對服務(wù)端是非透明的,即服務(wù)端并不知道自己收到的是來自代理的訪問還是來自真實客戶端的訪問。

          反向代理

          反向代理(Reverse Proxy)方式是指以代理服務(wù)器來接受 internet 上的連接請求,然后將請求轉(zhuǎn)發(fā)給內(nèi)部網(wǎng)絡(luò)上的服務(wù)器,并將從服務(wù)器上得到的結(jié)果返回給 internet 上請求連接的客戶端,此時代理服務(wù)器對外就表現(xiàn)為一個反向代理服務(wù)器。

          反向代理是為服務(wù)端服務(wù)的,反向代理可以幫助服務(wù)器接收來自客戶端的請求,幫助服務(wù)器做請求轉(zhuǎn)發(fā),負(fù)載均衡等。

          反向代理對服務(wù)端是透明的,對我們是非透明的,即我們并不知道自己訪問的是代理服務(wù)器,而服務(wù)器知道反向代理在為他服務(wù)。

          反向代理的優(yōu)勢:

          • 隱藏真實服務(wù)器;

          • 負(fù)載均衡便于橫向擴充后端動態(tài)服務(wù);

          • 動靜分離,提升系統(tǒng)健壯性;


          那么“動靜分離”是什么?負(fù)載均衡又是什么?

          動靜分離

          動靜分離是指在 web 服務(wù)器架構(gòu)中,將靜態(tài)頁面與動態(tài)頁面或者靜態(tài)內(nèi)容接口和動態(tài)內(nèi)容接口分開不同系統(tǒng)訪問的架構(gòu)設(shè)計方法,進而提示整個服務(wù)的訪問性和可維護性。


          一般來說,都需要將動態(tài)資源和靜態(tài)資源分開,由于 Nginx 的高并發(fā)和靜態(tài)資源緩存等特性,經(jīng)常將靜態(tài)資源部署在 Nginx 上。如果請求的是靜態(tài)資源,直接到靜態(tài)資源目錄獲取資源,如果是動態(tài)資源的請求,則利用反向代理的原理,把請求轉(zhuǎn)發(fā)給對應(yīng)后臺應(yīng)用去處理,從而實現(xiàn)動靜分離。

          使用前后端分離后,可以很大程度提升靜態(tài)資源的訪問速度,即使動態(tài)服務(wù)不可用,靜態(tài)資源的訪問也不會受到影響。

          負(fù)載均衡

          一般情況下,客戶端發(fā)送多個請求到服務(wù)器,服務(wù)器處理請求,其中一部分可能要操作一些資源比如數(shù)據(jù)庫、靜態(tài)資源等,服務(wù)器處理完畢后,再將結(jié)果返回給客戶端。

          這種模式對于早期的系統(tǒng)來說,功能要求不復(fù)雜,且并發(fā)請求相對較少的情況下還能勝任,成本也低。隨著信息數(shù)量不斷增長,訪問量和數(shù)據(jù)量飛速增長,以及系統(tǒng)業(yè)務(wù)復(fù)雜度持續(xù)增加,這種做法已無法滿足要求,并發(fā)量特別大時,服務(wù)器容易崩。

          很明顯這是由于服務(wù)器性能的瓶頸造成的問題,除了堆機器之外,最重要的做法就是負(fù)載均衡。

          請求爆發(fā)式增長的情況下,單個機器性能再強勁也無法滿足要求了,這個時候集群的概念產(chǎn)生了,單個服務(wù)器解決不了的問題,可以使用多個服務(wù)器,然后將請求分發(fā)到各個服務(wù)器上,將負(fù)載分發(fā)到不同的服務(wù)器,這就是負(fù)載均衡,核心是「分?jǐn)倝毫Α埂ginx 實現(xiàn)負(fù)載均衡,一般來說指的是將請求轉(zhuǎn)發(fā)給服務(wù)器集群。

          舉個具體的例子,晚高峰乘坐地鐵的時候,入站口經(jīng)常會有地鐵工作人員大喇叭“請走 B 口, B 口人少車空……”,這個工作人員的作用就是負(fù)載均衡。


          Nginx 實現(xiàn)負(fù)載均衡的策略:

          • 輪詢策略:默認(rèn)情況下采用的策略,將所有客戶端請求輪詢分配給服務(wù)端。這種策略是可以正常工作的,但是如果其中某一臺服務(wù)器壓力太大,出現(xiàn)延遲,會影響所有分配在這臺服務(wù)器下的用戶。

          • 最小連接數(shù)策略:將請求優(yōu)先分配給壓力較小的服務(wù)器,它可以平衡每個隊列的長度,并避免向壓力大的服務(wù)器添加更多的請求。

          • 最快響應(yīng)時間策略:優(yōu)先分配給響應(yīng)時間最短的服務(wù)器。

          • 客戶端 IP 綁定策略:來自同一個 IP 的請求永遠只分配一臺服務(wù)器,有效解決了動態(tài)網(wǎng)頁存在的 session 共享問題。


          Nginx 實戰(zhàn)配置


          在配置反向代理和負(fù)載均衡等等功能之前,有兩個核心模塊是我們必須要掌握的,這兩個模塊應(yīng)該說是 Nginx 應(yīng)用配置中的核心,它們分別是: upstream、proxy_pass。

          upstream

          用于定義上游服務(wù)器(指的就是后臺提供的應(yīng)用服務(wù)器)的相關(guān)信息。


          語法:upstream name {
           ...
          }

          上下文:http

          示例:
          upstream back_end_server{
            server 192.168.100.33:8081
          }

          在 upstream 內(nèi)可使用的指令:

          • server 定義上游服務(wù)器地址;

          • zone 定義共享內(nèi)存,用于跨 worker 子進程;

          • keepalive 對上游服務(wù)啟用長連接;

          • keepalive_requests 一個長連接最多請求 HTTP 的個數(shù);

          • keepalive_timeout 空閑情形下,一個長連接的超時時長;

          • hash 哈希負(fù)載均衡算法;

          • ip_hash 依據(jù) IP 進行哈希計算的負(fù)載均衡算法;

          • least_conn 最少連接數(shù)負(fù)載均衡算法;

          • least_time 最短響應(yīng)時間負(fù)載均衡算法;

          • random 隨機負(fù)載均衡算法;


          server

          定義上游服務(wù)器地址。
          語法:server address [parameters]

          上下文:upstream
          parameters 可選值:

          • weight=number 權(quán)重值,默認(rèn)為 1;

          • max_conns=number 上游服務(wù)器的最大并發(fā)連接數(shù);

          • fail_timeout=time 服務(wù)器不可用的判定時間;

          • max_fails=numer 服務(wù)器不可用的檢查次數(shù);

          • backup 備份服務(wù)器,僅當(dāng)其他服務(wù)器都不可用時才會啟用;

          • down 標(biāo)記服務(wù)器長期不可用,離線維護;


          keepalive

          限制每個 worker 子進程與上游服務(wù)器空閑長連接的最大數(shù)量。

          keepalive connections;

          上下文:upstream

          示例:keepalive 16;


          keepalive_requests

          單個長連接可以處理的最多 HTTP 請求個數(shù)。

          語法:keepalive_requests number;

          默認(rèn)值:keepalive_requests 100;

          上下文:upstream


          keepalive_timeout

          空閑長連接的最長保持時間。
          語法:keepalive_timeout time;

          默認(rèn)值: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

          用于配置代理服務(wù)器。
          語法: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 參數(shù)原則:

          • URL 必須以 http 或 https 開頭;

          • URL 中可以攜帶變量;

          • URL 中是否帶 URI ,會直接影響發(fā)往上游請求的 URL;


          接下來讓我們來看看兩種常見的 URL 用法:

          • proxy_pass http://192.168.100.33:8081

          • proxy_pass http://192.168.100.33:8081/


          這兩種用法的區(qū)別就是帶 / 和不帶 / ,在配置代理時它們的區(qū)別可大了:

          • 不帶 / 意味著 Nginx 不會修改用戶 URL,而是直接透傳給上游的應(yīng)用服務(wù)器;

          • 帶 / 意味著 Nginx 會修改用戶 URL ,修改方法是將 location 后的 URL 從用戶 URL 中刪除;


          不帶 / 的用法:
          location /bbs/{
            proxy_pass http://127.0.0.1:8080;
          }
          分析:

          • 用戶請求 URL:/bbs/abc/test.html

          • 請求到達 Nginx 的 URL:/bbs/abc/test.html

          • 請求到達上游應(yīng)用服務(wù)器的 URL :/bbs/abc/test.html


          帶 / 的用法:

          location /bbs/{
            proxy_pass http://127.0.0.1:8080/;
          }

          分析:

          • 用戶請求 URL:/bbs/abc/test.html

          • 請求到達 Nginx 的 URL:/bbs/abc/test.html

          • 請求到達上游應(yīng)用服務(wù)器的 URL:/abc/test.html


          并沒有拼接上 /bbs,這點和 root與 alias 之間的區(qū)別是保持一致的。

          配置反向代理

          這里為了演示更加接近實際,作者準(zhǔn)備了兩臺云服務(wù)器,它們的公網(wǎng) IP 分別是:121.42.11.34 與 121.5.180.193。

          我們把 121.42.11.34 服務(wù)器作為上游服務(wù)器,做如下配置:

          # /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 服務(wù)器 nginx -s reload。

          把 121.5.180.193 服務(wù)器作為代理服務(wù)器,做如下配置:

          # /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 進入配置文件,添加如下內(nèi)容:

          121.5.180.193 proxy.lion.club



          分析:

          • 當(dāng)訪問 proxy.lion.club/proxy 時通過 upstream 的配置找到 121.42.11.34:8080;

          • 因此訪問地址變?yōu)?nbsp;http://121.42.11.34:8080/proxy;

          • 連接到 121.42.11.34 服務(wù)器,找到 8080 端口提供的 server;

          • 通過 server 找到 /usr/share/nginx/html/proxy/index.html 資源,最終展示出來。


          配置負(fù)載均衡

          配置負(fù)載均衡主要是要使用 upstream 指令。

          我們把 121.42.11.34 服務(wù)器作為上游服務(wù)器,做如下配置(/etc/nginx/conf.d/balance.conf):

          server{
            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';
            }
          }

          配置完成后:

          • nginx -t 檢測配置是否正確;

          • nginx -s reload 重啟 Nginx 服務(wù)器;

          • 執(zhí)行 ss -nlt 命令查看端口是否被占用,從而判斷 Nginx 服務(wù)是否正確啟動。


          把 121.5.180.193 服務(wù)器作為代理服務(wù)器,做如下配置(/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 服務(wù)器。并且在需要訪問的客戶端配置好 ip 和域名的映射關(guān)系。

          # /etc/hosts

          121.5.180.193 balance.lion.club

          在客戶端機器執(zhí)行 curl http://balance.lion.club/balance/ 命令:


          不難看出,負(fù)載均衡的配置已經(jīng)生效了,每次給我們分發(fā)的上游服務(wù)器都不一樣。就是通過簡單的輪詢策略進行上游服務(wù)器分發(fā)。

          接下來,我們再來了解下 Nginx 的其它分發(fā)策略。

          hash 算法

          通過制定關(guān)鍵字作為 hash key,基于 hash 算法映射到特定的上游服務(wù)器中。關(guān)鍵字可以包含有變量、字符串。

          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 保持不變,就會一直分發(fā)給同一臺服務(wù)器。

          ip_hash

          根據(jù)客戶端的請求 ip 進行判斷,只要 ip 地址不變就永遠分配到同一臺主機。它可以有效解決后臺服務(wù)器 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;
            }
          }


          最少連接數(shù)算法

          各個 worker 子進程通過讀取共享內(nèi)存的數(shù)據(jù),來獲取后端服務(wù)器的信息。來挑選一臺當(dāng)前已建立連接數(shù)最少的服務(wù)器進行分配請求。

          語法:least_conn;

          上下文:upstream;

          示例:

          upstream demo_server {
            zone test 10M; # zone可以設(shè)置共享內(nèi)存空間的名字和大小
            least_conn;
            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;
            }
          }

          最后你會發(fā)現(xiàn),負(fù)載均衡的配置其實一點都不復(fù)雜。

          配置緩存

          緩存可以非常有效的提升性能,因此不論是客戶端(瀏覽器),還是代理服務(wù)器(Nginx),乃至上游服務(wù)器都多少會涉及到緩存。可見緩存在每個環(huán)節(jié)都是非常重要的。下面讓我們來學(xué)習(xí) Nginx 中如何設(shè)置緩存策略。

          proxy_cache

          存儲一些之前被訪問過、而且可能將要被再次訪問的資源,使用戶可以直接從代理服務(wù)器獲得,從而減少上游服務(wù)器的壓力,加快整個訪問速度。

          語法:proxy_cache zone | off ; # zone 是共享內(nèi)存的名稱

          默認(rèn)值:proxy_cache off;

          上下文:http、server、location


          proxy_cache_path

          設(shè)置緩存文件的存放路徑。

          語法:proxy_cache_path path [level=levels] ...可選參數(shù)省略,下面會詳細列舉

          默認(rèn)值:proxy_cache_path off

          上下文:http

          參數(shù)含義:

          • path 緩存文件的存放路徑;

          • level path 的目錄層級;

          • keys_zone 設(shè)置共享內(nèi)存;

          • inactive 在指定時間內(nèi)沒有被訪問,緩存會被清理,默認(rèn)10分鐘;


          proxy_cache_key

          設(shè)置緩存文件的 key 。

          語法:proxy_cache_key

          默認(rèn)值:proxy_cache_key $scheme$proxy_host$request_uri;

          上下文:http、server、location


          proxy_cache_valid

          配置什么狀態(tài)碼可以被緩存,以及緩存時長。

          語法:proxy_cache_valid [code...] time;

          上下文:http、server、location

          配置示例:proxy_cache_valid 200 304 2m;; # 說明對于狀態(tài)為 200 和 304 的緩存文件的緩存時間是 2 分鐘


          proxy_no_cache

          定義相應(yīng)保存到緩存的條件,如果字符串參數(shù)的至少一個值不為空且不等于“ 0”,則將不保存該響應(yīng)到緩存。

          語法:proxy_no_cache string;

          上下文:http、server、location

          示例:proxy_no_cache $http_pragma    $http_authorization;


          proxy_cache_bypass

          定義條件,在該條件下將不會從緩存中獲取響應(yīng)。

          語法:proxy_cache_bypass string;

          上下文:http、server、location

          示例:proxy_cache_bypass $http_pragma    $http_authorization;


          upstream_cache_status 變量

          它存儲了緩存是否命中的信息,會設(shè)置在響應(yīng)頭信息中,在調(diào)試中非常有用。

          MISS:未命中緩存
          HIT:命中緩存
          EXPIRED:緩存過期
          STALE:命中了陳舊緩存
          REVALIDDATED:Nginx 驗證陳舊緩存依然有效
          UPDATING:內(nèi)容陳舊,但正在更新
          BYPASS:X響應(yīng)從原始服務(wù)器獲取


          配置實例

          我們把 121.42.11.34 服務(wù)器作為上游服務(wù)器,做如下配置(/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 服務(wù)器作為代理服務(wù)器,做如下配置(/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; # 設(shè)置緩存內(nèi)存,上面配置中已經(jīng)定義好的
              proxy_cache_valid 200 5m; # 緩存狀態(tài)為 200 的請求,緩存時長為 5 分鐘
              proxy_cache_key $request_uri# 緩存文件的 key 為請求的URI
              add_header Nginx-Cache-Status $upstream_cache_status # 把緩存狀態(tài)設(shè)置為頭部信息,響應(yīng)給客戶端
              proxy_pass http://cache_server; # 代理轉(zhuǎn)發(fā)
            }
          }

          緩存就是這樣配置,我們可以在 /etc/nginx/cache_temp 路徑下找到相應(yīng)的緩存文件。

          對于一些實時性要求非常高的頁面或數(shù)據(jù)來說,就不應(yīng)該去設(shè)置緩存,下面來看看如何配置不緩存的內(nèi)容。

          ...

          server {
            listen 80;
            server_name cache.lion.club;
            # URI 中后綴為 .txt 或 .text 的設(shè)置變量值為 "no cache"
            if ($request_uri ~ \.(txt|text)$) {
             set $cache_name "no cache"
            }
            
            location / {
              proxy_no_cache $cache_name# 判斷該變量是否有值,如果有值則不進行緩存,如果沒有值則進行緩存
              proxy_cache cache_zone; # 設(shè)置緩存內(nèi)存
              proxy_cache_valid 200 5m; # 緩存狀態(tài)為  200的請求,緩存時長為 5 分鐘
              proxy_cache_key $request_uri# 緩存文件的 key 為請求的 URI
              add_header Nginx-Cache-Status $upstream_cache_status # 把緩存狀態(tài)設(shè)置為頭部信息,響應(yīng)給客戶端
              proxy_pass http://cache_server; # 代理轉(zhuǎn)發(fā)
            }
          }


          HTTPS

          在學(xué)習(xí)如何配置 HTTPS 之前,我們先來簡單回顧下 HTTPS 的工作流程是怎么樣的?它是如何進行加密保證安全的?

          HTTPS 工作流程

          • 客戶端(瀏覽器)訪問 https://www.baidu.com 百度網(wǎng)站;

          • 百度服務(wù)器返回 HTTPS 使用的 CA 證書;

          • 瀏覽器驗證 CA 證書是否為合法證書;

          • 驗證通過,證書合法,生成一串隨機數(shù)并使用公鑰(證書中提供的)進行加密;

          • 發(fā)送公鑰加密后的隨機數(shù)給百度服務(wù)器;

          • 百度服務(wù)器拿到密文,通過私鑰進行解密,獲取到隨機數(shù)(公鑰加密,私鑰解密,反之也可以);

          • 百度服務(wù)器把要發(fā)送給瀏覽器的內(nèi)容,使用隨機數(shù)進行加密后傳輸給瀏覽器;

          • 此時瀏覽器可以使用隨機數(shù)進行解密,獲取到服務(wù)器的真實傳輸內(nèi)容。


          這就是 HTTPS 的基本運作原理,使用對稱加密和非對稱機密配合使用,保證傳輸內(nèi)容的安全性。

          關(guān)于HTTPS更多知識,可以查看作者的另外一篇文章:https://juejin.cn/post/6844904148601667598#heading-37。

          配置證書

          下載證書的壓縮文件,里面有個 Nginx 文件夾,把 xxx.crt 和 xxx.key 文件拷貝到服務(wù)器目錄,再進行如下配置:

          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協(xié)議版本,默認(rèn)為后三個,主流版本是[TLSv1.2]
           
            location / {
              root         /usr/share/nginx/html;
              index        index.html index.htm;
            }
          }

          如此配置后就能正常訪問 HTTPS 版的網(wǎng)站了。

          配置跨域 CORS

          先簡單回顧下跨域究竟是怎么回事。

          跨域的定義

          同源策略限制了從同一個源加載的文檔或腳本如何與來自另一個源的資源進行交互。這是一個用于隔離潛在惡意文件的重要安全機制。通常不允許不同源間的讀操作。

          同源的定義

          如果兩個頁面的協(xié)議,端口(如果有指定)和域名都相同,則兩個頁面具有相同的源。

          下面給出了與 URL http://store.company.com/dir/page.html 的源進行對比的示例:
          http://store.company.com/dir2/other.html 同源
          https://store.company.com/secure.html 不同源,協(xié)議不同
          http://store.company.com:81/dir/etc.html 不同源,端口不同
          http://news.company.com/dir/other.html 不同源,主機不同
          不同源會有如下限制:

          • Web 數(shù)據(jù)層面,同源策略限制了不同源的站點讀取當(dāng)前站點的 Cookie、IndexDB、LocalStorage 等數(shù)據(jù)。

          • DOM 層面,同源策略限制了來自不同源的 JavaScript 腳本對當(dāng)前 DOM 對象讀和寫的操作。

          • 網(wǎng)絡(luò)層面,同源策略限制了通過 XMLHttpRequest 等方式將站點的數(shù)據(jù)發(fā)送給不同源的站點。


          Nginx 解決跨域的原理

          例如:

          • 前端 server 的域名為:fe.server.com

          • 后端服務(wù)的域名為:dev.server.com


          現(xiàn)在我在 fe.server.com 對 dev.server.com 發(fā)起請求一定會出現(xiàn)跨域。

          現(xiàn)在我們只需要啟動一個 Nginx 服務(wù)器,將 server_name 設(shè)置為 fe.server.com 然后設(shè)置相應(yīng)的 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 對服務(wù)端轉(zhuǎn)發(fā)的請求不會觸發(fā)瀏覽器的同源策略。

          配置開啟 gzip 壓縮

          GZIP 是規(guī)定的三種標(biāo)準(zhǔn) HTTP 壓縮格式之一。目前絕大多數(shù)的網(wǎng)站都在使用 GZIP 傳輸 HTML、CSS、JavaScript 等資源文件。

          對于文本文件,GZiP 的效果非常明顯,開啟后傳輸所需流量大約會降至 1/4~1/3 。

          并不是每個瀏覽器都支持 gzip 的,如何知道客戶端是否支持 gzip 呢,請求頭中的 Accept-Encoding 來標(biāo)識對壓縮的支持。


          啟用 gzip 同時需要客戶端和服務(wù)端的支持,如果客戶端支持 gzip 的解析,那么只要服務(wù)端能夠返回 gzip 的文件就可以啟用 gzip 了,我們可以通過 Nginx 的配置來讓服務(wù)端支持 gzip。下面的 respone 中 content-encoding:gzip,指服務(wù)端開啟了 gzip 的壓縮方式。


          在 /etc/nginx/conf.d/ 文件夾中新建配置文件 gzip.conf :
          # # 默認(rèn) off,是否開啟 gzip
          gzip on; 
          # 要采用 gzip 壓縮的 MIME 文件類型,其中 text/html 被系統(tǒng)強制啟用;
          gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;

          # ---- 以上兩個參數(shù)開啟就可以支持 Gzip 壓縮了 ---- #

          # 默認(rèn) off,該模塊啟用后,Nginx 首先檢查是否存在請求靜態(tài)文件的 gz 結(jié)尾的文件,如果有則直接返回該 .gz 文件內(nèi)容;
          gzip_static on;

          # 默認(rèn) off,Nginx 做為反向代理時啟用,用于設(shè)置啟用或禁用從代理服務(wù)器上收到相應(yīng)內(nèi)容 gzip 壓縮;
          gzip_proxied any;

          # 用于在響應(yīng)消息頭中添加 Vary:Accept-Encoding,使代理服務(wù)器根據(jù)請求頭中的 Accept-Encoding 識別是否啟用 gzip 壓縮;
          gzip_vary on;

          # gzip 壓縮比,壓縮級別是 1-9,1 壓縮級別最低,9 最高,級別越高壓縮率越大,壓縮時間越長,建議 4-6;
          gzip_comp_level 6;

          # 獲取多少內(nèi)存用于緩存壓縮結(jié)果,16 8k 表示以 8k*16 為單位獲得;
          gzip_buffers 16 8k;

          # 允許壓縮的頁面最小字節(jié)數(shù),頁面字節(jié)數(shù)從 header 頭中的 Content-Length 中進行獲取。默認(rèn)值是 0,不管頁面多大都壓縮。建議設(shè)置成大于 1k 的字節(jié)數(shù),小于 1k 可能會越壓越大;
          # gzip_min_length 1k;

          # 默認(rèn) 1.1,啟用 gzip 所需的 HTTP 最低版本;
          gzip_http_version 1.1;
          其實也可以通過前端構(gòu)建工具例如 webpack、rollup 等在打生產(chǎn)包時就做好 Gzip 壓縮,然后放到 Nginx 服務(wù)器中,這樣可以減少服務(wù)器的開銷,加快訪問速度。

          關(guān)于 Nginx 的實際應(yīng)用就學(xué)習(xí)到這里,相信通過掌握了 Nginx 核心配置以及實戰(zhàn)配置,之后再遇到什么需求,我們也能輕松應(yīng)對。接下來,讓我們再深入一點學(xué)習(xí)下 Nginx 的架構(gòu)。


          Nginx 架構(gòu)


          進程結(jié)構(gòu)

          多進程結(jié)構(gòu) Nginx 的進程模型圖:


          多進程中的 Nginx 進程架構(gòu)如下圖所示,會有一個父進程(Master Process),它會有很多子進程(Child Processes)。

          • Master Process 用來管理子進程的,其本身并不真正處理用戶請求。

            • 某個子進程 down 掉的話,它會向 Master 進程發(fā)送一條消息,表明自己不可用了,此時 Master 進程會去新起一個子進程。

            • 某個配置文件被修改了 Master 進程會去通知 work 進程獲取新的配置信息,這也就是我們所說的熱部署。


          • 子進程間是通過共享內(nèi)存的方式進行通信的。


          配置文件重載原理

          reload 重載配置文件的流程:

          • 向 master 進程發(fā)送 HUP 信號(reload 命令);

          • master 進程檢查配置語法是否正確;

          • master 進程打開監(jiān)聽端口;

          • master 進程使用新的配置文件啟動新的 worker 子進程;

          • master 進程向老的 worker 子進程發(fā)送 QUIT 信號;

          • 老的 worker 進程關(guān)閉監(jiān)聽句柄,處理完當(dāng)前連接后關(guān)閉進程;

          • 整個過程 Nginx 始終處于平穩(wěn)運行中,實現(xiàn)了平滑升級,用戶無感知;


          Nginx 模塊化管理機制

          Nginx 的內(nèi)部結(jié)構(gòu)是由核心部分和一系列的功能模塊所組成。這樣劃分是為了使得每個模塊的功能相對簡單,便于開發(fā),同時也便于對系統(tǒng)進行功能擴展。Nginx 的模塊是互相獨立的,低耦合高內(nèi)聚。


          總結(jié)


          相信通過本文的學(xué)習(xí),你應(yīng)該會對 Nginx 有一個更加全面的認(rèn)識。
          瀏覽 75
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  欧美美女做爱 | 人妻夜夜爽天天爽麻豆三区网站 | 成人性生活片 | 性爱视频网址 | 亚洲中文字幕一区二区 |