一、什么是正向代理和反向代理:
A同學在大眾創(chuàng)業(yè)的大時代背景下開啟他的創(chuàng)業(yè)之路,目前他遇到的最大的一個問題就是啟動資金,于是他決定去找馬云爸爸借錢,可想而知,最后碰一鼻子灰回來了,情急之下,他想到一個辦法,找關系開后門,經(jīng)過一番消息打探,原來A同學的大學老師王老師是馬云的同學,于是A同學找到王老師,托王老師幫忙去馬云那借500萬過來,當然最后事成了。不過馬云并不知道這錢是A同學借的,馬云是借給王老師的,最后由王老師轉交給A同學。這里的王老師在這個過程中扮演了一個非常關鍵的角色,就是代理,也可以說是正向代理,王老師代替A同學辦這件事,這個過程中,真正借錢的人是誰,馬云是不知道的,這點非常關鍵。
我們常說的代理也就是只正向代理,正向代理的過程,它隱藏了真實的請求客戶端,服務端不知道真實的客戶端是誰,客戶端請求的服務都被代理服務器代替來請求,某些科學上網(wǎng)工具扮演的就是典型的正向代理角色。用瀏覽器訪問http://www.google.com時,被殘忍的block,于是你可以在國外搭建一臺代理服務器,讓代理幫我去請求google.com,代理把請求返回的相應結構再返回給我。

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

nginx能實現(xiàn)負載均衡,什么是負載均衡呢?就是我的項目部署在不同的服務器上,但是通過統(tǒng)一的域名進入,nginx則對請求進行分發(fā),減輕了服務器的壓力。
在上面這兩種情況下,nginx服務器的作用都只是作為分發(fā)服務器,真正的內(nèi)容,我們可以放在其他的服務器上,這樣來,還能起到一層安全隔壁的作用,nginx作為隔離層。
其次,nginx還能解決跨域的問題。
二、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. 一份配置清單例析
按照前面文章,給出一份簡要的清單配置舉例:

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 這個指令的含義就很容易了

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 {
}
}