基於 CentOS 7 + Nginx + Tomcat 的負載均衡伺服器的搭建

Wh1te發表於2018-03-04

前言

本文主要介紹如何在 CentOS 上從零開始使用 Nginx + Tomcat 搭建一個負載均衡伺服器。在搭建過程中學習 Nginx 的基本使用方式以及 Tomcat 相關知識,進一步理解兩者結合後的執行原理。

Nginx 安裝

使用原始碼編譯的方式在 CentOS 上安裝 Nginx 主要有以下幾個步驟:

  1. 安裝執行環境

    • Nginx 是使用 C 語言開發的,編譯依賴 gcc 環境,因此如果沒有 gcc 需要先安裝:
    yum install -y gcc-c++
    複製程式碼
    • 安裝 Nginx 依賴庫
    # rewrite模組需要 PCRE(Perl Compatible Regular Expressions),pcre-devel 庫
    yum install -y pcre pcre-devel 
    # gzip模組需要 zlib 庫
    yum install -y zlib
    # ssl 功能需要 OpenSSL 庫
    yum install -y openssl openssl-devel
    
    複製程式碼
  2. 下載 Ngnix

    Ngnix 官網下載最新穩定版,目前是 1.12.2

    # 如果還未安裝 wget 請先執行安裝命令
    yum install -y wget
    # 使用 wget 命令下載
    wget -c https://nginx.org/download/nginx-1.12.2.tar.gz
    # 解壓檔案
    tar -zxvf nginx-1.12.2.tar.gz 
    # 進入解壓後的目錄
    cd nginx-1.12.2
    # 使用預設配置
    ./configure
    複製程式碼
  3. 編譯安裝 Nginx

    編譯安裝十分簡單,只需執行兩個命令即可

    # 編譯
    make
    # 安裝
    make install
    # 安裝目錄預設為 /usr/local/nginx
    # 可以使用 whereis nginx 查詢
    [root@localhost nginx-1.12.2]# whereis nginx
    nginx: /usr/local/nginx
    複製程式碼
  4. 啟動測試

    Ngnix 安裝完成後即可啟動測試是否可以正常執行

    # 進入 ngnix 執行檔案目錄
    cd /usr/local/ngnix/sbin
    # 啟動
    # ./nginx  啟動
    # ./nginx -s stop  停止(先查出 nginx 程式 id 再使用 kill 命令強制殺掉程式)
    # ./nginx -s quit  退出(等待 nginx 程式將任務處理完畢再停止)
    # ./nginx -s reload  重新載入,適用於修改了配置檔案之後操作
    ./nginx
    # 啟動之後可以通過 ps 命令查詢 ngnix 程式
    ps aux|grep nginx
    # 訪問localhost:80 測試 ngnix 是否正常執行,返回 nginx 歡迎頁表示正常執行
    [root@localhost sbin]# curl localhost:80
    <!DOCTYPE html>
    <html>
    <head>
    <title>Welcome to nginx!</title>
    <style>
        body {
            width: 35em;
            margin: 0 auto;
            font-family: Tahoma, Verdana, Arial, sans-serif;
        }
    </style>
    </head>
    <body>
    <h1>Welcome to nginx!</h1>
    <p>If you see this page, the nginx web server is successfully installed and
    working. Further configuration is required.</p>
    
    <p>For online documentation and support please refer to
    <a href="http://nginx.org/">nginx.org</a>.<br/>
    Commercial support is available at
    <a href="http://nginx.com/">nginx.com</a>.</p>
    
    <p><em>Thank you for using nginx.</em></p>
    </body>
    </html>
    複製程式碼

Tomcat 多例項部署配置

Tomcat 單例項部署,即一個 Tomcat 伺服器執行時,不存在負載均衡一說,因此,我們首先要做的就是實現 Tomcat 多例項部署,將我們的同一個應用程式部署在多個 Tomcat 伺服器上同時執行。主要步驟如下:

  1. 安裝 JDK(如果本機已經安裝了則跳過第一步)
# 下載、解壓 JDK8,下載地址可以從官網獲取
wget http://download.oracle.com/otn-pub/java/jdk/8u161-b12/2f38c3b165be4555a1fa6e98c45e0808/jdk-8u161-linux-x64.tar.gz?AuthParam=1520068673_6f545cf32470b83658219011266e65b8
# 配置 Java 環境變數
vi /etc/profile
# 在檔案尾部新增以下內容
export JAVA_HOME=/usr/local/jdk1.8.0_161 (這裡是JDK所在目錄)
export CLASSPATH=.:$JAVA_HOME/jre/lib/rt.jar:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
export PATH=$PATH:$JAVA_HOME/bin
# 儲存完成後重新載入 /etc/profile 檔案
source /etc/profile
# 測試是否配置正確
[root@localhost local]# java -version
java version "1.8.0_161"
Java(TM) SE Runtime Environment (build 1.8.0_161-b12)
Java HotSpot(TM) 64-Bit Server VM (build 25.161-b12, mixed mode)
複製程式碼
  1. 下載 Tomcat
