如果你的nginx服務器給2臺web服務器做代理,負載均衡算法采用輪詢,那么當你的一臺機器web程序關閉造成web不能訪問,那么nginx服務器分發請求還是會給這臺不能訪問的web服務器,如果這里的響應連接時間過...
如果你的nginx服務器給2臺web服務器做代理,負載均衡算法采用輪詢,那么當你的一臺機器web程序關閉造成web不能訪問,那么nginx服務器分發請求還是會給這臺不能訪問的web服務器,如果這里的響應連接時間過長,就會導致客戶端的頁面一直在等待響應,對用戶來說體驗就打打折扣,這里我們怎么避免這樣的情況發生呢。這里我配張圖來說明下問題。
如果負載均衡中其中web2發生這樣的情況,nginx首先會去web1請求,但是nginx在配置不當的情況下會繼續分發請求道web2,然后等待web2響應,直到我們的響應時間超時,才會把請求重新分發給web1,這里的響應時間如果過長,用戶等待的時間就會越長。
下面的配置是解決方案之一、
proxy_connect_timeout 1; #nginx服務器與被代理的服務器建立連接的超時時間,默認60秒
proxy_read_timeout 1; #nginx服務器向被代理服務器組發出read請求后,等待響應的超時間,默認為60秒。
proxy_send_timeout 1; #nginx服務器向被代理服務器組發出write請求后,等待響應的超時間,默認為60秒。
proxy_ignore_client_abort on; #客戶端斷網時,nginx服務器是否中斷對被代理服務器的請求。默認為off。
使用upstream指令配置一組服務器作為被代理服務器,服務器中的訪問算法遵循配置的負載均衡規則,同時可以使用該指令配置在發生哪些異常情況時,將請求順次交由下一組服務器處理.
proxy_next_upstream timeout; #反向代理upstream中設置的服務器組,出現故障時,被代理服務器返回的狀態值。error|timeout|invalid_header|http_500|http_502|http_503|http_504|http_404|off
error:建立連接或向被代理的服務器發送請求或讀取響應信息時服務器發生錯誤。
timeout:建立連接,想被代理服務器發送請求或讀取響應信息時服務器發生超時。
invalid_header:被代理服務器返回的響應頭異常。
off:無法將請求分發給被代理的服務器。
http_400,....:被代理服務器返回的狀態碼為400,500,502,等
首先給大家說下 upstream 這個配置的,這個配置是寫一組被代理的服務器地址,然后配置負載均衡的算法。這里的被代理服務器地址有兩種寫法。
upstream testapp {server 10.0.105.199:8081;server 10.0.105.202:8081;}server {listen 80;server_name localhost;location / {proxy_pass http://testapp; #請求轉向 testapp 定義的服務器列表}
upstream mysvr {server http://10.0.105.199:8081;server http://10.0.105.202:8081;}server {listen 80;server_name localhost;location / {proxy_pass http://mysvr; #請求轉向mysvr 定義的服務器列表}
upstream 支持4種負載均衡調度算法:
A、
輪詢(默認)
:每個請求按時間順序逐一分配到不同的后端服務器;B、
ip_hash
:每個請求按訪問IP的hash結果分配,同一個IP客戶端固定訪問一個后端服務器??梢员WC來自同一ip的請求被打到固定的機器上,可以解決session問題。C、
url_hash
:按訪問url的hash結果來分配請求,使每個url定向到同一個后端服務器。后臺服務器為緩存的時候提高效率。D、
fair
:這是比上面兩個更加智能的負載均衡算法。此種算法可以依據頁面大小和加載時間長短智能地進行負載均衡,也就是根據后端服務器的響應時間來分配請求,響應時間短的優先分配。Nginx
本身是不支持fair
的,如果需要使用這種調度算法,必須下載Nginx的upstream_fair
模塊。 # 課后擴展
upstream myweb {
server 172.17.14.2:8080;
server 172.17.14.3:8080 backup; #熱備
}
upstream myweb {
server 172.17.14.2:8080;
server 172.17.14.3:8080;
}
upstream myweb {
server 172.17.14.2:8080 weight=1;
server 172.17.14.3:8080 weight=2;
}
upstream myweb {
server 172.17.14.2:8080;
server 172.17.14.3:8080;
ip_hash;
}
down,表示當前的server暫時不參與負載均衡。
backup,預留的備份機器。當其他所有的非backup機器出現故障或者忙的時候,才會請求backup機器,因此這臺機器的壓力最輕。
max_fails,允許請求失敗的次數,默認為1。當超過最大次數時,返回proxy_next_upstream 模塊定義的錯誤。
fail_timeout,在經歷了max_fails次失敗后,暫停服務的時間單位秒。max_fails可以和fail_timeout一起使用。
upstream myweb {
server 172.17.14.2:8080 weight=2 max_fails=2 fail_timeout=2;
server 172.17.14.3:8080 weight=1 max_fails=2 fail_timeout=1;
}
舉例講解下什么是7層協議,什么是4層協議。
OSI(Open System Interconnection)是一個開放性的通行系統互連參考模型,他是一個定義的非常好的協議規范,共包含七層協議。直接上圖,這樣更直觀些:
TCP/IP協議 之所以說TCP/IP是一個協議族,是因為TCP/IP協議包括TCP、IP、UDP、ICMP、RIP、TELNETFTP、SMTP、ARP、TFTP等許多協議,這些協議一起稱為TCP/IP協議。
從協議分層模型方面來講,TCP/IP由四個層次組成:網絡接口層、網絡層、傳輸層、應用層。
這里我們舉例,在nginx做負載均衡,負載多個服務,部分服務是需要7層的,部分服務是需要4層的,也就是說7層和4層配置在同一個配置文件中。
準備三臺機器:
代理服務IP:10.0.105. --配置本地host解析域名;
后端服務器IP:nginx-a :10.0.105.199/nginx-b:10.0.105.202(yum安裝)后端服務器將nginx服務啟動
配置代理服務器的nginx配置文件
worker_processes 4;worker_rlimit_nofile 102400;events {worker_connections 1024;}http {include mime.types;default_type application/octet-stream;log_format main '$remote_addr - $remote_user [$time_local] "$request" ''$status $body_bytes_sent "$http_referer" ''"$http_user_agent" "$http_x_forwarded_for"';#access_log logs/access.log main;sendfile on;keepalive_timeout 65;gzip on;upstream testweb { ip_hash; server 10.0.105.199:80 weight=2 max_fails=2 fail_timeout=2s; server 10.0.105.202:80 weight=2 max_fails=2 fail_timeout=2s;}server {listen 80;server_name www.test.com;charset utf-8;#access_log logs/host.access.log main;location / { proxy_pass http://testweb;proxy_set_header Host $host:$server_port;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; }error_page 500 502 503 504 /50x.html;location = /50x.html {root html; } }upstream testapp { server 10.0.105.202:8081 weight=2 max_fails=2 fail_timeout=2s;server 10.0.105.199:8081 weight=2 max_fails=2 fail_timeout=2s; }server { listen 81; server_name www.app.com; charset utf-8; #access_log logs/host.access.log main;location / { proxy_pass http://testapp;proxy_set_header Host $host:$server_port;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } }}
瀏覽器測試訪問:
http://www.test.com/
http://www.app.com:81/
202服務器yum安裝的創建新的配置文件:
[root@nginx-server ~]# cd /etc/nginx/conf.d/[root@nginx-server conf.d]# cp default.conf test.conf[root@nginx-server conf.d]# cat test.confserver {listen 80;server_name localhost;location / {root /usr/share/nginx/html;index index.html index.htm;}}server {listen 8081;server_name localhost;location / {root /var/www/nginx/html;index index.html index.htm;}}[root@nginx-server ~]# nginx -s reload
nginx在1.9.0的時候,增加了一個 stream 模塊,用來實現四層協議(網絡層和傳輸層)的轉發、代理、負載均衡等。stream模塊的用法跟http的用法類似,允許我們配置一組TCP或者UDP等協議的監聽,然后通過proxy_pass來轉發我們的請求,通過upstream添加多個后端服務,實現負載均衡。
#4層tcp負載
stream {
upstream myweb {
hash $remote_addr consistent;
server 172.17.14.2:8080;
server 172.17.14.3:8080;
}
server {
listen 82;
proxy_connect_timeout 10s;
proxy_timeout 30s;
proxy_pass myweb;
}
}
nginx會話保持主要有以下幾種實現方式。
ip_hash使用源地址哈希算法,將同一客戶端的請求總是發往同一個后端服務器,除非該服務器不可用。
ip_hash語法:
upstream backend {
ip_hash;
server backend1.example.com;
server backend2.example.com;
server backend3.example.com down;
}
ip_hash簡單易用,但有如下問題: 當后端服務器宕機后,session會丟失; 來自同一局域網的客戶端會被轉發到同一個后端服務器,可能導致負載失衡; 不適用于CDN網絡,不適用于前段還有代理的情況。
使用sticky_cookie_insert啟用會話親緣關系,這會導致來自同一客戶端的請求被傳遞到一組服務器的同一臺服務器。與ip_hash不同之處在于,它不是基于IP來判斷客戶端的,而是基于cookie來判斷。因此可以避免上述ip_hash中來自同一局域網的客戶端和前段代理導致負載失衡的情況。(需要引入第三方模塊才能實現) # 課后擴展 語法:
upstream backend {
server backend1.example.com;
server backend2.example.com;
sticky expires=1h domain=3evip.cn path=/;
}
說明: expires:設置瀏覽器中保持cookie的時間 domain:定義cookie的域 path:為cookie定義路徑
jvm_route是通過session_cookie這種方式來實現session粘性。將特定會話附屬到特定tomcat上,從而解決session不同步問題,但是無法解決宕機后會話轉移問題。如果在cookie和url中并沒有session,則這只是個簡單的round-robin負載均衡。
jvm_route的原理
一開始請求過來,沒有帶session的信息,jvm_route就根據round robin的方法,發到一臺Tomcat上面
Tomcat添加上session信息,并返回給客戶
用戶再次請求,jvm_route看到session中有后端服務器的名稱,他就把請求轉到對應的服務器上
暫時jvm_route模塊還不支持fair的模式。jvm_route的工作模式和fair是沖突的。對于某個特定用戶,當一直為他服務的Tomcat宕機后,默認情況下它會重試max_fails的次數,如果還是失敗,就重新啟用round robin的方式,而這種情況下就會導致用戶的session丟失。
為了加快網站的解析速度,可以把動態頁面和靜態頁面由不同的服務器來解析,加快解析速度。降低原來單個服務器的壓力。 在動靜分離的tomcat的時候比較明顯,因為tomcat解析靜態很慢,其實這些原理的話都很好理解,簡單來說,就是使用正則表達式匹配過濾,然后交個不同的服務器。
準備一個nginx代理 兩個http 分別處理動態和靜態。
1.配置nginx反向代理upstream;upstream static {server 10.0.105.196:80 weight=1 max_fails=1 fail_timeout=60s;}upstream php {server 10.0.105.200:80 weight=1 max_fails=1 fail_timeout=60s;}server {listen 80;server_name localhost;#動態資源加載location ~ \.(php|jsp)$ {proxy_pass http://php;proxy_set_header Host $host:$server_port;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;}#靜態資源加載location ~ .*\.(html|gif|jpg|png|bmp|swf|css|js)$ {proxy_pass http://static;proxy_set_header Host $host:$server_port;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;}}
靜態資源配置server {listen 80;server_name localhost;location ~ \.(html|jpg|png|js|css|gif|bmp|jpeg) {root /home/www/nginx;}}
動態資源配置:yum 安裝php7.1[root@nginx-server ~]#rpm -Uvh https://mirror.webtatic.com/yum/el7/epel-release.rpm[root@nginx-server ~]#rpm -Uvh https://mirror.webtatic.com/yum/el7/webtatic-release.rpm[root@nginx-server ~]#yum install php71w-xsl php71w php71w-ldap php71w-cli php71w-common php71w-devel php71w-gd php71w-pdo php71w-mysql php71w-mbstring php71w-bcmath php71w-mcrypt -y[root@nginx-server ~]#yum install -y php71w-fpm[root@nginx-server ~]#systemctl start php-fpm[root@nginx-server ~]#systemctl enable php-fpm編輯nginx的配置文件:server {listen 80;server_name localhost;location ~ \.php$ {root /home/nginx/html; #指定網站目錄fastcgi_pass 127.0.0.1:9000; #指定訪問地址fastcgi_index index.php; #指定默認文件fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; #站點根目錄,取決于root配置項include fastcgi_params; #包含nginx常量定義 }}
兩個網站 A 和 B, A網站引用了B網站上的圖片,這種行為就叫做盜鏈。 防盜鏈,就是要防止A引用B的圖片。
ngx_http_referer_module
HTTP Referer是Header的一部分,當瀏覽器向Web服務器發送請求的時候,一般會帶上Referer,告訴服務器我是從哪個頁面鏈接過來的,服務器借此可以獲得一些信息用于處理,例如防止未經允許的網站盜鏈圖片、文件等。因此HTTP Referer頭信息是可以通過程序來偽裝生成的,所以通過Referer信息防盜鏈并非100%可靠,但是,它能夠限制大部分的盜鏈情況.
比如在www.google.com 里有一個www.baidu.com
鏈接,那么點擊這個www.baidu.com
,它的header
信息里就有:Referer=http://www.google.com
[root@nginx-server ~]# vim /etc/nginx/nginx.conf
# 日志格式添加"$http_referer"
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
# valid_referers 使用方式
Syntax: valid_referers none | blocked | server_names | string ...;
Default: —
Context: server, location
none : 允許沒有http_refer的請求訪問資源;
blocked : 允許不是http://開頭的,不帶協議的請求訪問資源;
server_names : 只允許指定ip/域名來的請求訪問資源(白名單);
準備兩臺機器,兩張圖片(緩存問題)
配置nginx配置文件,并上傳圖片[root@nginx-server html]# vim /etc/nginx/conf.d/nginx.confserver {listen 80;server_name localhost;location / {root /usr/share/nginx/html;index index.html index.htm;valid_referers none blocked *.qf.com 10.0.105.202;if ($invalid_referer) {return 502;}}location ~ .*\.(gif|jpg|png|jpeg)$ {root /usr/share/nginx/html;valid_referers qf.com 10.0.105.202;if ($invalid_referer) {return 403;}}}重載nginx服務[root@nginx-server ~]# nginx -s reload -c /etc/nginx/nginx.conf
第二臺機器客戶端配置nginx訪問頁面創建頁面[root@nginx-server nginx]# vim index.html<html><head><meta charset="utf-8"><title>qf.com</title></head><body style="background-color:red;"><img src="http://10.0.105.202/test.jpg"/></body></html>測試不帶http_refer:[root@nginx-server nginx]# curl -I "http://10.0.105.202/test1.png"HTTP/1.1 200 OKServer: nginx/1.16.0Date: Thu, 27 Jun 2019 16:21:13 GMTContent-Type: image/pngContent-Length: 235283Last-Modified: Thu, 27 Jun 2019 11:27:11 GMTConnection: keep-aliveETag: "5d14a80f-39713"Accept-Ranges: bytes測試帶非法http_refer:[root@nginx-server nginx]# curl -e http://www.baidu.com -I "http://10.0.105.202/test.jpg"HTTP/1.1 403 ForbiddenServer: nginx/1.16.0Date: Thu, 27 Jun 2019 16:22:32 GMTContent-Type: text/htmlContent-Length: 153Connection: keep-alive測試帶合法的http_refer:[root@nginx-server nginx]# curl -e http://10.0.105.202 -I "http://10.0.105.202/test.jpg"HTTP/1.1 200 OKServer: nginx/1.16.0Date: Thu, 27 Jun 2019 16:23:21 GMTContent-Type: image/jpegContent-Length: 27961Last-Modified: Thu, 27 Jun 2019 12:28:51 GMTConnection: keep-aliveETag: "5d14b683-6d39"Accept-Ranges: bytes
# location ~ .*\.(gif|jpg|png|jpeg)$ {# root /usr/share/nginx/html;# valid_referers none blocked xgui.com 10.0.105.202;# if ($invalid_referer) {# return 403;# }# }location ~ .*\.(gif|jpg|png|jpeg)$ {root /usr/share/nginx/html;valid_referers 10.0.105.202 *.baidu.com *.google.com;if ($invalid_referer) {rewrite ^/ http://10.0.105.202/test.jpg;#return 403;}}
以上所有來自 xgui.com 和域名中google和baidu的站點都可以訪問到當前站點的圖片,如果來源域名不在這個列表中,那么$invalid_referer等于1,在if語句中返回一個403給用戶,這樣用戶便會看到一個403的頁面,如果使用下面的rewrite,那么盜鏈的圖片都會顯示403.jpg。如果用戶直接在瀏覽器輸入你的圖片地址,那么圖片顯示正常,因為它符合none這個規則。
————————————————
版權聲明:本文為博主原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接和本聲明。
原文鏈接:https://blog.csdn.net/fkdmcjd/article/details/134507737
來源:本文內容搜集或轉自各大網絡平臺,并已注明來源、出處,如果轉載侵犯您的版權或非授權發布,請聯系小編,我們會及時審核處理。
聲明:江蘇教育黃頁對文中觀點保持中立,對所包含內容的準確性、可靠性或者完整性不提供任何明示或暗示的保證,不對文章觀點負責,僅作分享之用,文章版權及插圖屬于原作者。
Copyright?2013-2024 JSedu114 All Rights Reserved. 江蘇教育信息綜合發布查詢平臺保留所有權利
蘇公網安備32010402000125 蘇ICP備14051488號-3技術支持:南京博盛藍睿網絡科技有限公司
南京思必達教育科技有限公司版權所有 百度統計