Nginx基本功能及其原理

一、什么是正向代理和反向代理:

A同學在大眾創(chuàng)業(yè)的大時代背景下開啟他的創(chuàng)業(yè)之路,目前他遇到的最大的一個問題就是啟動資金,于是他決定去找馬云爸爸借錢,可想而知,最后碰一鼻子灰回來了,情急之下,他想到一個辦法,找關系開后門,經(jīng)過一番消息打探,原來A同學的大學老師王老師是馬云的同學,于是A同學找到王老師,托王老師幫忙去馬云那借500萬過來,當然最后事成了。不過馬云并不知道這錢是A同學借的,馬云是借給王老師的,最后由王老師轉交給A同學。這里的王老師在這個過程中扮演了一個非常關鍵的角色,就是代理,也可以說是正向代理,王老師代替A同學辦這件事,這個過程中,真正借錢的人是誰,馬云是不知道的,這點非常關鍵。

我們常說的代理也就是只正向代理,正向代理的過程,它隱藏了真實的請求客戶端,服務端不知道真實的客戶端是誰,客戶端請求的服務都被代理服務器代替來請求,某些科學上網(wǎng)工具扮演的就是典型的正向代理角色。用瀏覽器訪問http://www.google.com時,被殘忍的block,于是你可以在國外搭建一臺代理服務器,讓代理幫我去請求google.com,代理把請求返回的相應結構再返回給我。

圖1.1: 正向代理示意圖

大家都有過這樣的經(jīng)歷,撥打10086客服電話,可能一個地區(qū)的10086客服有幾個或者幾十個,你永遠都不需要關心在電話那頭的是哪一個,叫什么,男的,還是女的,漂亮的還是帥氣的,你都不關心,你關心的是你的問題能不能得到專業(yè)的解答,你只需要撥通了10086的總機號碼,電話那頭總會有人會回答你,只是有時慢有時快而已。那么這里的10086總機號碼就是我們說的反向代理??蛻舨恢勒嬲峁┓杖说氖钦l。反向代理隱藏了真實的服務端,當我們請求ww.baidu.com 的時候,就像撥打10086一樣,背后可能有成千上萬臺服務器為我們服務,但具體是哪一臺,你不知道,也不需要知道,你只需要知道反向代理服務器是誰就好了,www.baidu.com 就是我們的反向代理服務器,反向代理服務器會幫我們把請求轉發(fā)到真實的服務器那里去。Nginx就是性能非常好的反向代理服務器,用來做負載均衡。

兩者的區(qū)別在于代理的對象不一樣: 正向代理是為客戶端代理,反向代理是為服務端代理。

圖1.2: 反向代理示意圖

nginx能實現(xiàn)負載均衡,什么是負載均衡呢?就是我的項目部署在不同的服務器上,但是通過統(tǒng)一的域名進入,nginx則對請求進行分發(fā),減輕了服務器的壓力。

在上面這兩種情況下,nginx服務器的作用都只是作為分發(fā)服務器,真正的內(nèi)容,我們可以放在其他的服務器上,這樣來,還能起到一層安全隔壁的作用,nginx作為隔離層。

其次,nginx還能解決跨域的問題。

二、Nginx配置文件的整體結構

圖2.1: nginx配置文件的整體結構

1. 從圖中可以看出主要包含以下幾大部分內(nèi)容:

  • 全局塊

該部分配置主要影響Nginx全局,通常包括下面幾個部分:

配置運行Nginx服務器用戶(組)
worker process數(shù)
Nginx進程PID存放路徑
錯誤日志的存放路徑
配置文件的引入

  • events塊

該部分配置主要影響Nginx服務器與用戶的網(wǎng)絡連接,主要包括:

設置網(wǎng)絡連接的序列化
是否允許同時接收多個網(wǎng)絡連接
事件驅(qū)動模型的選擇
最大連接數(shù)的配置

  • http塊

定義MIMI-Type
自定義服務日志
允許sendfile方式傳輸文件
連接超時時間
單連接請求數(shù)上限

  • server塊

配置網(wǎng)絡監(jiān)聽
基于名稱的虛擬主機配置
基于IP的虛擬主機配置

  • location塊

location配置
請求根目錄配置
更改location的URI
網(wǎng)站默認首頁配置

2. 一份配置清單例析

按照前面文章,給出一份簡要的清單配置舉例:

圖2.1:nginx配置舉例

3. 配置運行Nginx服務器用戶(組)

指令格式:user user [group];

user:指定可以運行Nginx服務器的用戶

group:可選項,可以運行Nginx服務器的用戶組

如果user指令不配置或者配置為 user nobody nobody ,則默認所有用戶都可以啟動Nginx進程

4. worker_process數(shù)配置

Nginx服務器實現(xiàn)并發(fā)處理服務的關鍵,指令格式:worker_processes number | auto;

