文章目錄
- 一.nginx簡單介紹
- 二.安裝nginx和tomcat
- 三.nginx配置
- 四.負載均衡政策
-
- 4.1 輪詢
- 4.2 最少連接配接
- 4.3 權重
- 4.4 ip_hash
- 五. session共享
-
- 5.1 不使用session,換作cookie
- 5.2 應用伺服器自行實作共享
- 5.3 ip_hash
- 5.4 upstream_hash
- 六.關于限流
-
- 6.1 ngx_http_limit_conn_module
- 6.2 ngx_http_limit_req_module
- 七.vue打包dist放在nginx下的配置
-
- 7.1 配置檔案
- 附錄:
-
- 1.資料參考:
- 2. 零星知識點:
一.nginx簡單介紹
Nginx是一款輕量級兼備高性能的Http和反向代理伺服器。所謂反向代理就是指在使用者發起通路請求,由代理伺服器接收,然後将請求轉發給正式伺服器,并且将正式伺服器處理完的資料傳回給用戶端,此時代理伺服器就表現為一個伺服器。這麼做看起來多經過了一步,稍顯麻煩,但實則是好處多多.
-
熱部署
我個人覺得這個很不錯。在master管理程序與worker工作程序的分離設計,使的Nginx具有熱部署的功能,那麼在7×24小時不間斷服務的前提下,更新Nginx的可執行檔案。也可以在不停止服務的情況下修改配置檔案,更換日志檔案等功能。
-
可以高并發連接配接
這是一個很重要的一個特性!在這一個 網際網路 快速發展, 網際網路 使用者數量不斷增加,一些大公司、網站都需要面對高并發請求,如果有一個能夠在峰值頂住10萬以上并發請求的Server,肯定會得到大家的青睐。理論上,Nginx支援的并發連接配接上限取決于你的記憶體,10萬遠未封頂。
-
低的記憶體消耗
在一般的情況下,10000個非活躍的HTTP Keep-Alive 連接配接在Nginx中僅消耗2.5M的記憶體,這也是Nginx支援高并發連接配接的基礎。
-
處理響應請求很快
在正常的情況下,單次請求會得到更快的響應。在高峰期,Nginx可以比其他的Web伺服器更快的響應請求。
-
具有很高的可靠性
Nginx是一個高可靠性的Web伺服器,這也是我們為什麼選擇Nginx的基本條件,現在很多的網站都在使用Nginx,足以說明Nginx的可靠性。高可靠性來自其核心架構代碼的優秀設計、子產品設計的簡單性;并且這些子產品都非常的穩定。
二.安裝nginx和tomcat
nginx的安裝教程參見<使用fastDFS從頭搭建檔案伺服器>;
tomcat的安裝教程參見CentOS中的<阿裡雲centOS手工部署Java Web項目>.
三.nginx配置
常用指令:
#打開配置檔案
# vi /usr/local/nginx/conf/nginx.conf
#檢視nginx程序
#ps aux |grep nginx
# cd /usr/local/nginx/sbin/
# ./nginx
或者直接:
啟動
# /usr/local/nginx/sbin/nginx
停止
# /usr/local/nginx/sbin/nginx -s stop
重新開機
# /usr/local/nginx/sbin/nginx -s reload
其它指令
# ./nginx -s stop
# ./nginx -s quit
# ./nginx -s reload
#使用使用者與安裝使用者保持一緻,不然可能會報403 Forbidden,window下不指定
user root;
#啟動程序,通常設定成和cpu的數量相等
worker_processes 1;
#工作模式及連接配接數上限
events {
use epoll; #epoll是多路複用IO(I/O Multiplexing)中的一種方式,但是僅用于linux2.6以上核心,可以大大提高nginx的性能;使用網絡IO模型linux建議epoll,FreeBSD建議采用kqueue,window下不指定。
worker_connections 1024; #51200=1024*50,單個背景worker process程序的最大并發連結數
}
#設定http伺服器,利用它的反向代理功能提供負載均衡支援
http {
#設定mime類型,類型由mime.type檔案定義
include /etc/nginx/mime.types;
default_type application/octet-stream;
#設定日志格式
#access_log /var/log/nginx/access.log;
#sendfile 指令指定 nginx 是否調用 sendfile 函數(zero copy 方式)來輸出檔案,對于普通應用,
#必須設為 on,如果用來進行下載下傳等應用磁盤IO重負載應用,可設定為 off,以平衡磁盤與網絡I/O處理速度,降低系統的uptime.其主要作用是加快對靜态檔案的處理。預設情況下是開啟(on)狀态。
sendfile on;
tcp_nopush on;#屬于nginx靜态資源配置子產品,把多個包一次性整合之後再發送給用戶端,而不是一次次發,在sendfile開啟的情況下,提高網絡包的傳輸效率,可在http、server和location中配置,預設是關閉(off)狀态。
tcp_nodelay on;#屬于nginx靜态配置子產品,盡量的把包發送出去,不要等待,用在實時性有要求的場景。一般在keepalive連接配接下,提高網絡 包的傳輸實時性,可在http、server和location中配置,預設是開啟(on)狀态。看上去是和tcp_nopush相反的功能,但是兩邊都為on時nginx也可以平衡這兩個功能的使用。
#連接配接逾時時間
#keepalive_timeout 0;
keepalive_timeout 65;
#設定負載均衡的伺服器清單,這裡的域名要和下面proxy_pass的一樣
upstream test {
#weigth參數表示權值,權值越高被配置設定到的幾率越大
#本機上的Squid開啟3128端口
server 192.168.8.1:3128 weight=5;
server 192.168.8.2:80 weight=1;
server 192.168.8.3:80 weight=6;
}
server {
#偵聽80端口
listen 80;
#限制檔案上傳的大小,預設為1m,設為0表示無限制
#client_max_body_size 32m;
#定義使用www.xx.com通路,一般沒什麼用.目前知道的作用是虛拟主機:兩個域名解析到同一個IP位址,監聽同一個端口号,但是使用者通過兩個域名卻可以打開兩個完全不同的網站,互相不影響,就像通路兩個伺服器一樣,是以叫兩個虛拟主機。虛拟主機的原理是通過HTTP請求頭中的Host是否比對server_name來實作的
server_name test;
#設定本虛拟主機的通路日志
#access_log logs/www.xx.com.access.log main;
#預設請求轉發給後端伺服器
location / {
#Host 這個不配置Request().getServerPort()拿到的端口會是預設的80
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;
proxy_pass http://test;
}
#靜态資源路徑通路配置
location ^~/static/ {
alias /var/www/static/;
#或者用root /var/www/;
}
}
}
四.負載均衡政策
4.1 輪詢
這種是預設的政策,把每個請求按順序逐一配置設定到不同的server,如果server挂掉,能自動剔除。
upstream fengzp.com {
server 192.168.99.100:42000;
server 192.168.99.100:42001;
}
4.2 最少連接配接
把請求配置設定到連接配接數最少的server
upstream fengzp.com {
least_conn;
server 192.168.99.100:42000;
server 192.168.99.100:42001;
}
4.3 權重
使用weight來指定server通路比率,weight預設是1。以下配置會是server2通路的比例是server1的兩倍。
upstream fengzp.com {
server 192.168.99.100:42000 weight=1;
server 192.168.99.100:42001 weight=2;
}
4.4 ip_hash
每個請求會按照通路ip的hash值配置設定,這樣同一用戶端連續的Web請求都會被分發到同一server進行處理,可以解決session的問題。如果server挂掉,能自動剔除。[如果隻剩一個伺服器了,ip_hash還是能通路到的,不用擔心]
upstream fengzp.com {
ip_hash;
server 192.168.99.100:42000;
server 192.168.99.100:42001;
}
ip_hash可以和weight結合使用。
五. session共享
5.1 不使用session,換作cookie
能把session改成cookie,就能避開session的一些弊端,在從前看的一本J2EE的書上,也指明在叢集系統中不能用session,否則惹出禍端來就不好辦。如果系統不複雜,就優先考慮能否将session去掉,改動起來非常麻煩的話,再用下面的辦法。
5.2 應用伺服器自行實作共享
asp.net可以用資料庫或memcached來儲存session,進而在asp.net本身建立了一個session叢集,用這樣的方式可以令 session保證穩定,即使某個節點有故障,session也不會丢失,适用于較為嚴格但請求量不高的場合。但是它的效率是不會很高的,不适用于對效率 要求高的場合。
以上兩個辦法都跟nginx沒什麼關系,下面來說說用nginx該如何處理:
5.3 ip_hash
nginx中的ip_hash技術能夠将某個ip的請求定向到同一台後端,這樣一來這個ip下的某個用戶端和某個後端就能建立起穩固的session,ip_hash是在upstream配置中定義的:
upstream backend {
server 127.0.0.1:8080 ;
server 127.0.0.1:9090 ;
ip_hash;
}
ip_hash是容易了解的,但是因為僅僅能用ip這個因子來配置設定後端,是以ip_hash是有缺陷的,不能在一些情況下使用:
- nginx不是最前端的伺服器。ip_hash要求nginx一定是最前端的伺服器,否則nginx得不到正确ip,就不能根據ip作hash。譬如使用的是squid為最前端,那麼nginx取ip時隻能得到squid的伺服器ip位址,用這個位址來作分流是肯定錯亂的。
- nginx的後端還有其它方式的負載均衡。假如nginx後端又有其它負載均衡,将請求又通過另外的方式分流了,那麼某個用戶端的請求肯定不能定位到同一台session應用伺服器上。這麼算起來,nginx後端隻能直接指向應用伺服器,或者再搭一個squid,然後指向應用伺服器。最好的辦法是用location作一次分流,将需要session的部分請求通過ip_hash分流,剩下的走其它後端去。
5.4 upstream_hash
為了解決ip_hash的一些問題,可以使用upstream_hash這個第三方子產品,這個子產品多數情況下是用作url_hash的,但是并不妨礙将它用來做session共享。
六.關于限流
6.1 ngx_http_limit_conn_module
官方文檔
- limit_conn_zone:
文法規則:[key可以是$binary_remote_addr,$server_name,$server_port,$uri等]
Syntax: limit_conn_zone key zone=name:size;
Default: —
Context: http
- limit_conn:
文法規則:
Syntax: limit_conn zone number;
Default: —
Context: http, server, location
- 示例:
http {
limit_conn_zone $binary_remote_addr zone=addr:10m;
...
server {
...
location /download/ {
limit_conn addr 1;
}
}
...
}
6.2 ngx_http_limit_req_module
官方文檔
- limit_req_zone
文法規則:
Syntax: limit_req_zone key zone=name:size rate=rate [sync];
Default: —
Context: http
- limit_req
Syntax: limit_req zone=name [burst=number] [nodelay | delay=number];
Default: —
Context: http, server, location
- 示例
http {
limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s;#1r/s表示1秒鐘一個請求,1r/m表示1分鐘一個請求,但2r/m等價于30秒一個請求.如果想實作一分鐘内瞬間接受兩個請求,那就要用2r/m配合burst=1來實作了.
...
server {
...
location /search/ {
limit_req zone=one burst=5 nodelay;
}
}
...
}
- 酒店項目配置示例:
http {
limit_req_zone $server_name zone=reqperserver:10m rate=2r/m;
limit_conn_zone $server_name zone=perserver:10m;
limit_conn_zone $uri zone=peruri:10m;
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;
tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 30;
tcp_nodelay on;
#gzip on;
upstream hotelmanage.jsjunyi.com {
ip_hash;
#weigth參數表示權值,權值越高被配置設定到的幾率越大
#本機上的Squid開啟3128端口
server 127.0.0.1:8081;
server 127.0.0.1:8082;
}
server {
#設定檔案上傳大小限制
client_max_body_size 200M;
listen 8080;
server_name hotelmanage.jsjunyi.com;
#charset koi8-r;
#access_log logs/host.access.log main;
location ^~/hotel/photo/ {
alias /data/hotel/photo/;
}
location ^~/hotel/uploads/software {
#limit_req zone=reqperserver burst=1 nodelay;
limit_rate 1000k;
limit_conn perserver 3;
#limit_conn peruri 3;
alias /data/hotel/software/;
}
location / {
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;
proxy_pass http://hotelmanage.jsjunyi.com;
}
}
}
#以上配置一個靈異的點在于:
location ^~/hotel/uploads/software
改為
location ^~/uploads/software
時是不起作用的,這就說明location配置的時候,最好從端口号之後就開始比對.
七.vue打包dist放在nginx下的配置
7.1 配置檔案
server {
#偵聽10010端口
listen 9191;
#限制檔案上傳的大小,預設為1m,設為0表示無限制
client_max_body_size 200m;
#定義使用www.xx.com通路
server_name 10.58.21.170;
#設定本虛拟主機的通路日志
#access_log logs/www.xx.com.access.log main;
location ^~/hotel/photo/ {
alias /data/hotel/photo/;
}
location ^~/hotel/uploads/software/ {
alias /data/hotel/software/;
}
#location /hotel/main/ {
# root /data/;
# index /hotel/dist/index.html;
# try_files $uri $uri/ /hotel/dist/index.html;
#}
#location /hotel/dist/ {
# alias /data/hotel/dist/;
#}
#前端路由配置,通路/fontEndHotel下的某個檔案,找不到就傳回/fontEndHotel/dist/index.html
location /fontEndHotel/ {
root /data/hotel/;
index /fontEndHotel/dist/index.html;
try_files $uri $uri/ /fontEndHotel/;#這裡/fontEndHotel/也可以寫成/fontEndHotel/dist/index.html
}
#預設請求轉發給後端伺服器
location / {
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;
proxy_pass http://10.58.21.170;
}
}
#最重要的是做到前端路由和後端路由的區分,不能都是/hotel/...,這樣就沒辦法用location進行區分,隻要是區分開的,這邊配置就簡單了,就是兩個location的事情.建議前端保持不變,後端不用hotel,用hotelapi之類的,前端畢竟是要展示在頁面上的,用hotel比較好.
附錄:
1.資料參考:
Nginx靜态檔案路徑配置:root目錄與alias目錄的差別
使用Nginx實作Tomcat叢集負載均衡
Nginx +tomcat 實作負載均衡叢集
nginx反向代理後,jsp頁面request.getServerPort()擷取得端口号總是80解決方案
nginx+tomcat影響request值
Nginx http_limit_req子產品詳解
Nginx一種限流方案
nginx叢集tomcat,session共享問題
NGINX 借助JEDIS 對TOMCAT做SESSION共享
2. 零星知識點:
- 文法規則: location [=||*|^~] /uri/ { … }
= 開頭表示精确比對
^~ 開頭表示uri以某個正常字元串開頭,了解為比對 url路徑即可。nginx不對url做編碼,是以請求為/static/20%/aa,可以被規則^~ /static/ /aa比對到(注意是空格)。
~ 開頭表示區分大小寫的正則比對
~* 開頭表示不區分大小寫的正則比對
!~和!~*分别為區分大小寫不比對及不區分大小寫不比對 的正則
/ 通用比對,任何請求都會比對到。
多個location配置的情況下比對順序為(參考資料而來,還未實際驗證,試試就知道了,不必拘泥,僅供參考):
首先比對 =,其次比對^~, 其次是按檔案中順序的正則比對,最後是交給 / 通用比對。當有比對成功時候,停止比對,按目前比對規則處理請求。
- 伺服器叢集的名稱不能包含下劃線??
- alias和root的差別:
root:真實的路徑是root指定的值加上location指定的值。結尾的/可加可不加.
alias:指定的路徑是location的别名,不管location的值怎麼寫,資源的真實路徑都是 alias 指定的路徑