基于Tomcat + Nginx搭建負載均衡的服務(wù)器

nginx是一個高性能的HTTP和反向代理服務(wù)器,同時也是一個IMAP/POP3/SMTP 代理服務(wù)器。它主要有以下優(yōu)點:

  • 高并發(fā)連接: 官方測試能夠支撐5萬并發(fā)連接,在實際生產(chǎn)環(huán)境中跑到2~3萬并發(fā)連接數(shù)。
  • 內(nèi)存消耗少: 在3萬并發(fā)連接下,開啟的10個Nginx 進程才消耗150M內(nèi)(15M*10=150M)。
  • 配置文件非常簡單:風(fēng)格跟程序一樣通俗易懂。
  • 成本低廉: Nginx為開源軟件,可以免費使用。而購買F5 BIG-IP、NetScaler等硬件負載均衡交換機則需要十多萬至幾十萬人民幣。
  • 支持Rewrite重寫規(guī)則:能夠根據(jù)域名、URL的不同,將 HTTP 請求分到不同的后端服務(wù)器群組。
  • 內(nèi)置的健康檢查功能: 如果 Nginx Proxy 后端的某臺 Web 服務(wù)器宕機了,不會影響前端訪問。
  • 節(jié)省帶寬: 支持 GZIP 壓縮,可以添加瀏覽器本地緩存的 Header 頭。
  • 穩(wěn)定性高: 用于反向代理,宕機的概率微乎其微

由于nginx的性能很好,因此國內(nèi)很多大公司都在使用,最主要的原因也是nginx是開源免費的。除了上面描述的一系列功能,項目中主要用nginx來實現(xiàn)以下三個功能:

  • 動靜分離
  • 反向代理
  • 負載均衡

動靜分離

動靜分離的原理非常簡單,我們可以將一些靜態(tài)資源html文件、圖片等交給nginx來處理,將后臺請求轉(zhuǎn)發(fā)給后臺服務(wù)器處理,由于nginx會有緩存作用,因此這樣不僅僅加快了訪問速度,而且也減小了tomcat服務(wù)器的負載。

反向代理

反向代理(Reverse Proxy)方式是指以代理服務(wù)器來接受internet上的連接請求,然后將請求轉(zhuǎn)發(fā)給內(nèi)部網(wǎng)絡(luò)上的服務(wù)器,并將從服務(wù)器上得到的結(jié)果返回給internet上請求連的客戶端,此時代理服務(wù)器對外就表現(xiàn)為一個服務(wù)器。


image.png

需要注意的是代理服務(wù)器可以作為前端服務(wù)器來處理前端等請求處理靜態(tài)資源,但是不能處理后端服務(wù)器的請求。

nginx反向代理主要有以下特點:

反向代理又稱為Web服務(wù)器加速,是針對Web服務(wù)器提供加速功能的。它作為代理Cache,但并不針對瀏覽器用戶,而針對一臺或多臺特定Web服務(wù)器(這也是反向代理名稱的由來)。代理服務(wù)器可以緩存一些web的頁面,降低了web服務(wù)器的訪問量,所以可以降低web服務(wù)器的負載。web服務(wù)器同時處理的請求數(shù)少了,響應(yīng)時間自然就快了。同時代理服務(wù)器也存了一些頁面,可以直接返回給客戶端,加速客戶端瀏覽。

負載均衡

負載均衡主要是為了解決服務(wù)器負載過大,在有的時候,系統(tǒng)的并發(fā)量過大,一臺服務(wù)器無法負擔(dān)的起用戶發(fā)送的請求,因此我們需要搭建服務(wù)器集群,而nginx負載均衡就是接收用戶的請求將其轉(zhuǎn)發(fā)給后臺服務(wù)器集群上的每一臺機器。


image.png

負載均衡主要有以下特點:

  • 分散后臺服務(wù)器的負載
  • 自動去掉后臺宕機的服務(wù)器
  • 緩存后臺請求內(nèi)容,加速請求速度

nginx負載均衡主要有以下五種策略:

1、輪詢(默認)

每個請求按時間順序逐一分配到不同的后端服務(wù)器,如果后端服務(wù)器down掉,能自動剔除。

2、 weight

指定輪詢幾率,weight和訪問比率成正比,用于后端服務(wù)器性能不均的情況。

3、ip_hash

每個請求按訪問ip的hash結(jié)果分配,這樣每個訪客固定訪問一個后端服務(wù)器,可以解決session的問題。

4、fair(第三方)

按后端服務(wù)器的響應(yīng)時間來分配請求,響應(yīng)時間短的優(yōu)先分配。

5、url_hash(第三方)

