一個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的虛擬機、DocumentRoot存在、索引頁index.html配置。
場景是:每一個網站都須要一個IP。
缺點是:須要多個IP,若是是公網IP,每一個IP都須要付費。前端
在這裏須要知道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 # 有空行的都刪除
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; } } }
兩個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
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; } } }
$ /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和基於端口虛擬主機的問題。正則表達式
# /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; } } }
$ /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
反向代理圖示以下:算法
業務服務器安全配置只接受來自源IP爲堡壘機的連接訪問,其餘的都拒絕。黑客攻擊的只是一臺暴露在外網的反向代理服務器,服務器上其實什麼都沒有,不用擔憂數據丟失。chrome
適用於公網IP地址不足的場景。
在業務服務器前面作一個反向代理服務器,以虛擬主機的方式配置三個虛擬機主機,並配置三個代理。訪問不一樣的虛擬主機找不一樣的業務服務器獲取數據,再將數據提供給用戶。後端
常見緩存場景應用: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服務器傳 }
限流(rate limiting)是NGINX衆多特性中最有用的,也是常常容易被誤解和錯誤配置的特性之一。
限速該特性能夠限制某個用戶在一個給定時間段內可以產生的HTTP請求數。請求能夠簡單到就是一個對於主頁的GET請求或者一個登錄表格的POST請求。
限流也能夠用於安全目的上,好比減慢暴力密碼破解攻擊。經過限制進來的請求速率,而且(結合日誌)標記出目標URLs來幫助防範DDoS攻擊。通常地說,限流是用在保護上游應用服務器不被在同一時刻的大量用戶請求湮沒。另外還能夠保護磁盤IO。
算法思想是:
水(請求)從上方倒入水桶,從水桶下方流出(被處理);
來不及流出的水存在水桶中(緩衝),以固定速率流出;
水桶滿後水溢出(丟棄)。
這個算法的核心是:緩存請求、勻速處理、多餘的請求直接丟棄。
相比漏桶算法,令牌桶算法不一樣之處在於它不但有一隻「桶」,還有個隊列,這個桶是用來存放令牌的,隊列纔是用來存放請求的。
Nginx官方版本限制IP的鏈接和併發分別有兩個模塊:
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;
基於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; 設置緩存區(設置一個漏桶)
2)limit_req zone=baism burst=5 nodelay; 應用緩存區
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限速(不太經常使用) } } }
# 案例一:請求數限速 $ 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;
URL重寫是基於ngx_http_rewrite_module這個rewrite模塊。
Rewrite功能是Nginx服務器提供的一個重要功能,也幾乎是全部web產品必備技能,用於實現URL重寫。
URL重寫是很是有用的功能,好比它能夠在咱們改變網站結構後,不須要客戶端修改原來的書籤,也不須要其餘網站修改對咱們網站的友情連接,還能夠在必定程度上提升網站的安全性,可以讓咱們的網站顯得更加專業。
Nginx服務器Rewrite功能的實現是依賴於PCRE(Perl Compatible Regular Expression,Perl兼容的正則表達式)的支持,因此在編譯安裝Nginx以前,須要安裝PCRE庫。
上述圖片過程:用戶經過瀏覽器向nginx發起請求,nginx接收請求後,url重寫將新的url告訴用戶瀏覽器,用戶瀏覽器再用新的url去訪問業務服務器,業務服務器將數據發給用戶瀏覽器。
(1) set:設置變量
(2) if:負責語句中的判斷
(3) return:返回返回值或URL
(4) break:終止後續的rewrite規則
(5) rewrite:重定向URL
模糊匹配:~匹配 !~不匹配 ~* 不區分大小寫的匹配
精確匹配:=匹配 !=不匹配
rewrite <regex> <replacement> [flag]; 關鍵字 正則 替代內容 flag標記 經常使用flag: last —— 本條規則匹配完成後,繼續向下匹配新的location URL規則 break —— 本條規則匹配完成即終止,再也不匹配後面的任何規則 redirect —— 返回302臨時重定向,瀏覽器地址會顯示跳轉後的URL地址 permanent —— 返回301永久重定向,瀏覽器地址欄會顯示跳轉後的URL地址
示例:將http://www.ayitula.com重寫爲http://www.ayitula.com/baism
語法:set $variable value;
做用域:server,location,if
location / { #root html; #index index.html index.htm; set $name baism; rewrite ^(.*)$ http://www.ayitula.com/$name; # 調用了變量$name }
語法: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內部變量。
語法:
return code [text]; # 返回代碼和文本 return code URL; return URL; # 返回url
做用域:server,location,if
語法: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。
域名跳轉: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
注意:
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; } }
注意正則使用: