Nginx基礎篇----虛擬主機、日誌、模塊、請求限制

一.多套業務配置問題

在企業中,我們有很多的業務服務A,B,C等等,按照最最傳統的財大氣粗方式就是在一臺機器上搭建一個Nginx,並且一個Nginx只爲一個業務進行服務,如下圖所示,我們有3個業務服務,我們就在3個機器上搭建3個Nginx,這顯然是很浪費資源的一種不合理方式。


虛擬主機方式

  虛擬主機的方式是指,我們在同一個Nginx上運行多套單獨服務,而且這些服務是獨立的,如下圖所示:


虛擬主機配置方式

方式一:基於主機多IP的方式


  基於主機多IP的方式有兩種:

1.1:多網卡多IP的方式

1.2:單網卡多IP的方式

單網卡多IP的關鍵實現步驟:

第一步:在單網卡上添加多個IP--ip a add ip地址 設備名
第二步:我們找到nginx.conf中的http中的include的配置,找到其include的文件路徑
第三步:找到默認配置文件,進行復制,將server中的listen進行改動,改爲ip:port,在這裏如果我們要爲3個業務服務的話,我們就設置三個.conf的配置文件,每個配置文件中的ip不同即可。
第四步:nginx -s stop -c /etc/nginx/nginx.conf
nginx -s表示給nginx的主進程發送信號,停止應用。-c表示啓動的時候使用哪個配置文件。

方式二:基於端口的配置方式

關鍵實現步驟:

第一步:我們找到nginx.conf中的http中的include的配置,找到其include的文件路徑
第二步:找到默認配置文件,進行復制,將server中的listen 端口進行改動即可,每個配置文件中的端口不同即可。
第三步:nginx -tc /etc/nginx/nginx.conf 對剛纔修改的配置文件進行語法檢查
第四步:nginx -c /etc/nginx/nginx.conf 啓動nginx

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

關鍵實現步驟:

更改server_name