按訪問url的hash結(jié)果來分配請求,使每個url定向到同一個后端服務(wù)器,后端服務(wù)器為緩存時比較有效。
默認情況下是輪詢的策略,但是這種方式的使用有一個問題,分布式session不一致的問題,不過我們可以使用ip_hash來將同一ip地址上的請求分配到一臺服務(wù)器中處理,這樣就不會出現(xiàn)session不一致的問題。這個問題不是我們這篇文章討論的重點,感興趣的讀者可以自行查詢資料。

Nginx下載安裝

Nginx官方下載地址
下載安裝比較簡單,直接解壓即可運行,具體操作查看下面文章
Nginx安裝與命令(Linux)
Nginx 從安裝到配置,看這篇教程就夠了

驗證是否安裝成功

nginx  -V
image.png

如果需要任何地方都可以執(zhí)行,直接在系統(tǒng)環(huán)境上添加安裝目錄即可


image.png

驗證成功

image.png

查看nginx進程

tasklist /fi  "imagename eq nginx.exe"
image.png

殺掉nginx進程

taskkill  /f  /pid 11044 /pid 7092
image.png

需要管理員權(quán)限,用管理員權(quán)限打開CMD,然后再次輸入上面的命令


image.png

啟動Nginx

start nginx.exe

注意需要先進入安裝目錄,在執(zhí)行start命令

cd C:\MyProgram\nginx-1.19.4
image.png

訪問localhost:80 測試 ngnix 是否正常運行

返回 nginx 歡迎頁表示正常運行


image.png

window下Nginx啟動bat腳本

對于常用的命令,可以寫成腳本的方式,這樣會更加方便。

@echo off
rem 提供Windows下nginx的啟動,重啟,關(guān)閉功能
 
echo ==================begin========================
 
cls 
::ngxin 所在的盤符
set NGINX_PATH=C:
 
::nginx 所在目錄
set NGINX_DIR=C:\MyProgram\nginx-1.19.4\
color 0a 
TITLE Nginx 管理程序增強版
 
CLS 
 
echo. 
echo. ** Nginx 管理程序  *** 
echo. 
 
:MENU 
 
echo. ***** nginx 進程list ****** 
::tasklist|findstr /i "nginx.exe"
tasklist /fi "imagename eq nginx.exe"
 
echo. 
 
    if ERRORLEVEL 1 (
        echo nginx.exe不存在
    ) else (
        echo nginx.exe存在
    )
 
echo. 
::*************************************************************************************************************
echo. 
    echo.  [1] 啟動Nginx  
    echo.  [2] 關(guān)閉Nginx  
    echo.  [3] 重啟Nginx 
    echo.  [4] 刷新控制臺  
    echo.  [5] 重新加載Nginx配置文件
    echo.  [6] 檢查測試nginx配置文件
    echo.  [7] 查看nginx version
    echo.  [0] 退 出 
echo. 
 
echo.請輸入選擇的序號:
set /p ID=
    IF "%id%"=="1" GOTO start 
    IF "%id%"=="2" GOTO stop 
    IF "%id%"=="3" GOTO restart 
    IF "%id%"=="4" GOTO MENU
    IF "%id%"=="5" GOTO reloadConf 
    IF "%id%"=="6" GOTO checkConf 
    IF "%id%"=="7" GOTO showVersion 
    IF "%id%"=="0" EXIT
PAUSE 
 
::*************************************************************************************************************
::啟動
:start 
    call :startNginx
    GOTO MENU
 
::停止
:stop 
    call :shutdownNginx
    GOTO MENU
 
::重啟
:restart 
    call :shutdownNginx
    call :startNginx
    GOTO MENU
 
::檢查測試配置文件
:checkConf 
    call :checkConfNginx
    GOTO MENU
 
::重新加載Nginx配置文件
:reloadConf 
    call :checkConfNginx
    call :reloadConfNginx
    GOTO MENU
    
::顯示nginx版本
:showVersion 
    call :showVersionNginx
    GOTO MENU   
    
    
::*************************************************************************************
::底層
::*************************************************************************************
:shutdownNginx
    echo. 
    echo.關(guān)閉Nginx...... 
    taskkill /F /IM nginx.exe > nul
    echo.OK,關(guān)閉所有nginx 進程
    goto :eof
 
:startNginx
    echo. 
    echo.啟動Nginx...... 
    IF NOT EXIST "%NGINX_DIR%nginx.exe" (
        echo "%NGINX_DIR%nginx.exe"不存在
        goto :eof
     )
 
    %NGINX_PATH% 
    cd "%NGINX_DIR%" 
 
    IF EXIST "%NGINX_DIR%nginx.exe" (
        echo "start '' nginx.exe"
        start "" nginx.exe
    )
    echo.OK
    goto :eof
    
 
