基于Tomcat + Nginx搭建負載均衡的服務器

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

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

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

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

動靜分離

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

反向代理

反向代理(Reverse Proxy)方式是指以代理服務器來接受internet上的連接請求,然后將請求轉發給內部網絡上的服務器,并將從服務器上得到的結果返回給internet上請求連的客戶端,此時代理服務器對外就表現為一個服務器。


image.png

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

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

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

負載均衡

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


image.png

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

  • 分散后臺服務器的負載
  • 自動去掉后臺宕機的服務器
  • 緩存后臺請求內容,加速請求速度

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

1、輪詢(默認)

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

2、 weight

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

3、ip_hash

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

4、fair(第三方)

按后端服務器的響應時間來分配請求,響應時間短的優先分配。

5、url_hash(第三方)

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

Nginx下載安裝

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

驗證是否安裝成功

nginx  -V
image.png

如果需要任何地方都可以執行,直接在系統環境上添加安裝目錄即可


image.png

驗證成功

image.png

查看nginx進程

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

殺掉nginx進程

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

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


image.png

啟動Nginx

start nginx.exe

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

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

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

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


image.png

window下Nginx啟動bat腳本

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

@echo off
rem 提供Windows下nginx的啟動,重啟,關閉功能
 
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] 關閉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.關閉Nginx...... 
    taskkill /F /IM nginx.exe > nul
    echo.OK,關閉所有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 中比較重要的概念(通常也是兩個系統變量)CATALINA_HOMECATALINA_BASE

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

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

復制tomcate

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


image.png

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

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

Tomcat 的基本目錄結構,以及對應的作用:

目錄 簡介
bin 存放腳本文件,例如比較常用的啟動和關閉腳本 startup.shshutdown.sh
conf 存放配置文件,如server.xml它是 tomcat 的主要配置文件
lib Tomcat 運行需要的依賴包
log 存放日志文件
temp 存放運行時產生的臨時文件
webapps web 應用的默認目錄,通常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 中配置了四個監聽端口,分別是:

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

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

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

大概有3個地方休要修改


image.png

編寫腳本

前面的準備工作做完之后就可以啟動 Tomcat 了,但是現在只有 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 關閉 tomcat-8080
echo 關閉 tomcat-8080
cd C:\Program Files\Apache Software Foundation\tomcat-home\bin
call shutdown.bat
pause

當然關閉和開啟也可以使用前面提及的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 文件,內容分別為 “8080” 和 “9090” 便于我們區分。

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

image.png

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


image.png

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

# 訪問 9090 端口,獲取到 9090 的數據
[root@localhost tomcat-9090]# curl localhost:9090
<h1> 9090 </h1>
# 訪問 8080 端口,獲取到 8080 的數據
[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 服務器集群
   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 / {
            ...
            # 請求轉發給 Tomcat 集群處理
            proxy_pass http://app_server;
     }

  }

nginx -s reload

不同的系統配置文件位置不一樣


image.png
image.png
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,327評論 6 537
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,996評論 3 423
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,316評論 0 382
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,406評論 1 316
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,128評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,524評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,576評論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,759評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,310評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,065評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,249評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,821評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,479評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,909評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,140評論 1 290
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,984評論 3 395
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,228評論 2 375

推薦閱讀更多精彩內容