Nginx管理(二)

1、Nginx虛擬主機

  一個web服務器軟件默認狀況下只能發佈一個web,由於一個web分享出去須要三個條件(IP、Port、Domain name)
  Nginx虛擬主機實現一個web服務器軟件發佈多個web
  虛擬主機就是將一臺物理服務器劃分紅多個「虛擬」的服務器,每一個虛擬主機均可以有獨立的域名和獨立的目錄。
  如今不少公司出售的產品——「網站空間」,就是基於虛擬主機來賣的。價格和使用成本遠遠低於購買雲服務器。php

  案例:同時發佈兩個網站html

DocumentRoot /usr/local/nginx/html/web1 
DocumentRoot /usr/local/nginx/html/web2

  

一、基於IP的虛擬主機

  要測試基於IP的虛擬主機,必需要有兩個IP的虛擬機、DocumentRoot存在、索引頁index.html配置。
  場景是:每一個網站都須要一個IP。
  缺點是:須要多個IP,若是是公網IP,每一個IP都須要付費。前端

(1) 配置文件快速重置

  在這裏須要知道nginx.conf文件是有一個默認備份文件的:nginx.conf.default,使用它能夠迅速完成配置重置。node

$ pwd
/usr/local/nginx/conf
$ cp nginx.conf nginx.conf.bak
$ cp nginx.conf.default nginx.conf

# 僅保留有用的配置
sed -i "/#/d" nginx.conf      # 有#的都刪除
sed -i "/^$/d" nginx.conf     # 有空行的都刪除

(2)nginx.conf配置

worker_processes  1;
events {
    worker_connections  1024;
}
http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    keepalive_timeout  65;
    server {
        listen       192.168.31.42:80;
        server_name  localhost;
        location / {
            root   html/web1;
            index  index.html index.htm;
        }
    }
    server {
        listen       192.168.31.52:80;
        server_name  localhost;
        location / {
            root   html/web2;
            index  index.html index.htm;
        }
    }
}

(3)準備環境配置驗證

  兩個IP、DocumentRoot存在、索引頁index.html配置nginx

# 兩個ip除了建立虛機等方式外,還能夠配置虛擬ip
$ ifconfig eno16777736:1 192.168.31.52/24 up  
# 建立DR目錄
$ mkdir /usr/local/nginx/html/web1
$ mkdir /usr/local/nginx/html/web2 
# 索引頁配置
$ echo web01 > /usr/local/nginx/html/web1/index.html
$ echo web02 > /usr/local/nginx/html/web2/index.html

# 啓動nginx並查看端口
$ /usr/local/nginx/sbin/nginx 
$ netstat -ntpl
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 127.0.0.1:25            0.0.0.0:*               LISTEN      1317/master         
tcp        0      0 192.168.31.52:80        0.0.0.0:*               LISTEN      12422/nginx: master 
tcp        0      0 192.168.31.42:80        0.0.0.0:*               LISTEN      12422/nginx: master 
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      1095/sshd           
tcp6       0      0 ::1:25                  :::*                    LISTEN      1317/master         
tcp6       0      0 :::22                   :::*                    LISTEN      1095/sshd   

# 訪問驗證
$ elinks http://192.168.31.42 --dump  
   web01
$ elinks http://192.168.31.52 --dump 
   web02

# 關閉子網卡方法
$ ifconfig eno16777736:1 down

  

二、基於端口的虛擬主機

  基於端口的虛擬主機只須要一個IP,但只適合內部用戶,端口變化內部通知便可。(各類不良網站會須要改變IP和端口來逃避封鎖)
  缺點:端口沒法告訴公網用戶,沒法適用於公網用戶。web

(1)nginx.conf配置

worker_processes  1;
events {
    worker_connections  1024;
}
http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    keepalive_timeout  65;
    server {
        listen       80;
        #server_name  localhost;
        location / {
            root   html/web1;
            index  index.html index.htm;
        }
    }
    server {
        listen       8080;
        #server_name  localhost;
        location / {
            root   html/web2;
            index  index.html index.htm;
        }
    }
}

