前端須要掌握的Nginx知識點

一直想整理Nginx的知識點而且從新學習一下,正好看見《前端想要了解的Nginx》 juejin.im/post/5cae9d… 這篇文章,所以參考這篇文章,作一個學習筆記,供之後學習。

什麼是Nginx?

Nginx是一款免費開源的高性能HTTP服務器以及反向代理服務器(Reverse Proxy),同時能夠提供IMAP/POP3/SMATP代理服務等功能。可以快速的響應靜態頁面請求和支持第三方功能模塊擴展。javascript

Nginx的優勢

  • 高併發、高性能(官方給出的併發數據5萬,實際中能夠達到2-4萬)
  • 輕量級、內存消耗少
  • 穩定性高,宕機機率低
  • 支持熱部署
  • 模塊化設計,擴展性較好
  • cpu親和

Nginx經常使用的場景

  • 靜態資源服務器
  • 動態匹配
  • 反向代理
  • Gzip壓縮
  • 負載均衡

Nginx的安裝配置

詳細的安裝教程能夠參考這篇文章 www.zhuxiaodong.net/2016/config…php

Nginx經常使用的命令

  • 查看版本號
nginx  -v 
複製代碼
  • 查看nginx 編譯的參數
nginx -V
複製代碼
  • 優雅重啓,並從新載入配置文件nginx.conf
/usr/local/nginx/sbin/nginx  -s  reload
複製代碼
  • 優雅中止nginx,有鏈接時會等鏈接請求完成再殺死worker進程
/usr/local/nginx/sbin/nginx  -s  quit
複製代碼

具體經常使用的命令參考以下:css

nginx -s stop       快速關閉Nginx,可能不保存相關信息,並迅速終止web服務。
nginx -s quit       平穩關閉Nginx,保存相關信息,有安排的結束web服務。
nginx -s reload     因改變了Nginx相關配置,須要從新加載配置而重載。
nginx -s reopen     從新打開日誌文件。
nginx -c filename   爲 Nginx 指定一個配置文件,來代替缺省的。
nginx -t            不運行,僅測試配置文件。nginx 將檢查配置文件的語法的正確性,並嘗試打開配置文件中所引用到的文件。
nginx -v            顯示 nginx 的版本。
nginx -V            顯示 nginx 的版本,編譯器版本和配置參數。
複製代碼

同時要注意在nginx中沒有nginx -s start 這個命令html

有些時候當你運行前端

/usr/local/nginx/sbin/nginx -s  stop
複製代碼

會報錯: java

在這裏插入圖片描述
上面的報錯爲在logs目錄發現確實沒有nginx.pid文件,那麼此時想到的即是檢查如下配置文件,生成nginx.pid文件。此時的解決方法爲:

/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
複製代碼

即可以解決此問題。webpack

Nginx的默認配置

Nginx 安裝目錄下的nginx.conf就是Nginx全局的配置文件,咱們主要修改這裏的內容。nginx.conf.default做爲配置文件的備份。nginx

其中nginx.conf中的配置信息以下:web

 #user nobody;
#設置工做進程的數量
worker_processes  1;
 #error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
 #pid logs/nginx.pid;
 # 處理鏈接
events {
 # 設置鏈接數
    worker_connections  1024;
}


http {
 # 文件拓展名查找集合
    include       mime.types;
    # 當查找不到對應類型的時候默認值
    default_type  application/octet-stream;
    
 # 日誌格式,定義別名爲 main
    #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  logs/access.log  main;
 # 調用 sendfile 系統傳輸文件
    sendfile        on;
    #tcp_nopush     on;
 # 客戶端與服務器鏈接超時時間,超時自動斷開
    #keepalive_timeout  0;
    keepalive_timeout  65;
 # 開啓gizip 壓縮
    #gzip  on;
 # 虛擬主機
    server {
        listen       8081;
        server_name  localhost;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;
 # 路由
        location / {
            root   html;
            index  index.html index.htm;
        }

        #error_page  404              /404.html;

        # redirect server error pages to the static page /50x.html
        #
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }

        # proxy the PHP scripts to Apache listening on 127.0.0.1:80
        #
        #location ~ \.php$ {
        #    proxy_pass   http://127.0.0.1;
        #}

        # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
        #
        #location ~ \.php$ {
        #    root           html;
        #    fastcgi_pass   127.0.0.1:9000;
        #    fastcgi_index  index.php;
        #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
        #    include        fastcgi_params;
        #}

        # deny access to .htaccess files, if Apache's document root
        # concurs with nginx's one
        #
        #location ~ /\.ht {
        #    deny  all;
        #}
    }


    # another virtual host using mix of IP-, name-, and port-based configuration
    #
    server {
        listen       9090;
        server_name  127.0.0.1;

        location / {
            root   build;
            index  index.html index.htm;
        }
    }


    # HTTPS server
    #
    #server {
    #    listen       443 ssl;
    #    server_name  localhost;

    #    ssl_certificate      cert.pem;
    #    ssl_certificate_key  cert.key;

    #    ssl_session_cache    shared:SSL:1m;
    #    ssl_session_timeout  5m;

    #    ssl_ciphers  HIGH:!aNULL:!MD5;
    #    ssl_prefer_server_ciphers  on;

    #    location / {
    #        root   html;
    #        index  index.html index.htm;
    #    }
    #}

}
複製代碼

