一、概述
使用Nginx主要是來解決高并發情況下的負載均衡問題。
二、要解決的問題
1、最主要是負載均衡請求分發。
2、文件上傳功能,只能上傳到一個Tomcat上,下載文件或者圖片的時候就有可能發生404錯誤。
3、多個Tomcat之間Session共享問題,否則會出現不斷要求登錄的情況。
三、環境準備以及問題解決思路
1、第一個問題肯定就是使用Nginx來做負載均衡。安裝Nginx,請參考:Linux Centos 6.5_x86安裝Nginx。
2、第二個問題思路有兩個:
(2)在Linux上搭建NFS服務器來實現文件共享,參考:Tomcat 集群 文件上傳下載的共享問題 NFS配置。
(1)利用Nginx的負載均衡,請求轉發功能,將關于圖片的上傳和下載請求全部轉到一臺Tomcat上。具體配置參考下邊配置一節。本文使用的是這種方式。
3、上述提到的第三個問題即Session共享問題選擇是Tomcat-Redis-Session_manager來解決的,具體請參考:使用Tomcat-redis-session-manager來實現Tomcat集群部署中的Session共享。
4、一臺Linux安裝多個Tomcat請參考:linux系統下安裝兩個或多個tomcat。
本文使用的是三臺Tomcat,兩臺處理除文件以外的請求,一臺專門處理文件上傳和下載的請求。
分別為:Tomcat1:192.168.1.96:7070
Tomcat2:192.168.1.96:8081
Tomcat3:192.168.1.96:9090
四、配置
# 使用的用戶和組
user root root;
# 指定工作衍生進程數(一般等于CPU的總核數或總核數的兩倍,例如兩個四核CPU,則綜合數為8.通過命令ps -ef|grep nginx可以看出來設置的是幾個)
worker_processes 8;
#指定錯誤日志存放的路徑,錯誤日志記錄級別可選項為:[debug|info|notice|warn|error|crit],默認是crit,記錄的日志數量從crit到debug,由少到多。
error_log /usr/local/nginx/logs/nginx_error.log crit;
#指定pid存放的路徑
pid /usr/local/nginx/nginx.pid;
# 指定文件描述符數量??
worker_rlimit_nofile 51200;
#events settings
events {
# 使用的網絡I/O模型,Linux系統推薦采用epoll模型,FreeeBSD系統推薦采用kqueue模型
use epoll;
# 允許的連接數
worker_connections 51200;
}
#遵循http協議的服務器全局設置
http {
include mime.types;
default_type application/octet-stream;
#設置使用的字符集,如果一個網站有多種字符集,請不要隨便設置,應讓程序員在HTML代碼中通過Meta標簽設置
#charset utf-8;
server_names_hash_bucket_size 128;
client_header_buffer_size 32k;
large_client_header_buffers 4 32k;
# 設置客戶端能夠上傳的文件大小,注意要與應用程序中的文件大小限制兼容。
client_max_body_size 300m;
sendfile on;
tcp_nopush on;
keepalive_timeout 60;
tcp_nodelay on;
client_body_buffer_size 512k;
proxy_connect_timeout 5;
proxy_read_timeout 60;
proxy_send_timeout 5;
proxy_buffer_size 16k;
proxy_buffers 4 64k;
proxy_busy_buffers_size 128k;
proxy_temp_file_write_size 128k;
#log_format 自定義日志記錄格式設置,main為名字,在access_log命令中引用
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 訪問日志文件設置
#關閉日志記錄
#access_log off;
#指定日志存放路徑,如果想使用默認的combined格式記錄日志,可以使用access_log logs/access.log combined; 以下是使用log_format自定義的格式記錄日志的。
access_log logs/access.log main;
# 開啟gzip壓縮設置(只能在http模塊中設置)
gzip on;
gzip_min_length 1k;
gzip_buffers 4 16k;
gzip_http_version 1.1;
gzip_comp_level 2;
gzip_types application/x-javascript text/css application/xml;
gzip_vary on;
# 用于設置如果出現指定的HTTP錯誤狀態碼,則返回指定的url頁面
error_page 404 /404.html;
error_page 500 502 503 504 /50x.html;
#upstream設置,設置代理服務器(負載均衡池),默認的負載均衡方式是輪詢,另外一種是ip_hash
upstream tomcat_server {
#ip_hash;
server 192.168.1.96:7070 weight=1;
server 192.168.1.96:8081 weight=1;
}
#處理上傳和下載的圖片文件服務器,設置代理服務器(負載均衡池),默認的負載均衡方式是輪訓,另外一種是ip_hash
upstream image_server{
server 192.168.1.96:9090 weight=1;
}
#server虛擬主機設置,可以設置多個:基于IP的虛擬主機,基于域名的虛擬主機
# 第一個虛擬主機(基于域名的虛擬主機),反向代理tomcat_server和image_server這兩組服務器
server {
# 監聽的端口
listen 8000;
# 主機名稱
server_name localhost;
# 設置Nginx的默認首頁文件
index index.html index.htm index.jsp index.do;
#root /home/oracle/dev_tools/server/apache-tomcat-6.0.44/webapps/examples;
# 配置該虛擬機的字符設置,如果不配置繼承自http中的charset設置
#charset koi8-r;
#access_log 訪問日志文件設置,如果server虛擬機中不設置,則繼承http模塊中的access_log的設置
#access_log logs/access.log main;
#rewrite settings
if (-d $request_filename)
{
rewrite ^/(.*)([^/])$ http://$host/$1$2/ permanent;
}
# location模塊說明
# 使用環境:server模塊
# iamge 服務器location
location ——*/NginxTest/image/ {
proxy_pass http://image_server;
}
location ——*/NginxTest/ {
# root /home/oracle/dev_tools/server/apache-tomcat-6.0.44/webapps/;
# HTTP代理模塊 proxy,主要是用來轉發請求到其他服務器
# 如果后端服務器返回502,504,執行超時等錯誤,自動將請求轉發到upstream負載均衡池中的另一臺服務器,實現failover。
proxy_next_upstream http_502 http_504 error timeout invalid_header;
# 變量$host等于客戶端請求頭中的Host值。
proxy_set_header Host $host;
#后端的web服務器可以通過X-Forwarded-For獲取真實的IP地址,$remote_addr客戶端的ip地址
proxy_set_header X-Forwarded-For $remote_addr;
proxy_pass http://tomcat_server;
}
#image expires settings
# expires 屬于http Header模塊,主要用來Nginx返回給用戶網頁添加附件的header信息,可以在http,server,location中使用
location —— .*/.(gif|jpg|jpeg|png|bmp|swf)$
{
expires 30d;
}
#css&js expires settings
# expires 屬于http Header模塊,主要用來Nginx返回給用戶網頁添加附件的header信息,可以在http,server,location中使用
location —— .*/.(js|css|html)?$
{
expires 2h;
}
# 如果http模塊設置了,則繼承。此處設置了則覆蓋。
#error_page 404 /404.html;
#error_page 500 502 503 504 /50x.html;
}
}
以下代碼配置了兩組負載均衡服務器。
#upstream設置,設置代理服務器(負載均衡池),默認的負載均衡方式是輪詢,另外一種是ip_hash
upstream tomcat_server {
#ip_hash;
server 192.168.1.96:7070 weight=1;
server 192.168.1.96:8081 weight=1;
}
#處理上傳和下載的圖片文件服務器,設置代理服務器(負載均衡池),默認的負載均衡方式是輪詢,另外一種是ip_hash
upstream image_server{
server 192.168.1.96:9090 weight=1;
}
第一組就tomcat_server是用來處理普通請求的。第二組image_server主要是用來處理圖片文件的上傳和下載的,可以理解為一個文件服務器,所有文件相關的上傳和下載都通過這組服務器。那怎么配置才能讓Nginx實現這種目的呢?看以下配置:
# iamge 服務器location
location ——*/NginxTest/image/ {
proxy_pass http://image_server;
}
location ——*/NginxTest/ {
# root /home/oracle/dev_tools/server/apache-tomcat-6.0.44/webapps/;
# HTTP代理模塊 proxy,主要是用來轉發請求到其他服務器
# 如果后端服務器返回502,504,執行超時等錯誤,自動將請求轉發到upstream負載均衡池中的另一臺服務器,實現failover。
proxy_next_upstream http_502 http_504 error timeout invalid_header;
# 變量$host等于客戶端請求頭中的Host值。
proxy_set_header Host $host;
#后端的web服務器可以通過X-Forwarded-For獲取真實的IP地址,$remote_addr客戶端的ip地址
proxy_set_header X-Forwarded-For $remote_addr;
proxy_pass http://tomcat_server;
}
其中location ——*/NginxTest/image/ 符合這種url路徑(這種路徑是根據自己的應用需求約定的)的請求轉發到 proxy_pass屬性指定的 image_server服務器,其他請求轉發到tomcat_server這組服務器。具體的路徑規則請按照自己項目需求約定。
五、測試
將三個應用分別部署到不同的Tomcat中,應用代碼下載:NginxTest.rar,
說明:
解壓后有三個文件:NginxTest.war,NginxTest2.war,NginxImageTest.war,
其中NginxTestImage必須放到Tomcat3中,三個應用程序名字在放入Tomcat之后必須都改為NginxTest。
只用NginxTestImage應用有圖片文件,NginxTest和NginxTest2中無圖片文件。
訪問:http://ip:port/NginxTest/whichTomcat,如下圖:
不斷刷新該頁面,SessionId如果是不變化的說明,Session是從Redis中取到的,解決了Session共享問題。
不斷刷新頁面,這是“Tomcat服務器1“文字應該和“Tomcat服務器2”不斷變化,說明請求訪問的不是相同的Tomcat。因為只有Tomcat3中的應用有圖片文件,所以圖片的獲取是從Tomat3中獲取的,也就解決了第二個問題。