(2)測試驗證

$ /usr/local/nginx/sbin/nginx  -g nginx.conf    # 驗證前面修改的nginx配置
nginx: [emerg] unexpected end of parameter, expecting ";" in command line
$ killall nginx
$ /usr/local/nginx/sbin/nginx     # 啓動服務
$ netstat -ntpl
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 127.0.0.1:25            0.0.0.0:*               LISTEN      1317/master         
tcp        0      0 0.0.0.0:8080            0.0.0.0:*               LISTEN      12543/nginx: master 
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      12543/nginx: master 
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      1095/sshd           
tcp6       0      0 ::1:25                  :::*                    LISTEN      1317/master         
tcp6       0      0 :::22                   :::*                    LISTEN      1095/sshd           
$ elinks http://192.168.31.42 --dump   # 未加端口默認是80端口
   web01
$ elinks http://192.168.31.42:8080 --dump
   web02

三、基於域名的虛擬主機

  一個網站必然有一個域名,能夠ip和端口相同,但域名不一樣。基於域名的虛擬主機主要用來處理線上問題。
  基於域名的虛擬主機,完美解決了基於IP和基於端口虛擬主機的問題。正則表達式

(1)配置/etc/hosts和nginx.cnnf

# /etc/hosts
......  原始的保留
192.168.31.42 www.abc.com
192.168.31.42 www.cbd.com

# nginx.conf
worker_processes  1;
events {
    worker_connections  1024;
}
http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    keepalive_timeout  65;
    server {
        listen       80;
        server_name  www.abc.com;
        location / {
            root   html/web1;
            index  index.html index.htm;
        }
    }
    server {
        listen       80;
        server_name  www.cbd.com;
        location / {
            root   html/web2;
            index  index.html index.htm;
        }
    }
}

(2)測試驗證

$ /usr/local/nginx/sbin/nginx -g nginx.conf
$ killall nginx
$ /usr/local/nginx/sbin/nginx 
$  netstat -ntpl               
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 127.0.0.1:25            0.0.0.0:*               LISTEN      1317/master         
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      12676/nginx: master 
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      1095/sshd           
tcp6       0      0 ::1:25                  :::*                    LISTEN      1317/master         
tcp6       0      0 :::22                   :::*                    LISTEN      1095/sshd           
$ elinks http://www.abc.com -dump  
   web01
$ elinks http://www.cbd.com -dump   
   web02

2、反向代理

  • 正向代理:
    正向代理是一個位於客戶端和原始服務器(origin server)之間的服務器,爲了從原始服務器取得內容,客戶端向代理髮送一個請求並指定目標(原始服務器),而後代理向原始服務器轉交請求並將得到的內容返回給客戶端。客戶端必需要進行一些特別的設置才能使用正向代理。
    正向代理的用途:訪問本來沒法訪問的資源、作緩存加速訪問資源、對客戶端訪問受權上網認證、代理能夠記錄用戶訪問記錄(上網行爲管理。)。
  • 反向代理(Reverse Proxy):
    代理服務器,客戶機在發送請求時,不會直接發送給目的主機,而是先發送給代理服務器,代理服務接受客戶機請求以後,再向主機發出,並接收目的主機返回的數據,存放在代理服務器的硬盤中,再發送給客戶機中。此時代理服務器對外就表現爲一個服務器。
    反向代理的做用:保證內網的安全,可使用反向代理提供WAF功能,阻止web攻擊;負載均衡,經過反向代理來優化網站的負載。

反向代理圖示以下:算法

反向代理圖示

一、反向代理應用場景

(1)堡壘機場景

  業務服務器安全配置只接受來自源IP爲堡壘機的連接訪問,其餘的都拒絕。黑客攻擊的只是一臺暴露在外網的反向代理服務器,服務器上其實什麼都沒有,不用擔憂數據丟失。chrome

