1. 程式人生 > >Nginx+Tomcat搭建叢集環境

Nginx+Tomcat搭建叢集環境

叢集概述與架構介紹

Tomcat叢集能帶來什麼:

  • 提高服務的效能,例如計算處理能力、併發能力等,以及實現服務的高可用性
  • 提供專案架構的橫向擴充套件能力,增加叢集中的機器就能提高叢集的效能

Tomcat叢集實現方式:

  • Tomcat叢集的實現方式有多種,最簡單的就是通過Nginx負載進行請求轉發來實現

Tomcat單機架構圖:
Nginx+Tomcat搭建叢集環境

可能看了上面的Tomcat單機的架構圖後,會 ”想當然“ 的覺得Tomcat叢集架構是這樣子的:
Nginx+Tomcat搭建叢集環境

這種 ”想當然“ 的Tomcat叢集會帶來什麼問題:

  • Session登入資訊儲存及讀取的問題
  • 伺服器定時任務併發的問題
  • ......

所以架構的演進並不是 ”想當然“ 的那麼簡單,當我們的架構隨著業務的需求進行演進時,就可能會發生程式碼上的改動,以及其他各方面配置及機器的改動,並不是單純的增加Tomcat機器就行了。因為架構的演進都不是一蹴而就的,程式設計是一個遇見問題解決問題的過程,所以我們不可能一下子就設計出一個完美的架構,而且也不存在完美的架構,只有合適的架構。

常見的Tomcat叢集解決方案:

  • 採用 nginx 中的 ip hash policy 來保持某個ip始終連線在某一個機器上
    • 優點:可以不改變現有的技術架構,直接實現橫向擴充套件,省事。但是缺陷也很明顯,在實際的生產環境中,極少使用這種方式
    • 缺點:1.單止伺服器請求(負載)不均衡,這是完全依賴 ip hash 的結果。2.客戶機ip動態變化頻繁的情況下,無法進行服務,因為可能每次的ip hash都不一樣,就無法始終保持只連線在同一臺機器上。
  • 採用redis或memchche等nosql資料庫,實現一個快取session的伺服器,當請求過來的時候,所有的Tomcat Server都統一往這個伺服器裡讀取session資訊。這是企業中比較常用的一種解決方案,所以大致的Tomcat叢集的架構圖如下:

Nginx+Tomcat搭建叢集環境


單機部署多個Tomcat例項(Linux)

由於考慮到在學習時,可能沒有足夠的機器資源去用多臺機器部署多個Tomcat例項,所以本節將簡單介紹一下如何在Linux系統環境下,單機部署多個Tomcat例項。多機就不介紹了,因為多機就是一臺機器安裝一個Tomcat就行了,不需要做額外的更改。

1.到Tomcat官網中,複製Tomcat的下載連結進行下載並解壓到相應的目錄下:

[[email protected] /usr/local/src]# wget http://mirrors.hust.edu.cn/apache/tomcat/tomcat-9/v9.0.7/bin/apache-tomcat-9.0.7.tar.gz
[[email protected] /usr/local/src]# tar -zxvf apache-tomcat-9.0.7.tar.gz -C /usr/local/

2.安裝好Tomcat後,將Tomcat目錄拷貝多份出來。並更改一下目錄名稱:

[[email protected] /usr/local]# cp -r apache-tomcat-9.0.7 ./tomcat9-02
[[email protected] /usr/local]# mv apache-tomcat-9.0.7 ./tomcat9-01

3.配置環境變數:

[[email protected] ~]# vim /etc/profile  # 在檔案末尾增加如下內容
export CATALINA_BASE=/usr/local/tomcat9-01
export CATALINA_HOME=/usr/local/tomcat9-01
export TOMCAT_HOME=/usr/local/tomcat9-01

export CATALINA_2_BASE=/usr/local/tomcat9-02
export CATALINA_2_HOME=/usr/local/tomcat9-02
export TOMCAT_2_HOME=/usr/local/tomcat9-02
[[email protected] ~]# source /etc/profile  # 使配置檔案生效