server {
    listen       80;
    server_name  zzm1.zzm1.com;

二.日誌

  Nginx的日誌類型有error.log和access_log兩類。error.log用於記錄錯誤類型的日誌,access_log記錄的是請求訪問的相關的日誌。Nginx使用了log_format把各種類型的變量進行組織,然後記錄到access_log當中去。
  log_format只能配置到http模塊下,所以我們看到nginx.conf中,會看到log_format的使用方式如下圖所示:


  log_format的語法規則是:
  log_format name [escape=default|json] string ...;
  其中log_format是關鍵字,name可以隨便命名
  前文提到了log_format組織了一堆變量,然後輸入到了日誌文件中,這裏所說的變量分爲三種類型:
  HTTP請求變量 - arg_PARAMETER、http_HEADER、sent_http_HEADER
  內置變量 - Nginx內置的
  自定義變量 -自己定義的
  我們可以在nginx.conf中修改了對應的變量之後使用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模塊

  編譯選項--with-http_stub_status_module,用於展示Nginx當前處理連接的狀態。這個模塊默認是沒有打開的,它必須要用戶顯示的server和location模塊中進行配置。



  我們在nginx.conf中配置好後,通過IP:PORT/mystatus進行訪問,會看到以下結果:



  第一行表示當前活躍的連接數,28 28 19分別表示的,Nginx當前接受的握手次數,Nginx處理的連接數,總的請求數。

random_index模塊

image.png該模塊使用的比較少,它表示是從目錄中隨機選取一個主頁。語法規則 random_index on | off,默認情況下是random_index off;只能放在location的上下文中。


http_sub模塊

這個模塊也用的不多,它主要用於對http的響應內容作替換。包含了很多用法:
  sub_filter string replacement 默認是不開啓的,可以用在http,server,location中,作用是替換html中的字符。
  sub_filter_last_modified on | off,默認是off,可以用在http,server,location中,作用是否阻止response header中寫入Last-Modified,防止緩存,默認是off,即防止緩存。
  sub_filter_once on | off,默認是on,可以用在http,server,location中,作用sub_filter指令是執行一次,還是重複執行,默認是隻執行一次。

四.請求限制

  Nginx中可以對連接頻率和請求頻率做限制。其中連接頻率限制的模塊是limit_conn_module,請求頻率限制的模塊是limit_req_module。
  請求和連接到底有什麼區別呢?我們知道HTTP協議是建立在TCP協議之上的,客戶端在向服務端發起請求的時候,必須先建立三次握手連接,建立完連接之後纔開始發送請求,爲了保持這個連接我們使用FIN和ACK,這樣就可以在一個連接中多次發起請求,因此我們可以說HTTP請求建立在一次TCP連接基礎上,一次TCP請求至少產生一次HTTP請求。



  連接限制的語法:
  定義空間:
  limit_conn_zone key zone=name:size 默認是沒有的,只能在http中配置,如果說我們想對用戶的IP地址做限制,那麼這裏的key我們可以配置成$remote_addr,這裏的name可以隨便命名,size設置大小
  limit_conn zone number;這裏的zone必須和上面的limit_conn_zone中的name對應,number表示的是連接數,默認是沒有的,可以在http,server,location中配置。
  請求限制的語法:
  定義空間:
  limit_req_zone key zone=name:size rate=rate默認是沒有的,只能在http中配置
  limit_req zone name [burst=number] [nodelay];這裏的zone必須和上面的limit_req_zone中的name對應,number表示的是連接數,默認是沒有的,可以在http,server,location中配置;burst爆發的意思,這個配置的意思是設置一個大小爲N的緩衝區,當有大量請求(爆發)過來時,超過了訪問頻次限制的請求可以先放到這個緩衝區內;nodelay,如果設置,超過訪問頻次而且緩衝區也滿了的時候就會直接返回503,如果沒有設置,則所有請求會等待排隊.

  實戰


  $binary_remote_addr是限制同一客戶端ip地址,binary_remote_addr和remote_addr其實是一樣的,但是binary_remote_addr要更節省空間。1m 可以儲存 32000 個併發會話。zone=req_zone:1m表示生成一個大小爲1M,名字爲req_one的內存區域,用來存儲訪問的頻次信息;rate=1r/s表示允許相同標識的客戶端的訪問頻次,這裏限制的是每秒1次,還可以有比如30r/m的。這裏我使用abtest來演示一下各種情況:

  測試一:

配置每秒鐘最多一次請求:

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發起請求,設置併發數20,發起20次請求。測試結果,成功1次,失敗19次,符合預期:



查看nginx錯誤日誌,圖中剛好有19個error記錄,而且是被限制了,符合預期:


  測試二:

設置一個大小爲3的緩衝區,超過訪問頻次限制的請求將會放入到緩衝區中:

    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發起請求,設置併發數20,發起20次請求。測試結果,成功4次,失敗16次,符合預期,因爲第一次成功後,超過了請求限制,放了3個請求到緩衝區中,所以總共成功4個:



查看nginx錯誤日誌,圖中剛好有16個error記錄,而且是被限制了,符合預期:


  測試三:

設置最大連接數爲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發起請求,設置併發數20,發起20次請求。測試結果,成功20次,失敗0次,符合預期:



查看nginx錯誤日誌,無任何錯誤日誌,符合預期。

五.Nginx的訪問控制

基於IP的訪問控制

  nginx的http_access_module模塊實現的,相關語法如下圖所示:


  使用方式之阻止某一個IP訪問頁面
  配置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的請求,阻止180.158.232.219的訪問,同時允許所有的IP訪問。結果如下圖所示:


  使用方式之只允許某一個IP訪問頁面
  配置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;
    }

請求成功:


  那麼http_access_module有什麼侷限性呢?

  如何解決呢

  http_x_forwarded_for方式

  X-Forwarded-For 是一個擴展頭。HTTP/1.1(RFC 2616)協議並沒有對它的定義,它最開始是由 Squid 這個緩存代理軟件引入,用來表示 HTTP 請求端真實 IP,現在已經成爲事實上的標準,被各大 HTTP 代理、負載均衡等轉發服務廣泛使用.如果一個 HTTP 請求到達服務器之前,經過了三個代理 Proxy1、Proxy2、Proxy3,IP 分別爲 IP1、IP2、IP3,用戶真實 IP 爲 IP0,那麼按照 XFF 標準,服務端最終會收到以下信息X-Forwarded-For: IP0, IP1, IP2。是不是這種方式就很穩了呢?答案是否定的。因爲X-Forwarded-For是一個協議要求的,並不是所有的代理廠商或者CDN廠商會按照要求來做,而且這個X-Forwarded-For作爲頭信息極有可能被客戶端修改。

  基於用戶的信任登錄

  是nginx的http_auth_basic_module模塊實現的,使用方式可以具體參考http://nginx.org/en/docs/http/ngx_http_auth_basic_module.html 這裏不再贅述
  Nginx的基礎篇就講到這裏,歡迎大家指正,下一篇文章我將介紹如何使用Nginx作爲靜態資源Web服務。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章