<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 !

          共 26371字,需瀏覽 53分鐘

           ·

          2022-03-15 18:28

          前言

          作為一名開發(fā)人員,你是不是經(jīng)常碰到領導讓你上服務器去修改 Nginx 配置,然而你可能會對這些配置并不熟悉!今天就讓我們一起告別這種尷尬,向“真正”的程序員邁進!!!

          如果本文對你有所幫助,請點個?? ?? ?? 吧!


          Nginx 概述

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


          Nginx 特點

          • 高并發(fā)、高性能;
          • 模塊化架構使得它的擴展性非常好;
          • 異步非阻塞的事件驅動模型這點和 Node.js 相似;
          • 相對于其它服務器來說它可以連續(xù)幾個月甚至更長而不需要重啟服務器使得它具有高可靠性;
          • 熱部署、平滑升級;
          • 完全開源,生態(tài)繁榮;

          Nginx 作用

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

          1. 靜態(tài)資源服務,通過本地文件系統(tǒng)提供服務;
          2. 反向代理服務,延伸出包括緩存、負載均衡等;
          3. API 服務, OpenResty

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

          用一張圖表示:

          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
          復制代碼

          主要關注的文件夾有兩個:

          1. /etc/nginx/conf.d/ 是子配置項存放處, /etc/nginx/nginx.conf 主配置文件會默認把這個文件夾中所有子配置項都引入;
          2. /usr/share/nginx/html/ 靜態(tài)文件都放在這個文件夾,也可以根據(jù)你自己的習慣放在其他地方;

          Nginx 常用命令

          systemctl 系統(tǒng)命令:

          #?開機配置
          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?運行狀態(tài)
          systemctl?status?nginx

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

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

          Nginx 應用程序命令:

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





          Nginx 核心配置

          配置文件結構

          Nginx 的典型配置示例:


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

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

          #?http段配置信息
          #?配置使用最頻繁的部分,代理、緩存、日志定義等絕大多數(shù)功能和第三方模塊的配置都在這里設置
          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;???#?減少網(wǎng)絡報文段的數(shù)量
          ????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;???????#?配置監(jiān)聽的端口
          ?????server_name??localhost;????#?配置的域名
          ??????
          ?????#?location段配置信息
          ?????location?/?{
          ??????root???/usr/share/nginx/html;??#?網(wǎng)站根目錄
          ??????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;???#?同上
          ????}
          }
          復制代碼
          • main 全局配置,對全局生效;
          • events 配置影響 Nginx 服務器與用戶的網(wǎng)絡連接;
          • http 配置代理,緩存,日志定義等絕大多數(shù)功能和第三方模塊的配置;
          • server 配置虛擬主機的相關參數(shù),一個 http 塊中可以有多個 server 塊;
          • location 用于配置匹配的 uri
          • upstream 配置后端服務器具體地址,負載均衡配置不可或缺的部分;

          用一張圖清晰的展示它的層級結構:

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

          user

          指定運行 Nginxwoker 子進程的屬主和屬組,其中組可以不指定。

          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;?#?與當前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)先級,通常設定為負值,以優(yōu)先調(diào)用 Nginx

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

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

          [備注] 應用的默認優(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;?#?默認是on,后臺運行模式
          復制代碼

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

          use

          Nginx 使用何種事件驅動模型。

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

          method 可選值為:select、poll、kqueue、epoll、/dev/poll、eventport
          復制代碼

          worker_connections

          worker 子進程能夠處理的最大并發(fā)連接數(shù)。

          worker_connections?1024?#?每個子進程的最大連接數(shù)為1024
          復制代碼

          accept_mutex

          是否打開負載均衡互斥鎖。

          accept_mutex?on?#?默認是off關閉的,這里推薦打開
          復制代碼

          server_name 指令

          指定虛擬主機域名。

          server_name?name1?name2?name3

          #?示例:
          server_name?www.nginx.com;
          復制代碼

          域名匹配的四種寫法:

          • 精確匹配:server_name www.nginx.com ;
          • 左側通配:server_name *.nginx.com ;
          • 右側統(tǒng)配:server_name www.nginx.* ;
          • 正則匹配:server_name ~^www\.nginx\.*$ ;

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

          server_name 配置實例:

          1、配置本地 ?DNS 解析 vim /etc/hostsmacOS 系統(tǒng))

          #?添加如下內(nèi)容,其中?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 解析,如果使用阿里云上購買的域名,則需要在阿里云上設置好域名解析。

          2、配置阿里云 Nginxvim /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、訪問分析

          • 當訪問 www.nginx-test.com 時,都可以被匹配上,因此選擇優(yōu)先級最高的“完全匹配”;
          • 當訪問 mail.nginx-test.com 時,會進行“左匹配”;
          • 當訪問 www.nginx-test.org 時,會進行“右匹配”;
          • 當訪問 doc.nginx-test.com 時,會進行“左匹配”;
          • 當訪問 www.nginx-test.cn 時,會進行“右匹配”;
          • 當訪問 fe.nginx-test.club 時,會進行“正則匹配”;

          root

          指定靜態(tài)資源目錄位置,它可以寫在 httpserverlocation 等配置中。

          root?path

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

          當用戶訪問?www.test.com/image/1.png?時,實際在服務器找的路徑是?/opt/nginx/static/image/1.png
          復制代碼

          [注意] root 會將定義路徑與 URI 疊加, alias 則只取定義路徑。

          alias

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

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

          當用戶訪問?www.test.com/image/1.png?時,實際在服務器找的路徑是?/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;
          ??
          ??#?只有當訪問?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/?{
          ?...
          }
          復制代碼
          • 不帶 / 當訪問 www.nginx-test.com/test 時, Nginx 先找是否有 test 目錄,如果有則找 test 目錄下的 index.html ;如果沒有 test 目錄, nginx 則會找是否有 test 文件。
          • / 當訪問 www.nginx-test.com/test 時, Nginx 先找是否有 test 目錄,如果有則找 test 目錄下的 index.html ,如果沒有它也不會去找是否存在 test 文件。

          return

          停止處理請求,直接返回響應碼或重定向到其他 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?{
          ??
          ??}
          }
          復制代碼

          按照這個配置我們來分析:

          • 當訪問 fe.lion.club/search 時,會自動幫我們重定向到 https://www.baidu.com
          • 當訪問 fe.lion.club/images/1.jpg 時,第一步重寫 URLfe.lion.club/pics/1.jpg ,找到 picslocation ,繼續(xù)重寫 URLfe.lion.club/photos/1.jpg ,找到 /photoslocation 后,去 html/photos 目錄下尋找 1.jpg 靜態(tài)資源。

          if 指令

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

          上下文:server、location

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

          condition 判斷條件:

          • $variable 僅為變量時,值為空或以0開頭字符串都會被當做 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;
          ????}
          ??}
          }
          復制代碼

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

          autoindex

          用戶請求以 / 結尾時,列出目錄結構,可以用于快速搭建靜態(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顯示文件大小,默認為on,以bytes顯示出?件的確切??
          ????autoindex_format?html;?#?以html的方式進行格式化,可選參數(shù)有?html?|?json?|?xml
          ????autoindex_localtime?off;?#?顯示的?件時間為?件的服務器時間。默認為off,顯示的?件時間為GMT時間
          ??}
          }
          復制代碼

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

          變量

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

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

          變量名含義
          remote_addr客戶端 IP 地址
          remote_port客戶端端口
          server_addr服務端 IP 地址
          server_port服務端端口
          server_protocol服務端協(xié)議
          binary_remote_addr二進制格式的客戶端 IP 地址
          connectionTCP 連接的序號,遞增
          connection_requestTCP 連接當前的請求數(shù)量
          uri請求的URL,不包含參數(shù)
          request_uri請求的URL,包含參數(shù)
          scheme協(xié)議名, httphttps
          request_method請求方法
          request_length全部請求的長度,包含請求行、請求頭、請求體
          args全部參數(shù)字符串
          arg_參數(shù)名獲取特定參數(shù)值
          is_argsURL 中是否有參數(shù),有的話返回 ? ,否則返回空
          query_stringargs 相同
          host請求信息中的 Host ,如果請求中沒有 Host 行,則在請求頭中找,最后使用 nginx 中設置的 server_name
          http_user_agent用戶瀏覽器
          http_referer從哪些鏈接過來的請求
          http_via每經(jīng)過一層代理服務器,都會添加相應的信息
          http_cookie獲取用戶 cookie
          request_time處理請求已消耗的時間
          https是否開啟了 https ,是則返回 on ,否則返回空
          request_filename磁盤文件系統(tǒng)待訪問文件的完整路徑
          document_rootURIroot/alias 規(guī)則生成的文件夾路徑
          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:8081/test?pid=121414&cid=sadasd 時,由于 Nginx 中寫了 return 方法,因此 chrome 瀏覽器會默認為我們下載一個文件,下面展示的就是下載的文件內(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 的配置還有非常多,以上只是羅列了一些常用的配置,在實際項目中還是要學會查閱文檔。

          Nginx 應用核心概念

          代理是在服務器和客戶端之間假設的一層服務器,代理將接收客戶端的請求并將它轉發(fā)給服務器,然后將服務端的響應轉發(fā)給客戶端。

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

          正向代理

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

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

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

          反向代理

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

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

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

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

          • 隱藏真實服務器;
          • 負載均衡便于橫向擴充后端動態(tài)服務;
          • 動靜分離,提升系統(tǒng)健壯性;

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

          動靜分離

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

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

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

          負載均衡

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

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

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

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

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

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

          • 輪詢策略:默認情況下采用的策略,將所有客戶端請求輪詢分配給服務端。這種策略是可以正常工作的,但是如果其中某一臺服務器壓力太大,出現(xiàn)延遲,會影響所有分配在這臺服務器下的用戶。
          • 最小連接數(shù)策略:將請求優(yōu)先分配給壓力較小的服務器,它可以平衡每個隊列的長度,并避免向壓力大的服務器添加更多的請求。
          • 最快響應時間策略:優(yōu)先分配給響應時間最短的服務器。
          • 客戶端 ip 綁定策略:來自同一個 ip 的請求永遠只分配一臺服務器,有效解決了動態(tài)網(wǎng)頁存在的 session 共享問題。

          Nginx 實戰(zhàn)配置

          在配置反向代理和負載均衡等等功能之前,有兩個核心模塊是我們必須要掌握的,這兩個模塊應該說是 Nginx 應用配置中的核心,它們分別是:upstreamproxy_pass

          upstream

          用于定義上游服務器(指的就是后臺提供的應用服務器)的相關信息。

          語法:upstream name {
          ?...
          }

          上下文:http

          示例:
          upstream?back_end_server{
          ??server?192.168.100.33:8081
          }
          復制代碼

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

          • server 定義上游服務器地址;
          • zone 定義共享內(nèi)存,用于跨 worker 子進程;
          • keepalive 對上游服務啟用長連接;
          • keepalive_requests 一個長連接最多請求 HTTP 的個數(shù);
          • keepalive_timeout 空閑情形下,一個長連接的超時時長;
          • hash 哈希負載均衡算法;
          • ip_hash 依據(jù) IP 進行哈希計算的負載均衡算法;
          • least_conn 最少連接數(shù)負載均衡算法;
          • least_time 最短響應時間負載均衡算法;
          • random 隨機負載均衡算法;

          server

          定義上游服務器地址。

          語法:server address [parameters]

          上下文:upstream
          復制代碼

          parameters 可選值:

          • weight=number 權重值,默認為1;
          • max_conns=number 上游服務器的最大并發(fā)連接數(shù);
          • fail_timeout=time 服務器不可用的判定時間;
          • max_fails=numer 服務器不可用的檢查次數(shù);
          • backup 備份服務器,僅當其他服務器都不可用時才會啟用;
          • down 標記服務器長期不可用,離線維護;

          keepalive

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

          keepalive?connections;

          上下文:upstream

          示例:keepalive 16;
          復制代碼

          keepalive_requests

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

          語法:keepalive_requests number;

          默認值:keepalive_requests 100;

          上下文:upstream
          復制代碼

          keepalive_timeout

          空閑長連接的最長保持時間。

          語法: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

          用于配置代理服務器。

          語法: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ù)原則

          1. URL 必須以 httphttps 開頭;
          2. URL 中可以攜帶變量;
          3. URL 中是否帶 URI ,會直接影響發(fā)往上游請求的 URL

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

          1. proxy_pass http://192.168.100.33:8081
          2. proxy_pass http://192.168.100.33:8081/

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

          • 不帶 / 意味著 Nginx 不會修改用戶 URL ,而是直接透傳給上游的應用服務器;
          • / 意味著 Nginx 會修改用戶 URL ,修改方法是將 location 后的 URL 從用戶 URL 中刪除;

          不帶 / 的用法:

          location?/bbs/{
          ??proxy_pass?http://127.0.0.1:8080;
          }
          復制代碼

          分析:

          1. 用戶請求 URL/bbs/abc/test.html
          2. 請求到達 NginxURL/bbs/abc/test.html
          3. 請求到達上游應用服務器的 URL/bbs/abc/test.html

          / 的用法:

          location?/bbs/{
          ??proxy_pass?http://127.0.0.1:8080/;
          }
          復制代碼

          分析:

          1. 用戶請求 URL/bbs/abc/test.html
          2. 請求到達 NginxURL/bbs/abc/test.html
          3. 請求到達上游應用服務器的 URL/abc/test.html

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

          配置反向代理

          這里為了演示更加接近實際,作者準備了兩臺云服務器,它們的公網(wǎng) IP 分別是:121.42.11.34121.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

          ?121.42.11.34?proxy?html?


          復制代碼

          配置完成后重啟 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 進入配置文件,添加如下內(nèi)容:

          121.5.180.193?proxy.lion.club
          復制代碼

          分析:

          1. 當訪問 proxy.lion.club/proxy 時通過 upstream 的配置找到 121.42.11.34:8080
          2. 因此訪問地址變?yōu)?http://121.42.11.34:8080/proxy
          3. 連接到 121.42.11.34 服務器,找到 8080 端口提供的 server
          4. 通過 server 找到 /usr/share/nginx/html/proxy/index.html 資源,最終展示出來。

          配置負載均衡

          配置負載均衡主要是要使用 upstream 指令。

          我們把 121.42.11.34 服務器作為上游服務器,做如下配置( /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';
          ??}
          }
          復制代碼

          配置完成后:

          1. nginx -t 檢測配置是否正確;
          2. nginx -s reload 重啟 Nginx 服務器;
          3. 執(zhí)行 ss -nlt 命令查看端口是否被占用,從而判斷 Nginx 服務是否正確啟動。

          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/hosts

          121.5.180.193?balance.lion.club
          復制代碼

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

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

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

          hash 算法

          通過制定關鍵字作為 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 變量作為 hashkey 值,只要訪問的 URI 保持不變,就會一直分發(fā)給同一臺服務器。

          ip_hash

          根據(jù)客戶端的請求 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;
          ??}
          }
          復制代碼

          最少連接數(shù)算法

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

          語法:least_conn;

          上下文:upstream;
          復制代碼

          示例:

          upstream?demo_server?{
          ??zone?test?10M;?#?zone可以設置共享內(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),負載均衡的配置其實一點都不復雜。

          配置緩存

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

          proxy_cache

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

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

          默認值:proxy_cache off;

          上下文:http、server、location
          復制代碼

          proxy_cache_path

          設置緩存文件的存放路徑。

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

          默認值:proxy_cache_path off

          上下文:http
          復制代碼

          參數(shù)含義:

          • path 緩存文件的存放路徑;
          • level path 的目錄層級;
          • keys_zone 設置共享內(nèi)存;
          • inactive 在指定時間內(nèi)沒有被訪問,緩存會被清理,默認10分鐘;

          proxy_cache_key

          設置緩存文件的 key

          語法:proxy_cache_key

          默認值: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

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

          語法:proxy_no_cache string;

          上下文:http、server、location

          示例:proxy_no_cache $http_pragma????$http_authorization;
          復制代碼

          proxy_cache_bypass

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

          語法:proxy_cache_bypass string;

          上下文:http、server、location

          示例:proxy_cache_bypass $http_pragma????$http_authorization;
          復制代碼

          upstream_cache_status 變量

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

          MISS:?未命中緩存
          HIT:?命中緩存
          EXPIRED:?緩存過期
          STALE:?命中了陳舊緩存
          REVALIDDATED:?Nginx驗證陳舊緩存依然有效
          UPDATING:?內(nèi)容陳舊,但正在更新
          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;?#?設置緩存內(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)設置為頭部信息,響應給客戶端
          ????proxy_pass?http://cache_server;?#?代理轉發(fā)
          ??}
          }
          復制代碼

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

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

          ...

          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;?#?設置緩存內(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)設置為頭部信息,響應給客戶端
          ????proxy_pass?http://cache_server;?#?代理轉發(fā)
          ??}
          }
          復制代碼

          HTTPS

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

          HTTPS 工作流程

          1. 客戶端(瀏覽器)訪問 https://www.baidu.com 百度網(wǎng)站;
          2. 百度服務器返回 HTTPS 使用的 CA 證書;
          3. 瀏覽器驗證 CA 證書是否為合法證書;
          4. 驗證通過,證書合法,生成一串隨機數(shù)并使用公鑰(證書中提供的)進行加密;
          5. 發(fā)送公鑰加密后的隨機數(shù)給百度服務器;
          6. 百度服務器拿到密文,通過私鑰進行解密,獲取到隨機數(shù)(公鑰加密,私鑰解密,反之也可以);
          7. 百度服務器把要發(fā)送給瀏覽器的內(nèi)容,使用隨機數(shù)進行加密后傳輸給瀏覽器;
          8. 此時瀏覽器可以使用隨機數(shù)進行解密,獲取到服務器的真實傳輸內(nèi)容;

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

          關于HTTPS更多知識,可以查看作者的另外一篇文章《學習 HTTP 協(xié)議》。

          配置證書

          下載證書的壓縮文件,里面有個 Nginx 文件夾,把 xxx.crtxxx.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協(xié)議版本,默認為后三個,主流版本是[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ù)層面,同源策略限制了不同源的站點讀取當前站點的 CookieIndexDBLocalStorage 等數(shù)據(jù)。
          • DOM 層面,同源策略限制了來自不同源的 JavaScript 腳本對當前 DOM 對象讀和寫的操作。
          • 網(wǎng)絡層面,同源策略限制了通過 XMLHttpRequest 等方式將站點的數(shù)據(jù)發(fā)送給不同源的站點。

          Nginx 解決跨域的原理

          例如:

          • 前端 server 的域名為:fe.server.com
          • 后端服務的域名為:dev.server.com

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

          現(xiàn)在我們只需要啟動一個 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 訪問 Nginxfe.server.com 屬于同源訪問,而 Nginx 對服務端轉發(fā)的請求不會觸發(fā)瀏覽器的同源策略。

          配置開啟 gzip 壓縮

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

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

          并不是每個瀏覽器都支持 gzip 的,如何知道客戶端是否支持 gzip 呢,請求頭中的 Accept-Encoding 來標識對壓縮的支持。啟用 gzip 同時需要客戶端和服務端的支持,如果客戶端支持 gzip 的解析,那么只要服務端能夠返回 gzip 的文件就可以啟用 gzip 了,我們可以通過 Nginx 的配置來讓服務端支持 gzip 。下面的 responecontent-encoding:gzip ,指服務端開啟了 gzip 的壓縮方式。/etc/nginx/conf.d/ 文件夾中新建配置文件 gzip.conf

          #?#?默認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壓縮了?----?#

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

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

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

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

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

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

          #?默認 1.1,啟用 gzip 所需的 HTTP 最低版本;
          gzip_http_version?1.1;
          復制代碼

          其實也可以通過前端構建工具例如 webpackrollup 等在打生產(chǎn)包時就做好 Gzip 壓縮,然后放到 Nginx 服務器中,這樣可以減少服務器的開銷,加快訪問速度。

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

          Nginx 架構

          進程結構

          多進程結構 Nginx 的進程模型圖:

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

          • Master?Process

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

            • 某個子進程 down 掉的話,它會向 Master 進程發(fā)送一條消息,表明自己不可用了,此時 Master 進程會去新起一個子進程。
            • 某個配置文件被修改了 Master 進程會去通知 work 進程獲取新的配置信息,這也就是我們所說的熱部署。
          • 子進程間是通過共享內(nèi)存的方式進行通信的。

          配置文件重載原理

          reload 重載配置文件的流程:

          1. master 進程發(fā)送 HUP 信號( reload 命令);
          2. master 進程檢查配置語法是否正確;
          3. master 進程打開監(jiān)聽端口;
          4. master 進程使用新的配置文件啟動新的 worker 子進程;
          5. master 進程向老的 worker 子進程發(fā)送 QUIT 信號;
          6. 老的 worker 進程關閉監(jiān)聽句柄,處理完當前連接后關閉進程;
          7. 整個過程 Nginx 始終處于平穩(wěn)運行中,實現(xiàn)了平滑升級,用戶無感知;

          Nginx 模塊化管理機制

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

          總結

          相信通過本文的學習,你應該會對 Nginx 有一個更加全面的認識。

          瀏覽 60
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

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

          手機掃一掃分享

          分享
          舉報
          <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>
                  国产成人久久视频 | 青青草手机视频 | 国内精品久久久久久久星 | 欧美性爱五月天 | 91视频人妻 |