使用Nginx主要是來解決高併發狀況下的負載均衡問題。css
一、最主要是負載均衡請求分發。java
二、文件上傳功能,只能上傳到一個Tomcat上,下載文件或者圖片的時候就有可能發生404錯誤。node
三、多個Tomcat之間Session共享問題,不然會出現不斷要求登陸的狀況。linux
一、第一個問題確定就是使用Nginx來作負載均衡。安裝Nginx,請參考:Linux Centos 6.5_x86安裝Nginx。程序員
二、第二個問題思路有兩個:web
a)在Linux上搭建NFS服務器來實現文件共享,參考:Tomcat 集羣 文件上傳下載的共享問題 NFS配置。redis
b)利用Nginx的負載均衡,請求轉發功能,將關於圖片的上傳和下載請求所有轉到一臺Tomcat上。具體配置參考下邊配置一節。本文使用的是這種方式。
三、上述提到的第三個問題即Session共享問題選擇是Tomcat-Redis-Session_manager來解決的,具體請參考:使用Tomcat-redis-session-manager來實現Tomcat集羣部署中的Session共享。
三、一臺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這組服務器。具體的路徑規則請按照本身項目需求約定。Nginx配置參數請參考書籍:《實戰Nginx:取代Apache的高性能Web服務器》。
將三個應用分別部署到不一樣的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中獲取的,也就解決了第二個問題。
一、此時Nginx只有一臺,若是這臺Nginx訪問不了了,整個集羣就沒法提供服務,因此爲了實現Nginx的高可用,須要實現Nginx的failover,實現方式參考:Nginx+Keepalived實現站點高可用。
二、Redis的問題同上,參考:keepalived+redis 高可用redis主從解決方案。