搭建靜態站點

# 虛擬主機server塊
server {
    # 端口
    listen   8080;
    # 匹配請求中的host值
    server_name  localhost;
    
    # 監聽請求路徑
    location / {
        # 查找目錄
        root /source;
        # 默認查找
        index index.html index.htm;
    }
}
複製代碼

這裏說明一下相關字段:正則表達式

  • server 配置虛擬主機的相關參數,能夠有多個
  • server_name 經過請求中的host值 找到對應的虛擬主機的配置
  • location 配置請求路由,處理相關頁面狀況
  • root 查找資源的路徑

配置完成後執行 nginx -t 看是否有錯誤,若是看到的是下面這種就是成功了

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
複製代碼

而後執行nginx -s reload 更新Nginx配置文件,這時候打開瀏覽器 輸入 localhost:8080 應該就能看到你的頁面了。

動態匹配(請求過濾)

一般在開發環境或者測試環境的時候呢咱們修改了代碼,由於瀏覽器緩存,可能不會生效,須要手動清除緩存,才能看到修改後的效果,這裏咱們作一個配置讓瀏覽器不緩存相關的資源。

location ~* \.(js|css|png|jpg|gif)$ {
    add_header Cache-Control no-store;
}
複製代碼

~* .(js|css|png|jpg|gif)$ 是匹配以相關文件類型而後單獨處理。 add_header 是給請求的響應加上一個頭信息Cache-Control no-store,告知瀏覽器禁用緩存,每次都從服務器獲取 效果以下:

在這裏插入圖片描述
匹配規則,一般的形式以下:

location = / {
    [ configuration A ]
}

location / {
    [ configuration B ]
}

location /documents/ {
    [ configuration C ]
}

location ^~ /images/ {
    [ configuration D ]
}

location ~* \.(gif|jpg|jpeg)$ {
    [ configuration E ]
}
複製代碼
location =|~|~*|^~| /uri/
  • = 表示精確匹配。只有請求的url路徑與後面的字符串徹底相等時,纔會命中(優先級最高)。
  • ^~ 表示若是該符號後面的字符是最佳匹配,採用該規則,再也不進行後續的查找。
  • ~ 表示該規則是使用正則定義的,區分大小寫。
  • ~* 表示該規則是使用正則定義的,不區分大小寫。
  • / 通用匹配,任何請求都會匹配到

最後總結:

  1. 先判斷精準命中,若是命中,當即返回結果並結束解析過程
  2. 判斷普通命中,若是有多個命中,記錄下來最長的命中結果
  3. 若是是^~開頭的命中,則不會繼續搜索正則命中,可是會繼續搜索通常命中
  4. 繼續判斷正則表達式的解析結果,按配置裏的正則表達式順序爲準,由上到下開始匹配,一旦匹配成功馬上返回結果,並結束解析過程。
  5. 普通命中:順序無所謂,是由於按命中長短來肯定的
  6. 正則命中:順序有所謂,由於是從前日後命中的

固然咱們還能夠經過狀態碼來過濾請求就像這樣:

# 經過狀態碼,返回指定的錯誤頁面
error_page 500 502 503 504 /50x.html;
location = /50x.html {
    root /source/error_page;
}
複製代碼

反向代理解決跨域

提起跨域問題,就會引出同源策略的概念,同源策略是瀏覽器的一種機制,同時因爲JavaScript出於安全方面的考慮,不容許跨域調用其餘頁面的對象。什麼是同源?簡單的說:

域名、端口號、協議三者都相同的狀況才被稱爲同源,當三者有一者不相同,便不符合同源策略,此時便產生了跨域。

在先後端分離的開發中,跨域問題是一個很是常見的問題,如今解決跨域問題比較經常使用的兩種方式爲:

  • 跨域資源請求(CORS)
  • Nginx反響代理

在這裏插入圖片描述
先來看上面的圖 ,當用戶請求 xx.720ui.com/server1的時候,Nginx會將請求轉發給Server1這個服務器上的具體應用,從而達到跨域的目的

同時nginx解決跨域時經常使用的參數配置。