堡壘機場景

(2)內網服務器發佈場景

  適用於公網IP地址不足的場景。
  在業務服務器前面作一個反向代理服務器,以虛擬主機的方式配置三個虛擬機主機,並配置三個代理。訪問不一樣的虛擬主機找不一樣的業務服務器獲取數據,再將數據提供給用戶。後端

發佈內網服務器

(3)緩存場景

  常見緩存場景應用:CDN。
  網站具備動態、靜態兩種數據。自行配置緩存服務器時,在緩存服務器上保存靜態數據。客戶訪問時,緩存服務器將靜態數據發給客戶端。動態數據則是由緩存服務器向業務服務器發送請求獲取後發給客戶端。每每靜態頁面還在渲染,動態數據已經獲取並逐漸加載。
  好處是:加載速度較快,用戶體驗提高;下降業務服務器壓力。

緩存服務器場景

二、反向代理原理

  1)客戶端經過瀏覽器發起請求,請求發送給代理服務器;
  2)代理服務器接收請求;
  3)代理服務器發送請求給業務服務器;
  4)業務服務器接受請求、處理請求;
  5)業務服務器發送響應請求把數據交給代理服務器;
  6)代理服務器再發送響應請求將數據交給客戶端;
  7)客戶端經過瀏覽器將數據渲染出來並展現給用戶。

