一.多套業(yè)務(wù)配置問題
在企業(yè)中析既,我們有很多的業(yè)務(wù)服務(wù)A躬贡,B,C等等眼坏,按照最最傳統(tǒng)的財(cái)大氣粗方式就是在一臺(tái)機(jī)器上搭建一個(gè)Nginx拂玻,并且一個(gè)Nginx只為一個(gè)業(yè)務(wù)進(jìn)行服務(wù),如下圖所示宰译,我們有3個(gè)業(yè)務(wù)服務(wù)檐蚜,我們就在3個(gè)機(jī)器上搭建3個(gè)Nginx,這顯然是很浪費(fèi)資源的一種不合理方式沿侈。
虛擬主機(jī)方式
??虛擬主機(jī)的方式是指闯第,我們?cè)谕粋€(gè)Nginx上運(yùn)行多套單獨(dú)服務(wù),而且這些服務(wù)是獨(dú)立的缀拭,如下圖所示:
虛擬主機(jī)配置方式
方式一:基于主機(jī)多IP的方式
??基于主機(jī)多IP的方式有兩種:
1.1:多網(wǎng)卡多IP的方式
1.2:?jiǎn)尉W(wǎng)卡多IP的方式
單網(wǎng)卡多IP的關(guān)鍵實(shí)現(xiàn)步驟:
第一步:在單網(wǎng)卡上添加多個(gè)IP--ip a add ip地址 設(shè)備名
第二步:我們找到nginx.conf中的http中的include的配置咳短,找到其include的文件路徑
第三步:找到默認(rèn)配置文件,進(jìn)行復(fù)制蛛淋,將server中的listen進(jìn)行改動(dòng)诲泌,改為ip:port,在這里如果我們要為3個(gè)業(yè)務(wù)服務(wù)的話铣鹏,我們就設(shè)置三個(gè).conf的配置文件敷扫,每個(gè)配置文件中的ip不同即可。
第四步:nginx -s stop -c /etc/nginx/nginx.conf
nginx -s表示給nginx的主進(jìn)程發(fā)送信號(hào)诚卸,停止應(yīng)用葵第。-c表示啟動(dòng)的時(shí)候使用哪個(gè)配置文件。
方式二:基于端口的配置方式
關(guān)鍵實(shí)現(xiàn)步驟:
第一步:我們找到nginx.conf中的http中的include的配置合溺,找到其include的文件路徑
第二步:找到默認(rèn)配置文件卒密,進(jìn)行復(fù)制,將server中的listen 端口進(jìn)行改動(dòng)即可棠赛,每個(gè)配置文件中的端口不同即可哮奇。
第三步:nginx -tc /etc/nginx/nginx.conf 對(duì)剛才修改的配置文件進(jìn)行語(yǔ)法檢查
第四步:nginx -c /etc/nginx/nginx.conf 啟動(dòng)nginx
方式三:基于多個(gè)host名稱方式(多域名方式也是企業(yè)中最常用的方式)
關(guān)鍵實(shí)現(xiàn)步驟:
更改server_name:
server {
listen 80;
server_name zzm1.zzm1.com;
二.日志
??Nginx的日志類型有error.log和access_log兩類膛腐。error.log用于記錄錯(cuò)誤類型的日志,access_log記錄的是請(qǐng)求訪問的相關(guān)的日志鼎俘。Nginx使用了log_format把各種類型的變量進(jìn)行組織哲身,然后記錄到access_log當(dāng)中去。
??log_format只能配置到http模塊下贸伐,所以我們看到nginx.conf中勘天,會(huì)看到log_format的使用方式如下圖所示:
??log_format的語(yǔ)法規(guī)則是:
??log_format name [escape=default|json] string ...;
??其中l(wèi)og_format是關(guān)鍵字,name可以隨便命名
??前文提到了log_format組織了一堆變量捉邢,然后輸入到了日志文件中脯丝,這里所說的變量分為三種類型:
??HTTP請(qǐng)求變量 - arg_PARAMETER、http_HEADER伏伐、sent_http_HEADER
??內(nèi)置變量 - Nginx內(nèi)置的
??自定義變量 -自己定義的
??我們可以在nginx.conf中修改了對(duì)應(yīng)的變量之后使用nginx -s reload -c /etc/nginx/nginx.conf使配置文件生效宠进。更多的變量可以參考http://nginx.org/en/docs/http/ngx_http_core_module.html#var_status
三.模塊
??Nginx的模塊分為官方的模塊和第三方的模塊,我們可以通過命令行nginx -V看到很多的--with-XXXX藐翎,這些就是Nginx中的模塊材蹬。
http_stub_status_module模塊
??編譯選項(xiàng)--with-http_stub_status_module,用于展示Nginx當(dāng)前處理連接的狀態(tài)阱高。這個(gè)模塊默認(rèn)是沒有打開的赚导,它必須要用戶顯示的server和location模塊中進(jìn)行配置茬缩。
??我們?cè)趎ginx.conf中配置好后赤惊,通過IP:PORT/mystatus進(jìn)行訪問,會(huì)看到以下結(jié)果:
??第一行表示當(dāng)前活躍的連接數(shù)凰锡,28 28 19分別表示的未舟,Nginx當(dāng)前接受的握手次數(shù),Nginx處理的連接數(shù)掂为,總的請(qǐng)求數(shù)裕膀。
random_index模塊
image.png該模塊使用的比較少,它表示是從目錄中隨機(jī)選取一個(gè)主頁(yè)勇哗。語(yǔ)法規(guī)則 random_index on | off昼扛,默認(rèn)情況下是random_index off;只能放在location的上下文中。
http_sub模塊
這個(gè)模塊也用的不多欲诺,它主要用于對(duì)http的響應(yīng)內(nèi)容作替換抄谐。包含了很多用法:
??sub_filter string replacement 默認(rèn)是不開啟的,可以用在http,server,location中,作用是替換html中的字符扰法。
??sub_filter_last_modified on | off蛹含,默認(rèn)是off,可以用在http,server,location中塞颁,作用是否阻止response header中寫入Last-Modified浦箱,防止緩存吸耿,默認(rèn)是off,即防止緩存酷窥。
??sub_filter_once on | off咽安,默認(rèn)是on,可以用在http,server,location中,作用sub_filter指令是執(zhí)行一次竖幔,還是重復(fù)執(zhí)行板乙,默認(rèn)是只執(zhí)行一次。
四.請(qǐng)求限制
??Nginx中可以對(duì)連接頻率和請(qǐng)求頻率做限制拳氢。其中連接頻率限制的模塊是limit_conn_module募逞,請(qǐng)求頻率限制的模塊是limit_req_module。
??請(qǐng)求和連接到底有什么區(qū)別呢馋评?我們知道HTTP協(xié)議是建立在TCP協(xié)議之上的放接,客戶端在向服務(wù)端發(fā)起請(qǐng)求的時(shí)候,必須先建立三次握手連接留特,建立完連接之后才開始發(fā)送請(qǐng)求纠脾,為了保持這個(gè)連接我們使用FIN和ACK,這樣就可以在一個(gè)連接中多次發(fā)起請(qǐng)求蜕青,因此我們可以說HTTP請(qǐng)求建立在一次TCP連接基礎(chǔ)上苟蹈,一次TCP請(qǐng)求至少產(chǎn)生一次HTTP請(qǐng)求。
??連接限制的語(yǔ)法:
??定義空間:
??limit_conn_zone key zone=name:size 默認(rèn)是沒有的右核,只能在http中配置慧脱,如果說我們想對(duì)用戶的IP地址做限制,那么這里的key我們可以配置成$remote_addr贺喝,這里的name可以隨便命名菱鸥,size設(shè)置大小
??limit_conn zone number;這里的zone必須和上面的limit_conn_zone中的name對(duì)應(yīng),number表示的是連接數(shù)躏鱼,默認(rèn)是沒有的氮采,可以在http,server,location中配置。
??請(qǐng)求限制的語(yǔ)法:
??定義空間:
??limit_req_zone key zone=name:size rate=rate默認(rèn)是沒有的染苛,只能在http中配置
??limit_req zone name [burst=number] [nodelay];這里的zone必須和上面的limit_req_zone中的name對(duì)應(yīng)鹊漠,number表示的是連接數(shù),默認(rèn)是沒有的茶行,可以在http,server,location中配置;burst爆發(fā)的意思躯概,這個(gè)配置的意思是設(shè)置一個(gè)大小為N的緩沖區(qū),當(dāng)有大量請(qǐng)求(爆發(fā))過來時(shí)拢军,超過了訪問頻次限制的請(qǐng)求可以先放到這個(gè)緩沖區(qū)內(nèi);nodelay楞陷,如果設(shè)置,超過訪問頻次而且緩沖區(qū)也滿了的時(shí)候就會(huì)直接返回503茉唉,如果沒有設(shè)置固蛾,則所有請(qǐng)求會(huì)等待排隊(duì).
??實(shí)戰(zhàn)
??$binary_remote_addr是限制同一客戶端ip地址,binary_remote_addr和remote_addr其實(shí)是一樣的结执,但是binary_remote_addr要更節(jié)省空間。1m 可以儲(chǔ)存 32000 個(gè)并發(fā)會(huì)話艾凯。zone=req_zone:1m表示生成一個(gè)大小為1M献幔,名字為req_one的內(nèi)存區(qū)域,用來存儲(chǔ)訪問的頻次信息;rate=1r/s表示允許相同標(biāo)識(shí)的客戶端的訪問頻次趾诗,這里限制的是每秒1次蜡感,還可以有比如30r/m的。這里我使用abtest來演示一下各種情況:
??測(cè)試一:
配置每秒鐘最多一次請(qǐng)求:
limit_conn_zone $binary_remote_addr zone=conn_zone:1m;
limit_req_zone $binary_remote_addr zone=req_zone:1m rate=1r/s;
server {
listen 80;
server_name localhost;
#charset koi8-r;
#access_log /var/log/nginx/host.access.log main;
location /mystatus{
stub_status;
}
location / {
root /usr/share/nginx/html;
#limit_conn conn_zone 1;
#limit_req zone=req_zone burst=3 nodelay;
#limit_req zone=req_zone burst=3;
limit_req zone=req_zone;
index index.html index.htm;
}
使用abtest發(fā)起請(qǐng)求恃泪,設(shè)置并發(fā)數(shù)20郑兴,發(fā)起20次請(qǐng)求。測(cè)試結(jié)果贝乎,成功1次情连,失敗19次办龄,符合預(yù)期:
查看nginx錯(cuò)誤日志姆怪,圖中剛好有19個(gè)error記錄,而且是被限制了黑低,符合預(yù)期:
??測(cè)試二:
設(shè)置一個(gè)大小為3的緩沖區(qū)锤灿,超過訪問頻次限制的請(qǐng)求將會(huì)放入到緩沖區(qū)中:
limit_conn_zone $binary_remote_addr zone=conn_zone:1m;
limit_req_zone $binary_remote_addr zone=req_zone:1m rate=1r/s;
server {
listen 80;
server_name localhost;
#charset koi8-r;
#access_log /var/log/nginx/host.access.log main;
location /mystatus{
stub_status;
}
location / {
root /usr/share/nginx/html;
#limit_conn conn_zone 1;
limit_req zone=req_zone burst=3 nodelay;
#limit_req zone=req_zone burst=3;
#limit_req zone=req_zone;
index index.html index.htm;
}
使用abtest發(fā)起請(qǐng)求挽拔,設(shè)置并發(fā)數(shù)20,發(fā)起20次請(qǐng)求但校。測(cè)試結(jié)果螃诅,成功4次,失敗16次始腾,符合預(yù)期州刽,因?yàn)榈谝淮纬晒罂罩矗^了請(qǐng)求限制浪箭,放了3個(gè)請(qǐng)求到緩沖區(qū)中,所以總共成功4個(gè):
查看nginx錯(cuò)誤日志辨绊,圖中剛好有16個(gè)error記錄奶栖,而且是被限制了,符合預(yù)期:
??測(cè)試三:
設(shè)置最大連接數(shù)為1:
limit_conn conn_zone 1;
#limit_req zone=req_zone burst=3 nodelay;
#limit_req zone=req_zone burst=3;
#limit_req zone=req_zone;
index index.html index.htm;
使用abtest發(fā)起請(qǐng)求门坷,設(shè)置并發(fā)數(shù)20宣鄙,發(fā)起20次請(qǐng)求。測(cè)試結(jié)果默蚌,成功20次冻晤,失敗0次,符合預(yù)期:
查看nginx錯(cuò)誤日志绸吸,無任何錯(cuò)誤日志鼻弧,符合預(yù)期设江。
五.Nginx的訪問控制
基于IP的訪問控制
??nginx的http_access_module模塊實(shí)現(xiàn)的,相關(guān)語(yǔ)法如下圖所示:
??使用方式之阻止某一個(gè)IP訪問頁(yè)面
??配置nginx.conf
server {
listen 80;
server_name localhost;
#charset koi8-r;
#access_log /var/log/nginx/host.access.log main;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
location ~ ^/admin.html {
root /usr/share/nginx/html;
deny 180.158.232.219;
allow all;
index index.html index.htm;
}
~表示模式匹配攘轩,這里我們表示凡是訪問admin.html的請(qǐng)求叉存,阻止180.158.232.219的訪問,同時(shí)允許所有的IP訪問度帮。結(jié)果如下圖所示:
??使用方式之只允許某一個(gè)IP訪問頁(yè)面
??配置nginx.conf
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
# location ~ ^/admin.html {
# root /usr/share/nginx/html;
# deny 180.158.232.219;
# allow all;
# index index.html index.htm;
# }
location ~ ^/admin.html {
root /usr/share/nginx/html;
allow 180.158.232.219;
deny all;
index index.html index.htm;
}
請(qǐng)求成功:
??那么http_access_module有什么局限性呢歼捏?
??如何解決呢
??http_x_forwarded_for方式
??X-Forwarded-For 是一個(gè)擴(kuò)展頭。HTTP/1.1(RFC 2616)協(xié)議并沒有對(duì)它的定義笨篷,它最開始是由 Squid 這個(gè)緩存代理軟件引入瞳秽,用來表示 HTTP 請(qǐng)求端真實(shí) IP,現(xiàn)在已經(jīng)成為事實(shí)上的標(biāo)準(zhǔn)率翅,被各大 HTTP 代理寂诱、負(fù)載均衡等轉(zhuǎn)發(fā)服務(wù)廣泛使用.如果一個(gè) HTTP 請(qǐng)求到達(dá)服務(wù)器之前,經(jīng)過了三個(gè)代理 Proxy1安聘、Proxy2痰洒、Proxy3,IP 分別為 IP1浴韭、IP2丘喻、IP3,用戶真實(shí) IP 為 IP0念颈,那么按照 XFF 標(biāo)準(zhǔn)泉粉,服務(wù)端最終會(huì)收到以下信息X-Forwarded-For: IP0, IP1, IP2。是不是這種方式就很穩(wěn)了呢榴芳?答案是否定的嗡靡。因?yàn)閄-Forwarded-For是一個(gè)協(xié)議要求的,并不是所有的代理廠商或者CDN廠商會(huì)按照要求來做窟感,而且這個(gè)X-Forwarded-For作為頭信息極有可能被客戶端修改讨彼。
??基于用戶的信任登錄
??是nginx的http_auth_basic_module模塊實(shí)現(xiàn)的,使用方式可以具體參考http://nginx.org/en/docs/http/ngx_http_auth_basic_module.html 這里不再贅述
??Nginx的基礎(chǔ)篇就講到這里柿祈,歡迎大家指正哈误,下一篇文章我將介紹如何使用Nginx作為靜態(tài)資源Web服務(wù)。