location /api {   
    # 請求host傳給後端
    proxy_set_header Host $http_host;
    # 請求ip 傳給後端
    proxy_set_header X-Real-IP $remote_addr;
    # 請求協議傳給後端
    proxy_set_header X-Scheme $scheme;
    # 路徑重寫
    rewrite  /api/(.*)  /$1  break;
    # 代理服務器
    proxy_pass http://localhost:9000;
}
複製代碼
  • 攔截路徑/api, 能夠經過正則匹配
  • proxy_set_header 容許從新定義或添加字段傳遞給代理服務器的請求頭
  • http_host、 remote_addr、$ scheme 爲Nginx內置變量
  • rewrite 根據rewrite後的請求URI,將路徑重寫,如:接口路徑爲 /user, 咱們能夠請求 /api/user。(爲何須要重寫uri?由於在使用Nginx作反向代理的時候,須要匹配到跨域的接口再作轉發,爲了方便匹配,會人爲的在原接口中添加一段路徑(或標示, 如例子中的api),所以須要在匹配以後、轉發以前把添加的那段去掉,所以須要rewrite)
  • break 繼續本次請求後面的處理 ,中止匹配下面的location。須要注意的是與之相似的last執行過程則是中止當前這個請求,並根據rewrite匹配的規則從新發起一個請求,從上到下依次匹配location後面的規則
  • proxy_pass 代理服務器

原理:Nginx攔截到相關匹配規則, Nginx再將請求轉發到http://localhost:9000,Nginx獲得請求後再響應到前端,能夠直接請求/api/user完成請求。

nginx跨域請求一個簡單的dome:

server
{
    listen 80;
    server_name www.1212.com;

    location ^~ /blog/ {
        proxy_pass http://blog.12121.com/;
    }   
}
複製代碼

配置Gzip

開發過程當中不免用到一些成熟的框架,或者插件,這些外部的依賴,有時候體積比較大,致使頁面響應緩慢,咱們能夠用打包工具(webpack, rollup),將代碼進行壓縮,以縮小代碼體積。 開啓Nginx Gzip壓縮功能。須要注意的是 Gzip 壓縮功能須要瀏覽器跟服務器都支持,即服務器壓縮,瀏覽器解析。

  • 查看瀏覽器支持狀況,肯定 請求頭 中的Accept-Encoding字段
    在這裏插入圖片描述
  • 肯定瀏覽器支持,咱們就能夠在Nginx中配置
server {
    # 開啓gzip 壓縮
    gzip on;
    # 設置gzip所需的http協議最低版本 (HTTP/1.1, HTTP/1.0)
    gzip_http_version 1.1;
    # 設置壓縮級別,壓縮級別越高壓縮時間越長  (1-9)
    gzip_comp_level 4;
    # 設置壓縮的最小字節數, 頁面Content-Length獲取
    gzip_min_length 1000;
    # 設置壓縮文件的類型  (text/html)
    gzip_types text/plain application/javascript text/css;
}
複製代碼
  • 查看配置是否生效,查看 響應頭 中的Content-Encoding字段,值爲 gzip
    在這裏插入圖片描述

負載均衡

負載均衡是Nginx 比較經常使用的一個功能,可優化資源利用率,最大化吞吐量,減小延遲,確保容錯配置,將流量分配到多個後端服務器

幾種常見的策略:

  • 輪詢(默認),請求過來後,Nginx 隨機分配流量到任一服務器
upstream backend {
    server 127.0.0.1:3000;
    server 127.0.0.1:3001;
}
複製代碼
  • weight=number 設置服務器的權重,默認爲1,權重大的會被優先分配
upstream backend {
    server 127.0.0.1:3000 weight=2;
    server 127.0.0.1:3001 weight=1;
}
複製代碼
  • backup 標記爲備份服務器。當主服務器不可用時,將傳遞與備份服務器的鏈接
upstream backend {
    server 127.0.0.1:3000 backup;
    server 127.0.0.1:3001;
}
複製代碼
  • ip_hash 保持會話,保證同一客戶端始終訪問一臺服務器
upstream backend {
    ip_hash;  
    server 127.0.0.1:3000 backup;
    server 127.0.0.1:3001;
}
複製代碼
  • least_conn 優先分配最少鏈接數的服務器,避免服務器超載請求過多
upstream backend {
    least_conn;
    server 127.0.0.1:3000;
    server 127.0.0.1:3001;
}
複製代碼

當咱們須要代理一個集羣時候能夠經過下面這種方式實現

http {

    upstream backend {
        server 127.0.0.1:3000;
        server 127.0.0.1:3001;
    }

    ...
    server {
        listen      9000;
        server_name localhost;
        
        location / {
            proxy_set_header Host $http_host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Scheme $scheme;
            
            proxy_pass backend; 
        }
    }
}
複製代碼
相關文章
相關標籤/搜索