三、反向代理實現

  client用mac電腦代替,反向代理用以前的Nginx,業務機器用book.ayitula.com(http://118.190.209.153:4000)。指望實如今mac上訪問http://192.168.31.42訪問到該服務頁面。

(1)備份重啓操做

$ cp nginx.conf nginx.conf.bak_2
$ cp nginx.conf.default nginx.conf
$ killall nginx
$ /usr/local/nginx/sbin/nginx

(2)nginx.conf配置修改內容

server {
        listen       80;
        server_name  localhost;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

        location / {
            # root   html;     # 這個機器再也不是web服務器,而是反向代理,所以沒用了
            proxy_pass http://118.190.209.153:4000;   # 請求轉向指定地址
            index  index.html index.htm;
        }

(3)反向代理效果

訪問效果

四、反向代理優化參數(性能優化)

location / {
    index index.php index.html index.htm;    #定義首頁索引文件的名稱
    proxy_pass http://mysvr ;   #請求轉向mysvr 定義的服務器列表 
    # 設置請求頭——給請求頭加字段
    proxy_set_header Host $host;      
    proxy_set_header X-Real-IP $remote_addr;    # 告訴業務服務器是代替哪一個客戶來拿數據
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 

    # 經常使用緩存和超時的設置
    client_max_body_size 10m;        # 容許客戶端請求的最大單文件字節數 
    client_body_buffer_size 128k;     # 緩衝區代理緩衝用戶端請求的最大字節數,
    proxy_connect_timeout 90;       # nginx跟後端服務器鏈接超時時間(代理鏈接超時)
    proxy_send_timeout 90;           # 後端服務器數據回傳時間(代理髮送超時)
    proxy_read_timeout 90;           # 鏈接成功後,後端服務器響應時間(代理接收超時)
    proxy_buffer_size 4k;               # 設置代理服務器(nginx)保存用戶頭信息的緩衝區大小
    proxy_buffers 4 32k;                # proxy_buffers緩衝區,網頁平均在32k如下的話,這樣的設置
    proxy_busy_buffers_size 64k;        # 高負荷下緩衝大小(proxy_buffers*2)
    proxy_temp_file_write_size 64k;     # 設定緩存文件夾大小,大於這個值,將從upstream服務器傳
}

3、Nginx限速

  限流(rate limiting)是NGINX衆多特性中最有用的,也是常常容易被誤解和錯誤配置的特性之一。
  限速該特性能夠限制某個用戶在一個給定時間段內可以產生的HTTP請求數。請求能夠簡單到就是一個對於主頁的GET請求或者一個登錄表格的POST請求。
  限流也能夠用於安全目的上,好比減慢暴力密碼破解攻擊。經過限制進來的請求速率,而且(結合日誌)標記出目標URLs來幫助防範DDoS攻擊。通常地說,限流是用在保護上游應用服務器不被在同一時刻的大量用戶請求湮沒。另外還能夠保護磁盤IO。

一、應用場景

  • DDOS防護
    DDOS的特色是分佈式,針對帶寬和服務攻擊,也就是四層流量攻擊和七層應用攻擊,相應的防護瓶頸四層在帶寬,七層的多在架構的吞吐量。對於七層的應用攻擊,咱們仍是能夠作一些配置來防護的,例如前端是 Nginx,主要使用nginx的http_limit_conn和http_limit_req模塊來防護。 ngx_http_limit_conn_module 能夠限制單個IP的鏈接數,ngx_http_limit_req_module 能夠限制單個IP每秒請求數,經過限制鏈接數和請求數能相對有效的防護CC攻擊。
  • 下載場景保護IO
    不少人一塊兒下載,硬盤IO負荷太高,硬盤會扛不住,致使硬盤故障或服務器宕機。

二、限速原理(漏桶原理)

算法思想是:
  水(請求)從上方倒入水桶,從水桶下方流出(被處理);
  來不及流出的水存在水桶中(緩衝),以固定速率流出;
  水桶滿後水溢出(丟棄)。
  這個算法的核心是:緩存請求、勻速處理、多餘的請求直接丟棄

  相比漏桶算法,令牌桶算法不一樣之處在於它不但有一隻「桶」,還有個隊列,這個桶是用來存放令牌的,隊列纔是用來存放請求的。

三、實現方式

  Nginx官方版本限制IP的鏈接和併發分別有兩個模塊:

  • limit_req_zone 用來限制單位時間內的請求數,即速率限制,採用的漏桶算法 "leaky bucket"。
  • limit_req_conn 用來限制同一時間鏈接數,即併發限制。

(1)limit_req_zone參數配置:

  Syntax: limit_req zone=name [burst=number] [nodelay]; Default: —
  Context: http, server, location
  limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;

(2)基於請求數限速案例

  基於IP對下載速率作限制,限制每秒處理1次請求,對突發超過5個之後的請求放 入緩存區

http {
    limit_req_zone $binary_remote_addr zone=baism:10m rate=1r/s; 
    server {
        location /abc {
            limit_req zone=baism burst=5 nodelay; 
        }
    }
}

1)limit_req_zone $binary_remote_addr zone=baism:10m rate=1r/s; 設置緩存區(設置一個漏桶)

  • 第一個參數:$binary_remote_addr 表示經過remote_addr這個標識來作限制, 「binary_」的目的是縮寫內存佔用量,是限制同一客戶端ip地址。
  • 第二個參數:zone=baism:10m表示生成一個大小爲10M,名字爲one的內存區域, 用來存儲訪問的頻次信息。
  • 第三個參數:rate=1r/s表示容許相同標識的客戶端的訪問頻次,這裏限制的是每秒 1次,還能夠有好比30r/m的。

2)limit_req zone=baism burst=5 nodelay; 應用緩存區

  • 第一個參數:zone=baism 設置使用哪一個配置區域來作限制,與上面 limit_req_zone 裏的name對應。
  • 第二個參數:burst=5,重點說明一下這個配置,burst爆發的意思,這個配置的意 思是設置一個大小爲5的緩衝區當有大量請求(爆發)過來時,超過了訪問頻次限 制的請求能夠先放到這個緩衝區內。
  • 第三個參數:nodelay,若是設置,超過訪問頻次並且緩衝區也滿了的時候就會直 接返回503,若是沒有設置,則全部請求會等待排隊。