:checkConfNginx
    echo. 
    echo.檢查測試 nginx 配置文件...... 
    IF NOT EXIST "%NGINX_DIR%nginx.exe" (
        echo "%NGINX_DIR%nginx.exe"不存在
        goto :eof
     )
 
    %NGINX_PATH% 
    cd "%NGINX_DIR%" 
    nginx -t -c conf/nginx.conf
 
    goto :eof
    
::重新加載 nginx 配置文件
:reloadConfNginx
    echo. 
    echo.重新加載 nginx 配置文件...... 
    IF NOT EXIST "%NGINX_DIR%nginx.exe" (
        echo "%NGINX_DIR%nginx.exe"不存在
        goto :eof
     )
 
    %NGINX_PATH% 
    cd "%NGINX_DIR%" 
    nginx -s reload
 
    goto :eof
    
::顯示nginx版本
:showVersionNginx
    echo. 
    %NGINX_PATH% 
    cd "%NGINX_DIR%" 
    nginx -V
    goto :eof
image.png

安裝Tomcat

基本的安裝運行請查看下方文章
SpringBootServletInitializer (Tomcat)啟動spring boot項目

Tomcat多實例部署

Tomcat 中比較重要的概念(通常也是兩個系統(tǒng)變量)CATALINA_HOMECATALINA_BASE

  • CATALINA_HOME:即指向Tomcat安裝路徑的系統(tǒng)變量(安裝目錄)
  • CATALINA_BASE:即指向活躍配置路徑的系統(tǒng)變量(工作目錄)

通過設(shè)置這兩個變量,就可以將Tomcat的安裝目錄和工作目錄分離,從而實現(xiàn)Tomcat多實例的部署。

復(fù)制tomcate

復(fù)制tomcate安裝文件夾,本例在本地模擬三臺tomcat服務(wù)器(一個home和兩個base)和一臺nginx服務(wù)器


image.png

三個 Tomcat,它們的作用分別是:

目錄 作用
tomcat-home 作為 CATALINA_HOME,即只需要保留 bin 和 lib 兩個文件夾
tomcat-8080 作為 CATALINA_BASE,需要保留除了 bin 和 lib 之外的其他文件夾,使用 8080 端口
tomcat-9090 同 tomcat-8080,使用 9090 端口

Tomcat 的基本目錄結(jié)構(gòu),以及對應(yīng)的作用:

目錄 簡介
bin 存放腳本文件,例如比較常用的啟動和關(guān)閉腳本 startup.sh、shutdown.sh
conf 存放配置文件,如server.xml它是 tomcat 的主要配置文件
lib Tomcat 運行需要的依賴包
log 存放日志文件
temp 存放運行時產(chǎn)生的臨時文件
webapps web 應(yīng)用的默認目錄,通常war包會部署到這里
work 主要存放由JSP文件生成的servlet(Java文件以及最終編譯生成的class文件)

Tomcat官方文檔上說明了 CATALINA_HOME 路徑下需要包含 bin 和 lib 目錄,也就是兩個支持 tomcat 運行的目錄,而 CATALINA_BASE 可以包含所有目錄,但是 bin 和 lib 不是必須的,缺省時會使用 CATALINA_HOME 中的 bin 和 lib。
因此我們就可以使用一個 CATALINA_HOME 和多個 CATALINA_BASE 部署多個實例,這樣的好處是便于管理和升級 Tomcat。

按照上面的要求刪除三個tomcat目錄下無用的文件夾:
tomcat-home 保留 bin 和 lib 目錄,刪除其他目錄
omcat-8080 保留除了 bin 和 lib 之外的其他文件夾,使用 8080 端口
tomcat-9090 保留除了 bin 和 lib 之外的其他文件夾,使用 9090 端口

修改 Tomcat 配置文件

image.png

這一步主要是修改conf目錄下的 server.xml 中端口的配置,在 server.xml 中配置了四個監(jiān)聽端口,分別是:

  • Server port(默認8005): 監(jiān)聽關(guān)閉 tomcat 的 shutdown 命令
  • Connector port(默認8080):監(jiān)聽 http 請求
  • AJP Connector port(默認8009):監(jiān)聽 AJP 請求
  • redirectPort(默認8443):重定向端口,出現(xiàn)在Connector配置中,如果該Connector僅支持非SSL的普通http請求,那么該端口會把https的請求轉(zhuǎn)發(fā)到這個Redirect Port指定的端口

了解了監(jiān)聽的各個端口的作用之后就可以開始修改 server.xml 了,如果不使用 AJP 請求,那么我們只需要保證多實例中的 Server port 和 Connector port 不同即可