# 下載 Tomcat 9
wget http://mirrors.hust.edu.cn/apache/tomcat/tomcat-9/v9.0.5/bin/apache-tomcat-9.0.5.tar.gz
# 解壓
tar -zxvf apache-tomcat-9.0.5.tar.gz
# 為接下來的步驟做準備
# 重新命名為tomcat-home
mv apache-tomcat-9.0.5 tomcat-home
# 複製第二份,重新命名為tomcat-8080
cp -R tomcat-home tomcat-8080
# 複製第三份,重新命名為tomcat-9090
cp -R tomcat-home tomcat-9090
複製程式碼
  1. 分離目錄

    首先介紹兩個 tomcat 中比較重要的概念(通常也是兩個系統變數)CATALINA_HOMECATALINA_BASE

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

    通過設定這兩個變數,就可以將tomcat的安裝目錄和工作目錄分離,從而實現tomcat多例項的部署。 下面就是 Tomcat 的基本目錄結構,以及對應的作用。

    目錄 簡介
    bin 存放指令碼檔案,例如比較常用的啟動和關閉指令碼 startup.sh、shutdown.sh 等
    conf 存放配置檔案,最重要的是 server.xml,它是 tomcat 的主要配置檔案
    lib Tomcat 執行需要的依賴包
    log 存放日誌檔案
    temp 存放執行時產生的臨時檔案
    webapps web 應用的預設目錄
    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 作為 CATALINA_HOME,即只需要保留 bin 和 lib 兩個資料夾
    tomcat-8080 作為 CATALINA_BASE,需要保留除了 bin 和 lib 之外的其他資料夾,使用 8080 埠
    tomcat-9090 同 tomcat-8080,使用 9090 埠

    基於 CATALINA_HOME 和 CATALINA_BASE 分離目錄

    # 根據上面表格整理完目錄之後,目錄結構如下:
    [root@localhost tomcat-home]# ls
    bin  lib  LICENSE  NOTICE  RELEASE-NOTES  RUNNING.txt
    [root@localhost tomcat-8080]# ls
    conf  LICENSE  logs  NOTICE  RELEASE-NOTES  RUNNING.txt  temp  webapps  work
    [root@localhost tomcat-9090]# ls
    conf  LICENSE  logs  NOTICE  RELEASE-NOTES  RUNNING.txt  temp  webapps  work
    複製程式碼
  2. 修改 Tomcat 配置檔案

    這一步主要是修改 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 的配置,修改後的 /usr/local/tomcat-9090/conf/server.xml 內容如下:
    ...
    <Server port="9005" shutdown="SHUTDOWN">
    ...
    <Connector port="9090" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="8443" />
    ...
    複製程式碼
  3. 編寫指令碼

    前面的準備工作做完之後就可以啟動 tomcat 了,但是現在只有 tomcat-home/bin 目錄下有 startup.sh 和 shutdown.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
    
    複製程式碼
  • 停止指令碼 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
    
    複製程式碼

    將這兩個指令碼檔案放在 tomcat-8080 和 tomcat-9090 的根目錄下即可

    [root@localhost tomcat-8080]# ls
    conf     logs    RELEASE-NOTES  start.sh  temp     work
    LICENSE  NOTICE  RUNNING.txt    stop.sh   webapps
    
    # 啟動 8080 埠的 tomcat
    [root@localhost tomcat-8080]# ./start.sh 
    Using CATALINA_BASE:   /usr/local/tomcat-8080
    Using CATALINA_HOME:   /usr/local/tomcat-home
    Using CATALINA_TMPDIR: /usr/local/tomcat-8080/temp
    Using JRE_HOME:        /usr/local/jdk1.8.0_161
    Using CLASSPATH:       /usr/local/tomcat-home/bin/bootstrap.jar:/usr/local/tomcat-home/bin/tomcat-juli.jar
    Tomcat started.
    # 停止
    [root@localhost tomcat-8080]# ./stop.sh 
    Using CATALINA_BASE:   /usr/local/tomcat-8080
    Using CATALINA_HOME:   /usr/local/tomcat-home
    Using CATALINA_TMPDIR: /usr/local/tomcat-8080/temp
    Using JRE_HOME:        /usr/local/jdk1.8.0_161
    Using CLASSPATH:       /usr/local/tomcat-home/bin/bootstrap.jar:/usr/local/tomcat-home/bin/tomcat-juli.jar
    
    複製程式碼
  1. 測試兩個 Tomcat 是否同時正常執行

    為了方便測試,在 /usr/local/tomcat-8080/webapps/ROOT 和 /usr/local/tomcat-9090/webapps/ROOT 目錄下分別新建一個 index.html 檔案,內容分別為 "tomcat-8080" 和 "tomcat-9090" 便於我們區分。完成之後使用 start.sh 啟動兩個例項,這裡我們同樣使用 curl 訪問來測試。

    # 訪問 9090 埠,獲取到 9090 的資料
    [root@localhost tomcat-9090]# curl localhost:9090
    <h1> tomcat-9090 </h1>
    # 訪問 8080 埠,獲取到 8080 的資料
    [root@localhost tomcat-8080]# curl localhost:8080
    <h1> tomcat-8080 </h1>
    複製程式碼

