使用Nginx實現Tomcat集羣負載均衡

  1. 概述
  2. 要解決的問題
  3. 環境準備以及問題解決思路
  4. 配置
  5. 測試
  6. 小結

1、概述javascript

  使用Nginx主要是來解決高併發狀況下的負載均衡問題。css

2、要解決的問題html

  一、最主要是負載均衡請求分發。java

  二、文件上傳功能,只能上傳到一個Tomcat上,下載文件或者圖片的時候就有可能發生404錯誤。node

  三、多個Tomcat之間Session共享問題,不然會出現不斷要求登陸的狀況。linux

3、環境準備以及問題解決思路nginx

  一、第一個問題確定就是使用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

4、配置

  

# 使用的用戶和組
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服務器》。

5、測試

  將三個應用分別部署到不一樣的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中獲取的,也就解決了第二個問題。

6、小結

  一、此時Nginx只有一臺,若是這臺Nginx訪問不了了,整個集羣就沒法提供服務,因此爲了實現Nginx的高可用,須要實現Nginx的failover,實現方式參考:Nginx+Keepalived實現站點高可用

  二、Redis的問題同上,參考:keepalived+redis 高可用redis主從解決方案

相關文章
相關標籤/搜索