Nginx基礎(chǔ)篇----虛擬主機(jī)、日志、模塊、請(qǐng)求限制

一.多套業(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)資源的一種不合理方式。


傳統(tǒng)的業(yè)務(wù)服務(wù)方式

虛擬主機(jī)方式

??虛擬主機(jī)的方式是指,我們?cè)谕粋€(gè)Nginx上運(yùn)行多套單獨(dú)服務(wù),而且這些服務(wù)是獨(dú)立的,如下圖所示:


虛擬主機(jī)方式

虛擬主機(jī)配置方式

方式一:基于主機(jī)多IP的方式

基于主機(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)行語法檢查
第四步:nginx -c /etc/nginx/nginx.conf 啟動(dòng)nginx

方式三:基于多個(gè)host名稱方式(多域名方式也是企業(yè)中最常用的方式)

基于多個(gè)host名稱方式

關(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的語法規(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è)。語法規(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)求。



??連接限制的語法:
??定義空間:
??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)求限制的語法:
??定義空間:
??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)語法如下圖所示:

相關(guān)語法

??使用方式之阻止某一個(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與remote_addr的比較

??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ù)。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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

  • 大多數(shù) Nginx 新手都會(huì)頻繁遇到這樣一個(gè)困惑,那就是當(dāng)同一個(gè)location配置塊使用了多個(gè) Nginx 模塊...
    SkTj閱讀 8,246評(píng)論 0 12
  • 《老男孩Linux運(yùn)維》筆記 隱藏Nginx軟件版本號(hào) 一般來說,軟件的漏洞都和版本有關(guān)。因此要盡量隱藏對(duì)訪問用戶...
    Zhang21閱讀 3,891評(píng)論 0 28
  • Nginx簡(jiǎn)介 解決基于進(jìn)程模型產(chǎn)生的C10K問題,請(qǐng)求時(shí)即使無狀態(tài)連接如web服務(wù)都無法達(dá)到并發(fā)響應(yīng)量級(jí)一萬的現(xiàn)...
    魏鎮(zhèn)坪閱讀 2,214評(píng)論 0 9
  • 1.簡(jiǎn)介: ? Nginx:engine X ,2002年,開源,商業(yè)版? http協(xié)議:web服務(wù)器(類似于ht...
    尛尛大尹閱讀 2,011評(píng)論 0 3
  • I/O模型Nginx介紹Nginx的安裝和目錄結(jié)構(gòu)Nginx的配置Nginx的編譯安裝 一、I/O模型 (一)I/...
    哈嘍別樣閱讀 973評(píng)論 0 4

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