number:Nginx進程最多可以產(chǎn)生的worker process數(shù)

auto:Nginx進程將自動檢測

按照上文中的配置清單的實驗,我們給worker_processes配置的數(shù)目是:3,啟動Nginx服務器后,我們可以后臺看一下主機上的Nginx進程情況:

ps -aux | grep nginx

很明顯,理解 worker_processes 這個指令的含義就很容易了

圖2.2:查看nginx進程情況

5. Nginx進程PID存放路徑

Nginx進程是作為系統(tǒng)守護進程在運行,需要在某文件中保存當前運行程序的主進程號,Nginx支持該保存文件路徑的自定義

指令格式:pid file;

file:指定存放路徑和文件名稱

如果不指定默認置于路徑 logs/nginx.pid

6. 錯誤日志的存放路徑

指定格式:error_log file | stderr;

file:日志輸出到某個文件file

stderr:日志輸出到標準錯誤輸出

7. 配置文件的引入

指令格式:include file;

該指令主要用于將其他的Nginx配置或者第三方模塊的配置引用到當前的主配置文件中

8. 設置網(wǎng)絡連接的序列化

指令格式:accept_mutex on | off;

該指令默認為on狀態(tài),表示會對多個Nginx進程接收連接進行序列化,防止多個進程對連接的爭搶。

說到該指令,首先得闡述一下什么是所謂的"驚群問題",可以參考 WIKI百科的解釋。就Nginx的場景來解釋的話大致的意思就是:當一個新網(wǎng)絡連接來到時,多個worker進程會被同時喚醒,但僅僅只有一個進程可以真正獲得連接并處理之。如果每次喚醒的進程數(shù)目過多的話,其實是會影響一部分性能的。

所以在這里,如果accept_mutex on,那么多個worker將是以串行方式來處理,其中有一個worker會被喚醒;反之若accept_mutex off,那么所有的worker都會被喚醒,不過只有一個worker能獲取新連接,其它的worker會重新進入休眠狀態(tài)

這個值的開關與否其實是要和具體場景掛鉤的。

9. 是否允許同時接收多個網(wǎng)絡連接

指令格式:multi_accept on | off;

該指令默認為off狀態(tài),意指每個worker process 一次只能接收一個新到達的網(wǎng)絡連接。若想讓每個Nginx的worker process都有能力同時接收多個網(wǎng)絡連接,則需要開啟此配置

10. 事件驅(qū)動模型的選擇

指令格式:use model;

model模型可選擇項包括:select、poll、kqueue、epoll、rtsig等......

11. 最大連接數(shù)的配置

指令格式:worker_connections number;

number默認值為512,表示允許每一個worker process可以同時開啟的最大連接數(shù)

12. 定義MIME-Type

指令格式:

include mime.types;default_type mime-type;

MIME-Type指的是網(wǎng)絡資源的媒體類型,也即前端請求的資源類型

include指令將mime.types文件包含進來

cat mime.types 來查看mime.types文件內(nèi)容,我們發(fā)現(xiàn)其就是一個types結構,里面包含了各種瀏覽器能夠識別的MIME類型以及對應類型的文件后綴名字,如下所示:


13. 自定義服務日志

指令格式:

access_log path [format];

path:自定義服務日志的路徑 + 名稱

format:可選項,自定義服務日志的字符串格式。其也可以使用 log_format 定義的格式

14. 允許sendfile方式傳輸文件

指令格式:

sendfile on | off;sendfile_max_chunk size;

前者用于開啟或關閉使用sendfile()傳輸文件,默認off

后者指令若size>0,則Nginx進程的每個worker process每次調(diào)用sendfile()傳輸?shù)臄?shù)據(jù)了最大不能超出此值;若size=0則表示不限制。默認值為0

15. 連接超時時間配置

指令格式:

keepalive_timeout timeout [header_timeout];

timeout 表示server端對連接的保持時間,默認75秒

header_timeout 為可選項,表示在應答報文頭部的 Keep-Alive 域設置超時時間:"Keep-Alive : timeout = header_timeout"

16. 單連接請求數(shù)上限

指令格式:

keepalive_requests number;

該指令用于限制用戶通過某一個連接向Nginx服務器發(fā)起請求的次數(shù)

17. 配置網(wǎng)絡監(jiān)聽

指令格式:

第一種:配置監(jiān)聽的IP地址:listen IP[:PORT];

第二種:配置監(jiān)聽的端口:listen PORT;

實際舉例:

listen 192.168.31.177:8080;   # 監(jiān)聽具體IP和具體端口上的連接
listen 192.168.31.177;   # 監(jiān)聽IP上所有端口上的連接
listen 8080;     # 監(jiān)聽具體端口上的所有IP的連接

18. 基于名稱和IP的虛擬主機配置

指令格式:

server_name name1 name2 ...

name可以有多個并列名稱,而且此處的name支持正則表達式書寫

