Nginx+Tomcat搭建叢集環境
叢集概述與架構介紹
Tomcat叢集能帶來什麼:
- 提高服務的效能,例如計算處理能力、併發能力等,以及實現服務的高可用性
- 提供專案架構的橫向擴充套件能力,增加叢集中的機器就能提高叢集的效能
Tomcat叢集實現方式:
- Tomcat叢集的實現方式有多種,最簡單的就是通過Nginx負載進行請求轉發來實現
Tomcat單機架構圖:
可能看了上面的Tomcat單機的架構圖後,會 ”想當然“ 的覺得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叢集的架構圖如下:
單機部署多個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預設的首頁。如下:
至此,我們的單機部署多個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叢集環境就搭建完成了。