4.第一個Tomcat不需要動,只需要修改第二個Tomcat的相關配置,首先編輯第二個Tomcat安裝目錄中bin目錄下的catalina.sh檔案:

[[email protected] ~]# cd /usr/local/tomcat9-02/bin/
[[email protected] /usr/local/tomcat9-02/bin]# vim catalina.sh  # 找到如下那行註釋,在該註釋下,增加兩行配置
# OS specific support.  $var _must_ be set to either true or false.
export CATALINA_BASE=$CATALINA_2_BASE
export CATALINA_HOME=$CATALINA_2_HOME
[[email protected] /usr/local/tomcat9-02/bin]# 

5.然後編輯第二個Tomcat安裝目錄中conf目錄下的server.xml檔案,在該檔案中需要修改三個埠:

[[email protected] /usr/local/tomcat9-02/bin]# cd ../conf/
[[email protected] /usr/local/tomcat9-02/conf]# vim server.xml
# 第一個埠,Server port節點埠
<Server port="9005" shutdown="SHUTDOWN">

# 第二個埠,Connector port節點埠,也即是Tomcat訪問埠
<Connector port="9080" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" URIEncoding="UTF-8" />

# 第三個埠,Connector port節點埠
<Connector port="9009" protocol="AJP/1.3" redirectPort="8443" />        
[[email protected] /usr/local/tomcat9-02/conf]#     

6.修改完成後,分別進入兩個Tomcat的bin目錄,執行指令碼啟動Tomcat:

# 啟動Tomcat02
[[email protected] /usr/local/tomcat9-02/conf]# cd ../bin/
[[email protected] /usr/local/tomcat9-02/bin]# ./startup.sh 
Using CATALINA_BASE:   /usr/local/tomcat9-02
Using CATALINA_HOME:   /usr/local/tomcat9-02
Using CATALINA_TMPDIR: /usr/local/tomcat9-02/temp
Using JRE_HOME:        /usr/local/jdk1.8
Using CLASSPATH:       /usr/local/tomcat9-02/bin/bootstrap.jar:/usr/local/tomcat9-02/bin/tomcat-juli.jar
Tomcat started.
# 啟動Tomcat01
[[email protected] /usr/local/tomcat9-02/bin]# cd ../../tomcat9-01/bin/
[[email protected] /usr/local/tomcat9-01/bin]# ./startup.sh 
Using CATALINA_BASE:   /usr/local/tomcat9-01
Using CATALINA_HOME:   /usr/local/tomcat9-01
Using CATALINA_TMPDIR: /usr/local/tomcat9-01/temp
Using JRE_HOME:        /usr/local/jdk1.8
Using CLASSPATH:       /usr/local/tomcat9-01/bin/bootstrap.jar:/usr/local/tomcat9-01/bin/tomcat-juli.jar
Tomcat started.
[[email protected] /usr/local/tomcat9-01/bin]# 

啟動完成後,檢查監聽的埠號及程序:

[[email protected] ~]# netstat -lntp |grep java
tcp6       0      0 :::8009                 :::*                    LISTEN      2846/java           
tcp6       0      0 127.0.0.1:9005          :::*                    LISTEN      2784/java           
tcp6       0      0 :::8080                 :::*                    LISTEN      2846/java           
tcp6       0      0 :::9009                 :::*                    LISTEN      2784/java           
tcp6       0      0 :::9080                 :::*                    LISTEN      2784/java           
tcp6       0      0 127.0.0.1:8005          :::*                    LISTEN      2846/java           
[[email protected] ~]# ps aux |grep java
root       2784  5.6  1.5 7105356 123956 pts/0  Sl   06:24   0:06 /usr/local/jdk1.8/bin/java -Djava.util.logging.config.file=/usr/local/tomcat9-02/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djdk.tls.ephemeralDHKeySize=2048 -Djava.protocol.handler.pkgs=org.apache.catalina.webresources -Dorg.apache.catalina.security.SecurityListener.UMASK=0027 -Dignore.endorsed.dirs= -classpath /usr/local/tomcat9-02/bin/bootstrap.jar:/usr/local/tomcat9-02/bin/tomcat-juli.jar -Dcatalina.base=/usr/local/tomcat9-02 -Dcatalina.home=/usr/local/tomcat9-02 -Djava.io.tmpdir=/usr/local/tomcat9-02/temp org.apache.catalina.startup.Bootstrap start
root       2846  6.5  1.4 7105356 119712 pts/0  Sl   06:24   0:05 /usr/local/jdk1.8/bin/java -Djava.util.logging.config.file=/usr/local/tomcat9-01/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djdk.tls.ephemeralDHKeySize=2048 -Djava.protocol.handler.pkgs=org.apache.catalina.webresources -Dorg.apache.catalina.security.SecurityListener.UMASK=0027 -Dignore.endorsed.dirs= -classpath /usr/local/tomcat9-01/bin/bootstrap.jar:/usr/local/tomcat9-01/bin/tomcat-juli.jar -Dcatalina.base=/usr/local/tomcat9-01 -Dcatalina.home=/usr/local/tomcat9-01 -Djava.io.tmpdir=/usr/local/tomcat9-01/temp org.apache.catalina.startup.Bootstrap start
root       2904  0.0  0.0 112680   976 pts/0    S+   06:25   0:00 grep --color=auto java
[[email protected] ~]# 

最後在瀏覽器上訪問兩個不同的埠,看看是否能訪問到Tomcat預設的首頁。如下:
Nginx+Tomcat搭建叢集環境
Nginx+Tomcat搭建叢集環境

至此,我們的單機部署多個Tomcat例項就完成了,如果想繼續部署,依照此法繼續即可。

注:不同的Tomcat例項使用的埠號在系統中必須不能重複,必須是系統沒有使用的端口才行,不然會產生埠衝突。


Nginx負載均衡配置,常用策略,場景及特點簡介

Nginx負載均衡配置及策略:

  • 輪詢(預設)

    • 優點:實現簡單
    • 缺點:不考慮每臺伺服器的處理能力
    • 配置示例如下:
      upstream www.xxx.com {
      # 需要負載的server列表
      server www.xxx.com:8080;
      server www.xxx.com:9080;
      }
  • 權重,使用的較多的策略
    • 優點:考慮了每臺伺服器處理能力的不同,哪臺機器效能高就給哪臺機器的權重高一些
    • 配置示例如下:
      upstream www.xxx.com {
      # 需要負載的server列表,weight表示權重,weight預設為1,如果多個配置權重的節點,比較相對值
      server www.xxx.com:8080 weight=15;
      server www.xxx.com:9080 weight=10;
      }
  • ip hash
    • 優點:能實現同一個使用者始終訪問同一個伺服器
    • 缺點:根據 ip hash 不一定平均
    • 配置示例如下:
      upstream www.xxx.com {
      ip_hash;
      # 需要負載的server列表
      server www.xxx.com:8080;
      server www.xxx.com:9080;
      }
  • url hash (第三方外掛)
    • 優點:能實現同一個服務訪問同一個伺服器,也就是根據url進行負載
    • 缺點:和ip hash一樣,根據 url hash 分配請求不一定平均,請求頻繁的url會請求到同一臺伺服器上
    • 配置示例如下(需要事先安裝外掛)
      upstream www.xxx.com {
      # 需要負載的server列表
      server www.xxx.com:8080;
      server www.xxx.com:9080;
      hash $request_uri;
      }
  • fair (第三方外掛)
    • 特點:按後端伺服器的響應時間來分配請求,響應時間短的優先分配
    • 配置示例如下(需要事先安裝外掛)
      upstream www.xxx.com {
      # 需要負載的server列表
      server www.xxx.com:8080;
      server www.xxx.com:9080;
      fair;
      }

一些負載均衡引數簡介:

upstream www.xxx.com {
    ip_hash;
    # 需要負載的server列表
    server www.xxx.com:8080 down;  # down表示當前的server暫時不參與負載
    server www.xxx.com:9080 weight=2;  # weight預設值為1,weight的值越大,負載的權重就越大  
    server www.xxx.com:7080 backup;  # 其他所有的非backup機器,在down掉或者很忙的時候,才請求backup機器,也就是一個備用機器
    server www.xxx.com:6080;
}

Nginx+Tomcat搭建叢集

在上文中我們已經介紹瞭如何在單機上部署多個Tomcat例項,本節將介紹如何安裝Nginx,並且使用Nginx+Tomcat搭建叢集。

1.到nginx官網上獲取下載連結,然後到Linux上下載並解壓編譯nginx:

[[email protected] ~]# cd /usr/local/src/
[[email protected] /usr/local/src]# wget http://nginx.org/download/nginx-1.14.0.tar.gz
[[email protected] /usr/local/src]# tar -zxvf nginx-1.14.0.tar.gz
[[email protected] /usr/local/src]# cd nginx-1.14.0
[[email protected] /usr/local/src/nginx-1.14.0]# ./configure --prefix=/usr/local/nginx
[[email protected] /usr/local/src/nginx-1.14.0]# echo $?
0
[[email protected] /usr/local/src/nginx-1.14.0]# make && make install
[[email protected] /usr/local/src/nginx-1.14.0]# echo $?
0
[[email protected] /usr/local/src/nginx-1.14.0]# cd ../../nginx/
[[email protected] /usr/local/nginx]# ls  # 安裝完成
conf  html  logs  sbin
[[email protected] /usr/local/nginx]#

2.建立nginx的主配置檔案,因為我們不使用nginx自帶的配置檔案:

[[email protected] /usr/local/nginx/conf]# mv nginx.conf nginx.conf.bak
[[email protected] /usr/local/nginx/conf]# vim nginx.conf  # 內容如下
user nobody nobody;
worker_processes 2;
error_log /usr/local/nginx/logs/nginx_error.log crit;
pid /usr/local/nginx/logs/nginx.pid;
worker_rlimit_nofile 51200;
events
{
    use epoll;
    worker_connections 6000;
}
http
{
    include mime.types;
    default_type application/octet-stream;
    server_names_hash_bucket_size 3526;
    server_names_hash_max_size 4096;
    log_format combined_realip '$remote_addr $http_x_forwarded_for [$time_local]'
    ' $host "$request_uri" $status'
    ' "$http_referer" "$http_user_agent"';
    sendfile on;
    tcp_nopush on;
    keepalive_timeout 30;
    client_header_timeout 3m;
    client_body_timeout 3m;
    send_timeout 3m;
    connection_pool_size 256;
    client_header_buffer_size 1k;
    large_client_header_buffers 8 4k;
    request_pool_size 4k;
    output_buffers 4 32k;
    postpone_output 1460;
    client_max_body_size 10m;
    client_body_buffer_size 256k;
    client_body_temp_path /usr/local/nginx/client_body_temp;
    proxy_temp_path /usr/local/nginx/proxy_temp;
    fastcgi_temp_path /usr/local/nginx/fastcgi_temp;
    fastcgi_intercept_errors on;
    tcp_nodelay on;
    gzip on;
    gzip_min_length 1k;
    gzip_buffers 4 8k;
    gzip_comp_level 5;
    gzip_http_version 1.1;
    gzip_types text/plain application/x-javascript text/css text/htm 
    application/xml;
    add_header Access-Control-Allow-Origin *;
    include vhost/*.conf;
}
[[email protected] /usr/local/nginx/conf]# mkdir ./vhost  # 建立虛擬主機配置檔案的存放目錄
[[email protected] /usr/local/nginx/conf]# cd vhost/
[[email protected] /usr/local/nginx/conf/vhost]# vim www.xxx.com.conf  # 建立虛擬主機配置檔案,內容如下:
upstream 192.168.190.129 {
        # 需要負載的server列表,可以直接使用ip
        server 192.168.190.129:8080 weight=1;
        server 192.168.190.129:9080 weight=3;
        # server www.xxx.com:8080 weight=1;
        # server www.xxx.com:9080 weight=3;
}

server{
  listen 80;
  autoindex on;
  server_name 192.168.190;
  access_log /usr/local/nginx/logs/access.log combined;
  index index.html index.htm index.jsp;

  location / {
        proxy_pass http://192.168.190.129;
        add_header Access-Control-Allow-Origin *;
  }
}
[[email protected] /usr/local/nginx/conf/vhost]# 

3.檢查nginx配置檔案,顯示沒問題則啟動nginx服務:

[[email protected] /usr/local/nginx/conf/vhost]# cd ../../sbin/
[[email protected] /usr/local/nginx/sbin]# ./nginx -t  # 檢查nginx配置檔案
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok
nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
[[email protected] /usr/local/nginx/sbin]# ./nginx -c /usr/local/nginx/conf/nginx.conf  # 啟動nginx服務
[[email protected] /usr/local/nginx/sbin]# netstat -lntp | grep nginx  # 檢查埠是否已監聽
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      5676/nginx: master  
[[email protected] /usr/local/nginx/sbin]# ps aux |grep nginx  # 檢查nginx程序是否正常
root       5676  0.0  0.0  20492   624 ?        Ss   19:57   0:00 nginx: master process ./nginx -c /usr/local/nginx/conf/nginx.conf
nobody     5677  0.0  0.0  22936  3220 ?        S    19:57   0:00 nginx: worker process
nobody     5678  0.0  0.0  22936  3220 ?        S    19:57   0:00 nginx: worker process
root       5683  0.0  0.0 112680   976 pts/0    S+   19:58   0:00 grep --color=auto nginx
[[email protected] /usr/local/nginx/sbin]# 

4.啟動兩個Tomcat例項:

[[email protected] ~]# cd /usr/local/tomcat9-01/bin/
[[email protected] /usr/local/tomcat9-01/bin]# ./startup.sh 
Using CATALINA_BASE:   /usr/local/tomcat9-01
Using CATALINA_HOME:   /usr/local/tomcat9-01
Using CATALINA_TMPDIR: /usr/local/tomcat9-01/temp
Using JRE_HOME:        /usr/local/jdk1.8
Using CLASSPATH:       /usr/local/tomcat9-01/bin/bootstrap.jar:/usr/local/tomcat9-01/bin/tomcat-juli.jar
Tomcat started.
[[email protected] /usr/local/tomcat9-01/bin]# cd /usr/local/tomcat9-02/bin/
[[email protected] /usr/local/tomcat9-02/bin]# ./startup.sh 
Using CATALINA_BASE:   /usr/local/tomcat9-02
Using CATALINA_HOME:   /usr/local/tomcat9-02
Using CATALINA_TMPDIR: /usr/local/tomcat9-02/temp
Using JRE_HOME:        /usr/local/jdk1.8
Using CLASSPATH:       /usr/local/tomcat9-02/bin/bootstrap.jar:/usr/local/tomcat9-02/bin/tomcat-juli.jar
Tomcat started.
[[email protected] /usr/local/tomcat9-02/bin]# 

5.修改第二個Tomcat例項index.jsp檔案內容,以作為兩個Tomcat例項的區別,方便一會驗證負載均衡是否已成功生效:

[[email protected] ~]# vim /usr/local/tomcat9-02/webapps/ROOT/index.jsp 
<div id="congrats" class="curved container">
    <h2>I'm Tomcat 2</h2>
</div>
[[email protected] ~]# 

6.設定防火牆規則,開放80埠:

[[email protected] ~]# firewall-cmd --zone=public --add-port=80/tcp --permanent
success
[[email protected] ~]# firewall-cmd --reload
success
[[email protected] ~]# 

7.使用瀏覽器進行訪問,驗證nginx的負載均衡是否已成功生效:
Nginx+Tomcat搭建叢集環境
Nginx+Tomcat搭建叢集環境

如上,驗證成功,我們配置的nginx的負載均衡成功。到此為止,我們的Tomcat叢集環境就搭建完成了。