(3)基於鏈接數、下載作限速

http {
    #基於IP作鏈接限制 限制同一IP併發爲1 下載速度爲100K
    limit_conn_zone $binary_remote_addr zone=addr:10m; 

    #基於IP對下載速率作限制 限制每秒處理1次請求,對突發超過5個之後的請求放 入緩存區
    limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;
    server {
        listen 80;
        server_name localhost;
        location / {
            root html;
            index index.html index.htm; 
        }
        location /abc {
            limit_req zone=one burst=5 nodelay; 
            limit_conn addr 1;    # 併發限制,同一時間能下幾個資源
            limit_rate 100k;       # 下載最高速率限制
            #limit_rate_after 250m;   # 下載到250M限速(不太經常使用)
        } 
    }
}

(4)測試驗證

# 案例一:請求數限速
$ elinks http://192.168.31.42 -dump   # 連續發起5次,第五次將獲得404頁面,返回頁面也能夠自行定義

# 案例二:下載限速
#在服務器端生成一個300M的文件
$ dd if=/dev/zero of=../html/abc/bigfile bs=1M count=300

#從mac上訪問下載
$ wget http://192.168.31.42/abc/bigfile

#啓動下載限速最高100kB/s
limit_rate 100k;
#啓動同時鏈接數限制,最多一個
limit_conn addr 1;

4、URL重寫(URL rewrite)

  URL重寫是基於ngx_http_rewrite_module這個rewrite模塊。
  Rewrite功能是Nginx服務器提供的一個重要功能,也幾乎是全部web產品必備技能,用於實現URL重寫。
  URL重寫是很是有用的功能,好比它能夠在咱們改變網站結構後,不須要客戶端修改原來的書籤,也不須要其餘網站修改對咱們網站的友情連接,還能夠在必定程度上提升網站的安全性,可以讓咱們的網站顯得更加專業。
  Nginx服務器Rewrite功能的實現是依賴於PCRE(Perl Compatible Regular Expression,Perl兼容的正則表達式)的支持,因此在編譯安裝Nginx以前,須要安裝PCRE庫。

一、應用場景

  • 域名變動
    好比:京東以前的老域名是www.360buy.com,可是如今訪問這個域名,它會自動跳到www.jd.com。
  • 用戶跳轉
    好比老連接不用了,可是要引導客戶去訪問新連接,能夠從老連接跳到新連接。用戶不會由於連接修改而沒法訪問。
  • 僞靜態場景
    CDN只能緩存靜態頁面數據,可是若是能緩存動態數據會更完美好用,將動態頁面作成靜態頁面,變成一個僞靜態,便於CDN緩存動態頁面數據。

二、URL重寫原理

URL重寫原理

  上述圖片過程:用戶經過瀏覽器向nginx發起請求,nginx接收請求後,url重寫將新的url告訴用戶瀏覽器,用戶瀏覽器再用新的url去訪問業務服務器,業務服務器將數據發給用戶瀏覽器。

三、URL模塊語法

(1)經常使用關鍵字(指令)

(1) set:設置變量
(2) if:負責語句中的判斷
(3) return:返回返回值或URL
(4) break:終止後續的rewrite規則
(5) rewrite:重定向URL

(2)經常使用正則匹配:

  模糊匹配:~匹配 !~不匹配 ~* 不區分大小寫的匹配
  精確匹配:=匹配 !=不匹配

(3)URL rewrite指令語法

rewrite   <regex>   <replacement>   [flag]; 
關鍵字      正則          替代內容       flag標記

經常使用flag:
last             —— 本條規則匹配完成後,繼續向下匹配新的location URL規則
break          —— 本條規則匹配完成即終止,再也不匹配後面的任何規則
redirect       —— 返回302臨時重定向,瀏覽器地址會顯示跳轉後的URL地址
permanent   —— 返回301永久重定向,瀏覽器地址欄會顯示跳轉後的URL地址