# tomcat-8080 保持默認配置即可
# 修改 tomcat-9090 的配置,修改后的 /tomcat-9090/conf/server.xml 內(nèi)容如下:
...
<Server port="9005" shutdown="SHUTDOWN">
...
<Connector port="9090" protocol="HTTP/1.1"
           connectionTimeout="20000"
           redirectPort="8443" />
...
# tomcat-8080 保持默認配置即可
# 修改 tomcat-9090 的配置,修改后的 /tomcat-9090/conf/server.xml 內(nèi)容如下:
...
<Server port="9005" shutdown="SHUTDOWN">
...
<Connector port="9090" protocol="HTTP/1.1"
           connectionTimeout="20000"
           redirectPort="8443" />
...

大概有3個地方休要修改


image.png

編寫腳本

前面的準(zhǔn)備工作做完之后就可以啟動 Tomcat 了,但是現(xiàn)在只有 tomcat-home/bin 目錄下有 startup.shshutdown.sh,而我們要啟動的 8080 和 9090 兩個實例,因此我們就需要編寫一段腳本,修改 CATALINA_BASE 來達到分別操作兩個實例的目的:

啟動腳本start.sh

#!/bin/sh
CUR_DIR=`dirname $BASH_SOURCE`
export CATALINA_BASE=`readlink -f $CUR_DIR`
export CATALINA_HOME="/usr/local/tomcat-home"

if [ -f $CATALINA_HOME/bin/startup.sh ]; then
        $CATALINA_HOME/bin/startup.sh
else
        echo "$CATALINA_HOME/bin/startup.sh not exist"
fi

windows

@REM 啟動 tomcat-8080
echo 啟動 tomcat-8080
set "CATALINA_BASE=%cd%"
set "CATALINA_HOME=C:\Program Files\Apache Software Foundation\tomcat-home"
set "EXECUTABLE=%CATALINA_HOME%\bin\catalina.bat"
call "%EXECUTABLE%" start
pause

停止腳本stop.sh

#!/bin/sh
CUR_DIR=`dirname $BASH_SOURCE`
export CATALINA_BASE=`readlink -f $CUR_DIR`
export CATALINA_HOME="/usr/local/tomcat-home"

if [ -f $CATALINA_HOME/bin/shutdown.sh ]; then
       $CATALINA_HOME/bin/shutdown.sh
else
       echo "$CATALINA_HOME/bin/shutdown.sh not exist"
fi

windows

@REM 關(guān)閉 tomcat-8080
echo 關(guān)閉 tomcat-8080
cd C:\Program Files\Apache Software Foundation\tomcat-home\bin
call shutdown.bat
pause

當(dāng)然關(guān)閉和開啟也可以使用前面提及的tasklist taskkill等

然后將這兩個腳本文件放在 tomcat-8080 和 tomcat-9090 的根目錄下:

[root@localhost tomcat-8080]# ls
conf     logs    RELEASE-NOTES  start.sh  temp     work
LICENSE  NOTICE  RUNNING.txt    stop.sh   webapps

測試兩個 Tomcat 是否同時正常運行

tomcat-8080/webapps/ROOTtomcat-9090/webapps/ROOT 目錄下分別新建一個 index.html 文件,內(nèi)容分別為 “8080” 和 “9090” 便于我們區(qū)分。

完成之后使用 start.sh 啟動兩個實例

image.png

直接瀏覽器輸入localhost:9090 和localhost:8080


image.png

我們還可以使用 curl 訪問來測試:

# 訪問 9090 端口,獲取到 9090 的數(shù)據(jù)
[root@localhost tomcat-9090]# curl localhost:9090
<h1> 9090 </h1>
# 訪問 8080 端口,獲取到 8080 的數(shù)據(jù)
[root@localhost tomcat-8080]# curl localhost:8080
<h1>8080 </h1>

Nginx 與 Tomcat 進行負載均衡

打開nginx安裝目錄,找到conf目錄下的nginx.conf

# 進入 ngnix 配置文件的目錄
# 默認配置文件是 ngnix.conf
http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    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  /var/log/nginx/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    keepalive_timeout  65;

    gzip  on;
    gzip_types   text/css text/x-component application/x-javascript application/javascript text/javascript text/x-js text/richtext image/svg+xml text/plain text/xsd text/xsl text/xml image/x-icon;

    include /etc/nginx/conf.d/*.conf;

 # Tomcat 服務(wù)器集群
   upstream app_server {
        server 127.0.0.1:8080 weight=1;
        server 127.0.0.1:9080 weight=1;
   }
...

server {
     listen 80;

     server_name  api.xxx.com;

     location / {
            ...
            # 請求轉(zhuǎn)發(fā)給 Tomcat 集群處理
            proxy_pass http://app_server;
     }

  }

nginx -s reload

不同的系統(tǒng)配置文件位置不一樣


image.png
image.png
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容