實際舉例:

server_name ~^www\d+\.myserver\.com$

此時表示該虛擬主機可以接收類似域名 www1.myserver.com 等的請求而拒絕 www.myserver.com 的域名請求,所以說用正則表達式可以實現(xiàn)更精準的控制

至于基于IP的虛擬主機配置比較簡單,不再太贅述:

指令格式:

server_name IP地址

19. location配置

指令格式為:

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

這里的uri分為標準uri和正則uri,兩者的唯一區(qū)別是uri中是否包含正則表達式(URI,是uniform resource identifier,統(tǒng)一資源標識符,用來唯一的標識一個資源。而URL是uniform resource locator,統(tǒng)一資源定位器,它是一種具體的URI,即URL可以用來標識一個資源,而且還指明了如何locate這個資源。)

uri前面的方括號中的內(nèi)容是可選項,解釋如下:

"=":用于標準uri前,要求請求字符串與uri嚴格匹配,一旦匹配成功則停止

"~":用于正則uri前,并且區(qū)分大小寫

"~*":用于正則uri前,但不區(qū)分大小寫

"^~":用于標準uri前,要求Nginx找到標識uri和請求字符串匹配度最高的location后,立即使用此location處理請求,而不再使用location塊中的正則uri和請求字符串做匹配

20. 請求根目錄配置

指令格式:

root path;

path:Nginx接收到請求以后查找資源的根目錄路徑

當然,還可以通過alias指令來更改location接收到的URI請求路徑,指令為:

alias path; # path為修改后的根路徑

21. 設置網(wǎng)站的默認首頁

指令格式:

index file ......

file可以包含多個用空格隔開的文件名,首先找到哪個頁面,就使用哪個頁面響應請求

其實Nginx的配置真的是很簡單,對于新手們來說其實最大的問題就是Nginx所有的配置都是基于配置文件和各個模塊語法的,這些看著給人的感覺好復雜的樣子,其實理解了各個模塊的意義和基本語法后就變的尤為簡單了!

三、Nginx配置SSL及HTTP跳轉到HTTPS

隨著微信小程序和appstore對ssl安全的需求,越來越多的網(wǎng)站和app需要支持SSL功能,需要開啟https的方式來打開網(wǎng)站或傳輸數(shù)據(jù)。

ssl證書網(wǎng)上可以找到收費和免費的申請,nginx配置如下:

Nginx配置SSL并把Http跳轉到Https,需要修改Nginx.conf配置文件:

# Settings for a TLS enabled server.

# 如果是http請求默認訪問80端口,此時return強行301重定向到https://www.joyitsai.com

server {

  listen 80;

  server_name www.joyitsai.com;

  return 301 https://www.joyitsai.com$request_uri;

  # 把http重定向到https使用了nginx的重定向命令,之前老版本的nginx可能使用了以下類似的格式:
  # rewrite ^/(.*)$ http://www.joyitsai.com/$1 permanent;
  # 或者:
  # rewrite ^ http://www.joyitsai.com$request_uri? permanent;
  # 現(xiàn)在nginx新版本已經(jīng)換了種寫法,上面這些已經(jīng)不再推薦。現(xiàn)在網(wǎng)上可能還有很多文章寫的是第一種。
  # 新的寫法比較推薦方式是:return 301 https://www.joyitsai.com$request_uri;
}

server {

  listen 443;
  server_name www.joyitsai.com;
  root /data/release/weapp/uploadFiles;

  # 開啟ssl功能
  ssl on;

  # 配置ssl證書,直接用.pem和.key文件的絕對路徑

  ssl_certificate/data/release/nginx/1535530361992.pem;

  ssl_certificate_key/data/release/nginx/1535530361992.key;

  ssl_session_timeout 5m;

  ssl_protocols TLSv1 TLSv1.1 TLSv1.2;

  ssl_ciphers ECDHE - RSA - AES128 - GCM - SHA256: ECDHE: ECDH: AES: HIGH: !NULL: !aNULL: !MD5: !ADH: !RC4;

  ssl_prefer_server_ciphers on;

  location / {

     proxy_pass http://app_weapp;

     proxy_http_version 1.1;

     proxy_set_header Upgrade $http_upgrade;

     proxy_set_header Connection 'upgrade';

     proxy_set_header Host $host;

     proxy_cache_bypass $http_upgrade;

  }

  location /images/ {
    autoindex on;
  }

  # 配置uri, ~用于正則uri前,其中.(png|jpg)為正則表達式,如果后綴是.png或.jpg的url請求,則匹配成功
  # root用于配置接收到請求以后查找資源的根目錄路徑

  location ~ \.(png|jpg) {
     root /data/release/weapp/uploadFiles;
  }

  error_page 404 /404.html;

  location = /40x.html {
  }

  error_page 500 502 503 504 /50x.html;

  location = /50x.html {
  }
}
最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容