四、Rewrite規則相關指令

  示例:將http://www.ayitula.com重寫爲http://www.ayitula.com/baism

(1)set指令——自定義變量

  語法:set $variable value;
  做用域:server,location,if

location / {
    #root   html;
    #index  index.html index.htm;
    set $name baism;
    rewrite ^(.*)$ http://www.ayitula.com/$name;     # 調用了變量$name
}

(2)if指令——負責判斷

  語法:if (condition) {......}
  做用域:server和location。

location / {
    root html;
    index index.html index.htm;
    if ($http_user_agent ~* 'Chrome') {    # 不區分大小寫匹配chrome
        return 403;     # 若是瀏覽器是chrome,直接返回403
        #return http://www.jd.com;
    } 
}

  須要注意:$http_user_agent是Nginx內部變量。

(3)return指令——定義返回數據

  語法:

return code [text];    # 返回代碼和文本
return code URL;
return URL;    # 返回url

  做用域:server,location,if

(4)break指令——中止執行當前虛擬主機後續rewrite指令集

  語法:break;
  做用域:server,location,if

location / {
    root html;
    index index.html index.htm;
    if ($http_user_agent ~* 'Chrome') {
        break; 
        return 403;
    }
}

  break表明本條規則匹配完成即終止,再也不匹配後面的任何規則。

server {
    listen 80;
    server_name www.ayitula.com; 
    location / {
        rewrite ^/$ http://www.jd.com break; 
        # rewrite ^/$ http://www.jd.com redirect;    # redirect:臨時重定向
    } 
}

  直接將重寫的域名發給客戶端後結束。相似臨時重定向效果,返回客戶端302。

(5)rewrite指令

  域名跳轉:www.ayitula.com 重寫爲 www.jd.com

server {
    listen 80;
    server_name www.ayitula.com; 
    location / {
        rewrite ^/$ http://www.jd.com permanent;   # ^/$ 指定根目錄  permanent:永久重定向
        # rewrite ^/$ http://www.jd.com redirect;    # redirect:臨時重定向
    } 
}

  Nginx配置完後,還須要配置/etc/hosts,將域名解析到本地nginx服務器地址:

192.168.31.42   www.ayitula.com

注意:

  • 重定向就是將網頁自動轉向重定向。
  • 301永久性重定向:新網址徹底繼承舊網址,舊網址的排名等徹底清零。301重定向是網頁更改地址後對搜索引擎友好的最好方法,只要不是暫時搬移 的狀況,都建議使用301來作轉址。
  • 302臨時性重定向:對舊網址沒有影響,但新網址不會有排名。
  • 搜索引擎會抓取新的內容而保留舊的網址。(重定向主要影響在搜索引擎、推廣)

(6)last指令

last指令

  last指令在url重寫後,並不會結束而是立刻發起一個新的請求,再次進入server塊,重試location匹配,超過十次匹配不到報500錯誤,地址欄url不變。

  示例:根據用戶瀏覽器重寫訪問目錄
  若是是chrome瀏覽器 就將 http://192.168.10.42/$URI 重寫爲 http://http://192.168.10.42/chrome/$URI
  實現步驟:1)URL重寫;2)請求轉給本機location。

location / {
    .....
    if ($http_user_agent ~* 'chrome'){
        rewrite ^(.*)$ /chrome/$1 last;       # 第一步重寫url
    }
    location /chrome {          # 第二步用新的url(http://192.168.31.42/chorm/$uri)來匹配規則
        root html ;
        index index.html;
    } 
}

注意正則使用:

  • "^" 以什麼開頭 ^a
  • "$" 以什麼結尾 c$
  • "." 除了回車之外的任意一個字符
  • "*" 前面的字符能夠出現屢次或者不出現 #更多內容看正則表達式 re
相關文章
相關標籤/搜索