Nginx 與 Tomcat 結合

Ngnix 和 Tomcat 結合實現負載均衡的需求大概是這樣的:使用者訪問伺服器的 8888 埠,Ngnix 接收到請求之後轉發至 8080 埠或者 9090 埠由 Tomcat 處理。兩個 Tomcat 部署了同一個應用,這樣就可以實現負載均衡,可以由兩個 Tomcat 同時處理使用者請求。這裡我們以 localhost 為例,開始配置 Ngnix

這裡使用 localhost 作為示例,正式使用時在配置檔案中使用域名替換 localhost 即可

# 進入 ngnix 配置檔案的目錄
# 預設配置檔案是 ngnix.conf
/usr/local/nginx/conf
# 這裡我們新建一個 localhost.conf 單獨配置,內容如下:
upstream localhost {
        server 127.0.0.1:8080;
        server 127.0.0.1:9090;
}
server
        {
                listen       8888;
                server_name localhost;
                index index.html index.htm index.jsp index.php;

                location / {
                        proxy_pass http://localhost;
                        proxy_set_header X-Real-IP $remote_addr;
                        add_header X-Slave $upstream_addr;
                }

        }

# 接著將在 nginx.conf 中引入 localhost.conf
...
http {
    ...
    # 引入 localhost.conf;
    include /usr/local/nginx/conf/localhost.conf;
    ...
}
...

# 完成配置檔案修改之後可以通過 ./nginx -t 命令測試配置檔案是否正確
cd /usr/local/nginx/sbin/
./nginx -t
# 出現下面提示表示配置正確,如果有誤的話檢查配置檔案
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

# 過載 ngnix 配置檔案
./nginx -s reload
複製程式碼

至此,Nginx + Tomcat 的負責均衡伺服器已經搭建完成,現在訪問 localhost:8888 就可以看到兩個 Tomcat 都能處理來自 8888 埠的請求了

[root@localhost sbin]# curl localhost:8888
<h1> tomcat-8080 </h1>
[root@localhost sbin]# curl localhost:8888
<h1> tomcat-9090 </h1>
複製程式碼

負載均衡策略

上面我們使用的是 Nginx 預設的負載均衡策略,我們也可以根據自己需求配置其他的策略,Nginx 提供的策略主要有以下幾種:

  1. 輪詢(預設)

    每個請求按時間順序逐一分配到不同的後端伺服器,如果後端伺服器掛掉,能自動忽略該伺服器。

    upstream localhost {
        server 127.0.0.1:8080;
        server 127.0.0.1:9090;
    }
    複製程式碼
  2. 權重

    根據配置的權重去分配給不同的伺服器處理,適用於伺服器效能有差距的情況,可以個高效能的伺服器分配高權重

    upstream localhost {
        server 127.0.0.1:8080 weight=1;
        server 127.0.0.1:9090 weight=3;
    }
    複製程式碼
  3. IP 繫結 ip_hash

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

    upstream localhost {
        ip_hash; 
        server 127.0.0.1:8080;
        server 127.0.0.1:9090;
    }
    複製程式碼
  4. 最少連線

    將請求分配給當前連線數最少的伺服器

    upstream localhost {
        least_conn; 
        server 127.0.0.1:8080;
        server 127.0.0.1:9090;
    }
    複製程式碼

總結

以上,在 CentOS 上使用 Nginx + Tomcat 搭建負載均衡伺服器已經完成,搭建過程中主要是理解如何利用 CATALINA_HOME 和 CATALINA_BASE 實現 Tomcat 的多例項部署,在完成 Tomcat 多例項部署的基礎上結合 Nginx 實現負載均衡就很簡單了。

相關文章