8 Nginx 實現服務器端集群搭建


8 Nginx 實現服務器端集群搭建

8.1 Nginx與Tomcat部署

前面課程已經將Nginx的大部分內容進行了講解,我們都知道了Nginx在高並發場景和處理靜態資源是非常高性能的,但是在實際項目中除了靜態資源還有就是后台業務代碼模塊,一般后台業務都會被部署在Tomcat,weblogic或者是websphere等web服務器上。那么如何使用Nginx接收用戶的請求並把請求轉發到后台web服務器?

1604498725652

步驟分析:

  • 准備Tomcat環境,並在Tomcat上部署一個web項目

  • 准備Nginx環境,使用Nginx接收請求,並把請求分發到Tomat上

8.1.1 環境准備(Tomcat)

測試代碼下載地址:

wget https://gitee.com/wei_cunqi/images/raw/master/nginx/8/demo.war

(1)在Centos上准備一個Tomcat

# Tomcat官網地址:https://tomcat.apache.org/
# 下載tomcat,本次課程使用的是apache-tomcat-8.5.73.tar.gz
# 將tomcat進行解壓縮
mkdir /usr/local/tomcat/
tar -zxf apache-tomcat-8.5.73.tar.gz -C /usr/local/tomcat/

(2)准備一個web項目,將其打包為war

# 將資料中的demo.war上傳到tomcat8目錄下的webapps包下
# 將tomcat進行啟動,進入tomcat8的bin目錄下
./startup.sh

(3)啟動tomcat進行訪問測試

瀏覽器訪問:

http://192.168.5.4:8080/demo/index.html

image-20211206094357930

獲取動態資源的鏈接地址:

http://192.168.5.4:8080/demo/getAddress

image-20211206094407010

8.1.2 環境准備(Nginx)

(1)使用Nginx的反向代理,將請求轉給Tomcat進行處理。

upstream webservice {
server 192.168.5.4:8080;
}
server{
   listen 80;
   server_name localhost;
   location /demo/ {
  proxy_pass http://webservice;
  }
}

(2)啟動訪問測試

http://192.168.5.3/demo/

image-20211206094738135

學習到這,可能大家會有一個困惑,明明直接通過tomcat就能訪問,為什么還需要多加一個nginx,這樣不是反而是系統的復雜度變高了么? 那接下來我們從兩個方便給大家分析下這個問題,

  • 第一個使用Nginx實現動靜分離

  • 第二個使用Nginx搭建Tomcat的集群

8.2 Nginx實現動靜分離

(1)什么是動靜分離?

  • 動:后台應用程序的業務處理

  • 靜:網站的靜態資源(html,javaScript,css,images等文件)

  • 分離:將兩者進行分開部署訪問,提供用戶進行訪問。舉例說明就是以后所有和靜態資源相關的內容都交給Nginx來部署訪問,非靜態內容則交個類似於Tomcat的服務器來部署訪問。

(2)為什么要動靜分離?

前面我們介紹過Nginx在處理靜態資源的時候,效率是非常高的,而且Nginx的並發訪問量也是名列前茅,而Tomcat則相對比較弱一些,所以把靜態資源交個Nginx后,可以減輕Tomcat服務器的訪問壓力並提高靜態資源的訪問速度。

動靜分離以后,降低了動態資源和靜態資源的耦合度。如動態資源宕機了也不影響靜態資源的展示。

(3)如何實現動靜分離?

實現動靜分離的方式很多,比如靜態資源可以部署到CDN、Nginx等服務器上,動態資源可以部署到Tomcat,weblogic或者websphere上。本次課程只要使用Nginx+Tomcat來實現動靜分離。

8.2.1 需求分析

image-20211206094931579

 

8.2.2 動靜分離實現步驟

(1)關閉Tomcat服務並刪除之前殘留

./bin/shutdown.sh

rm -rf webapps/demo*

(2)導入新的war包

# 下載地址:
wget https://gitee.com/wei_cunqi/images/raw/master/nginx/8/demo_simple.war
cp /root/demo_simple.war webapps/
./bin/startup.sh

(3)訪問測試

# 訪問靜態資源
http://192.168.5.4:8080/demo_simple/index.html

image-20211206102027447

# 訪問動態資源
http://192.168.5.4:8080/demo_simple/getAddress

image-20211206102019550

(4)在Nginx所在服務器創建如下目錄,並將對應的靜態資源放入指定的位置

# 下載地址:
# Tomcat 項目代碼
wget https://gitee.com/wei_cunqi/images/raw/master/nginx/8/demo_simple.war
# Nginx 項目代碼
wget https://gitee.com/wei_cunqi/images/raw/master/nginx/8/web.tar.gz

1604493947499

其中index.html頁面的內容如下:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="js/jquery.min.js"></script>
<script>
$(function(){
$.get('http://192.168.5.3/demo_simple/getAddress',function(data){
$("#msg").html(data);
});
});
</script>
</head>
<body>
<img src="images/logo.png"/>
<h1>Nginx如何將請求轉發到后端服務器</h1>
<h3 id="msg"></h3>
<img src="images/mv.png"/>
</body>
</html>

(5)配置Nginx的靜態資源與動態資源的訪問

upstream webservice{
server 192.168.5.4:8080;
}
server {
listen 80;
server_name localhost;

#動態資源
location /demo {
proxy_pass http://webservice;
}
#靜態資源
location ~/.*\.(png|jpg|gif|js){
root html/web;
gzip on;
}

location / {
root html/web;
index index.html index.htm;
}
}

5.啟動測試

http://192.168.5.3/index.html

image-20211206103953265

假如某個時間點,由於某個原因導致Tomcat后的服務器宕機了,我們再次訪問Nginx,會得到如下效果,用戶還是能看到頁面,只是缺失了訪問次數的統計,這就是前后端耦合度降低的效果,並且整個請求只和后的服務器交互了一次,js和images都直接從Nginx返回,提供了效率,降低了后的服務器的壓力。

image-20211206104113958

8.3 Nginx實現Tomcat集群搭建

在使用Nginx和Tomcat部署項目的時候,我們使用的是一台Nginx服務器和一台Tomcat服務器,效果圖如下:

1604494256017

那么問題來了,如果Tomcat的真的宕機了,整個系統就會不完整,所以如何解決上述問題,一台服務器容易宕機,那就多搭建幾台Tomcat服務器,這樣的話就提升了后的服務器的可用性。

這也就是我們常說的集群,搭建Tomcat的集群需要用到了Nginx的反向代理和賦值均衡的知識,具體如何來實現?我們先來分析下原理

1604494269848

 

 

環境准備:

(1)准備3台tomcat,使用端口進行區分[實際環境應該是三台服務器],修改server.ml,將端口修改分別修改為8080,8180,8280

image-20211206105232451

image-20211206105256059

(2)啟動tomcat並訪問測試,

http://192.168.5.4:8080/demo_simple/getAddress

image-20211206105304524

http://192.168.5.4:8180/demo_simple/getAddress

image-20211206105313136

http://192.168.5.4:8280/demo_simple/getAddress

image-20211206105320436

(3)在Nginx對應的配置文件中添加如下內容:

upstream webservice{
server 192.168.5.4:8080;
server 192.168.5.4:8180;
server 192.168.5.4:8280;
}

image-20211206105546537

image-20211206105556186

好了,完成了上述環境的部署,我們已經解決了Tomcat的高可用性,一台服務器宕機,還有其他兩條對外提供服務,同時也可以實現后台服務器的不間斷更新。但是新問題出現了,上述環境中,如果是Nginx宕機了呢,那么整套系統都將服務對外提供服務了,這個如何解決?

8.4 Nginx高可用解決方案

針對於上面提到的問題,我們來分析下要想解決上述問題,需要面臨哪些問題?

1604495169905

需要兩台以上的Nginx服務器對外提供服務,這樣的話就可以解決其中一台宕機了,另外一台還能對外提供服務,但是如果是兩台Nginx服務器的話,會有兩個IP地址,用戶該訪問哪台服務器,用戶怎么知道哪台是好的,哪台是宕機了的?

8.4.1 Keepalived 介紹

使用Keepalived來解決,Keepalived 軟件由 C 編寫的,最初是專為 LVS 負載均衡軟件設計的,Keepalived 軟件主要是通過 VRRP 協議實現高可用功能。

8.4.2 VRRP 介紹

1604495824757

VRRP(Virtual Route Redundancy Protocol)協議,翻譯過來為虛擬路由冗余協議。VRRP協議將兩台或多台路由器設備虛擬成一個設備,對外提供虛擬路由器IP,而在路由器組內部,如果實際擁有這個對外IP的路由器如果工作正常的話就是MASTER,MASTER實現針對虛擬路由器IP的各種網絡功能。其他設備不擁有該虛擬IP,狀態為BACKUP,處了接收MASTER的VRRP狀態通告信息以外,不執行對外的網絡功能。當主機失效時,BACKUP將接管原先MASTER的網絡功能。

從上面的介紹信息獲取到的內容就是VRRP是一種協議,那這個協議是用來干什么的?

1.選擇協議

VRRP可以把一個虛擬路由器的責任動態分配到局域網上的 VRRP 路由器中的一台。其中的虛擬路由即Virtual路由是由VRRP路由群組創建的一個不真實存在的路由,這個虛擬路由也是有對應的IP地址。而且VRRP路由1和VRRP路由2之間會有競爭選擇,通過選擇會產生一個Master路由和一個Backup路由。

2.路由容錯協議

Master路由和Backup路由之間會有一個心跳檢測,Master會定時告知Backup自己的狀態,如果在指定的時間內,Backup沒有接收到這個通知內容,Backup就會替代Master成為新的Master。Master路由有一個特權就是虛擬路由和后端服務器都是通過Master進行數據傳遞交互的,而備份節點則會直接丟棄這些請求和數據,不做處理,只是去監聽Master的狀態

 

用了Keepalived后,解決方案如下:

1604495442179

8.4.3 環境搭建

(1)環境准備

VIP IP 主機名 主/從
  192.168.5.3 keepalived1 Master
192.168.5.10      
  192.168.5.4 keepalived2 Backup

(2)keepalived的安裝

# 步驟1:從官方網站下載keepalived,官網地址https://keepalived.org/
# 步驟2:將下載的資源上傳到服務器
keepalived-2.2.4.tar.gz
# 步驟3:創建keepalived目錄,方便管理資源
mkdir /opt/keepalived
# 步驟4:將壓縮文件進行解壓縮,解壓縮到指定的目錄
tar -zxvf keepalived-2.2.4.tar.gz -C /opt/keepalived
# 步驟5:對keepalived進行配置,編譯和安裝
cd /opt/keepalived/keepalived-2.2.4/
./configure --sysconf=/etc --prefix=/usr/local && make && make install

安裝完成后,有兩個文件需要我們認識下,一個是 /etc/keepalived/keepalived.conf(keepalived的系統配置文件,我們主要操作的就是該文件),一個是/usr/local/sbin目錄下的keepalived,是系統配置腳本,用來啟動和關閉keepalived

(3)准備nginx環境

兩個環境需要一致

image-20211206115854804

image-20211206115844751

 

8.4.4 Keepalived配置文件介紹

打開keepalived.conf配置文件

這里面會分三部,第一部分是global全局配置、第二部分是vrrp相關配置、第三部分是LVS相關配置。

global全局部分:
global_defs {
#通知郵件,當keepalived發送切換時需要發email給具體的郵箱地址
notification_email {
tom@itcast.cn
jerry@itcast.cn
}
#設置發件人的郵箱信息
notification_email_from zhaomin@itcast.cn
#指定smpt服務地址
smtp_server 192.168.200.1
#指定smpt服務連接超時時間
smtp_connect_timeout 30
#運行keepalived服務器的一個標識,可以用作發送郵件的主題信息
router_id LVS_DEVEL

#默認是不跳過檢查。檢查收到的VRRP通告中的所有地址可能會比較耗時,設置此命令的意思是,如果通告與接收的上一個通告來自相同的master路由器,則不執行檢查(跳過檢查)
vrrp_skip_check_adv_addr
#嚴格遵守VRRP協議。
vrrp_strict
#在一個接口發送的兩個免費ARP之間的延遲。可以精確到毫秒級。默認是0
vrrp_garp_interval 0
#在一個網卡上每組na消息之間的延遲時間,默認為0
vrrp_gna_interval 0
}
VRRP部分,該部分可以包含以下四個子模塊
1. vrrp_script
2. vrrp_sync_group
3. garp_group
4. vrrp_instance
我們會用到第一個和第四個,
#設置keepalived實例的相關信息,VI_1為VRRP實例名稱
vrrp_instance VI_1 {
state MASTER #有兩個值可選MASTER主 BACKUP備
interface ens33 #vrrp實例綁定的接口,用於發送VRRP包[當前服務器使用的網卡名稱]
virtual_router_id 51#指定VRRP實例ID,范圍是0-255
priority 100 #指定優先級,優先級高的將成為MASTER
advert_int 1 #指定發送VRRP通告的間隔,單位是秒
authentication { #vrrp之間通信的認證信息
auth_type PASS #指定認證方式。PASS簡單密碼認證(推薦)
auth_pass 1111 #指定認證使用的密碼,最多8位
}
virtual_ipaddress { #虛擬IP地址設置虛擬IP地址,供用戶訪問使用,可設置多個,一行一個
192.168.5.10
}
}

配置內容如下:

服務器1

global_defs {
notification_email {
tom@itcast.cn
jerry@itcast.cn
}
notification_email_from zhaomin@itcast.cn
smtp_server 192.168.200.1
smtp_connect_timeout 30
router_id keepalived1
vrrp_skip_check_adv_addr
vrrp_strict
vrrp_garp_interval 0
vrrp_gna_interval 0
}

vrrp_instance VI_1 {
state MASTER
interface ens33
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.5.10
}
}

服務器2

! Configuration File for keepalived

global_defs {
notification_email {
tom@itcast.cn
jerry@itcast.cn
}
notification_email_from zhaomin@itcast.cn
smtp_server 192.168.200.1
smtp_connect_timeout 30
router_id keepalived2
vrrp_skip_check_adv_addr
vrrp_strict
vrrp_garp_interval 0
vrrp_gna_interval 0
}

vrrp_instance VI_1 {
state BACKUP
interface ens33
virtual_router_id 51
priority 90
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.5.10
}
}

8.4.5 訪問測試

(1)啟動keepalived之前,咱們先使用命令 ip addr,查看192.168.5.3和192.168.5.4這兩台服務器的IP情況。

image-20211206131308401

image-20211206131319098

(2)分別啟動兩台服務器的keepalived

cd /usr/local/sbin
./keepalived

再次通過 ip addr查看ip

image-20211206131648154

image-20211206131700338

(3)當把192.168.5.3服務器上的keepalived關閉后,再次查看ip

image-20211206131801985

image-20211206131750577

通過上述的測試,我們會發現,虛擬IP(VIP)會在MASTER節點上,當MASTER節點上的keepalived出問題以后,因為BACKUP無法收到MASTER發出的VRRP狀態通過信息,就會直接升為MASTER。VIP也會"漂移"到新的MASTER。

上面測試和Nginx有什么關系?

我們把192.168.5.3服務器的keepalived再次啟動下,由於它的優先級高於服務器192.168.5.4的,所有它會再次成為MASTER,VIP也會"漂移"過去,然后我們再次通過瀏覽器訪問:

http://192.168.5.10

image-20211206131941711

如果把192.168.5.3服務器的keepalived關閉掉,再次訪問相同的地址

image-20211206132029697

效果實現了以后, 我們會發現要想讓vip進行切換,就必須要把服務器上的keepalived進行關閉,而什么時候關閉keepalived呢?應該是在keepalived所在服務器的nginx出現問題后,把keepalived關閉掉,就可以讓VIP執行另外一台服務器。

但是現在這所有的操作都是通過手動來完成的,我們如何能讓系統自動判斷當前服務器的nginx是否正確啟動,如果沒有,要能讓VIP自動進行"漂移",這個問題該如何解決?

8.4.6 keepalived之vrrp_script

keepalived只能做到對網絡故障和keepalived本身的監控,即當出現網絡故障或者keepalived本身出現問題時,進行切換。但是這些還不夠,我們還需要監控keepalived所在服務器上的其他業務

比如Nginx,如果Nginx出現異常了,僅僅keepalived保持正常,是無法完成系統的正常工作的,因此需要根據業務進程的運行狀態決定是否需要進行主備切換,這個時候,我們可以通過編寫腳本對業務進程進行檢測監控。

實現步驟:

  1. 在keepalived配置文件中添加對應的配置像

vrrp_script 腳本名稱
{
script "腳本位置"
interval 3 #執行時間間隔
weight -20 #動態調整vrrp_instance的優先級
}
  1. 編寫j監控腳本

cat <<EOF> /etc/keepalived/ck_nginx.sh
#!/bin/bash
num=`ps -C nginx --no-header | wc -l`
if [ $num -eq 0 ];then
/usr/local/nginx/sbin/nginx
sleep 2
if [ `ps -C nginx --no-header | wc -l` -eq 0 ]; then
killall keepalived
fi
fi
EOF

Linux ps命令用於顯示當前進程 (process) 的狀態。

-C(command) :指定命令的所有進程

--no-header 排除標題

  1. 為腳本文件設置權限

chmod 755 /etc/keepalived/ck_nginx.sh
  1. 將腳本添加到

vrrp_script ck_nginx {
script "/etc/keepalived/ck_nginx.sh" #執行腳本的位置
interval 2 #執行腳本的周期,秒為單位
weight -20 #權重的計算方式
}
vrrp_instance VI_1 {
state MASTER
interface ens33
virtual_router_id 10
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
192.168.5.10
}
track_script {
ck_nginx
}
}
  1. 如果效果沒有出來,可以使用 tail -f /var/log/messages查看日志信息,找對應的錯誤信息。

  2. 測試

問題思考:

通常如果master服務死掉后backup會變成master,但是當master服務又好了的時候 master此時會搶占VIP,這樣就會發生兩次切換對業務繁忙的網站來說是不好的。

所以我們要在配置文件加入 nopreempt 非搶占,但是這個參數只能用於state 為backup,故我們在用HA的時候最好master 和backup的state都設置成backup 讓其通過priority來競爭。

8.5 Nginx制作下載站點

(1)首先我們先要清楚什么是下載站點?

我們先來看一個網站http://nginx.org/download/這個我們剛開始學習Nginx的時候給大家看過這樣的網站,該網站主要就是用來提供用戶來下載相關資源的網站,就叫做下載網站。

image-20211206133052248(2)如何制作一個下載站點:

nginx使用的是模塊ngx_http_autoindex_module來實現的,該模塊處理以斜杠("/")結尾的請求,並生成目錄列表。

nginx編譯的時候會自動加載該模塊,但是該模塊默認是關閉的,我們需要使用下來指令來完成對應的配置

(3)autoindex:啟用或禁用目錄列表輸出

語法 autoindex on|off;
默認值 autoindex off;
位置 http、server、location

(4)autoindex_exact_size:對應HTLM格式,指定是否在目錄列表展示文件的詳細大小

  • 默認為on,顯示出文件的確切大小,單位是bytes。

  • 改為off后,顯示出文件的大概大小,單位是kB或者MB或者GB

語法 autoindex_exact_size on|off;
默認值 autoindex_exact_size on;
位置 http、server、location

(5)autoindex_format:設置目錄列表的格式

語法 autoindex_format html|xml|json|jsonp;
默認值 autoindex_format html;
位置 http、server、location

注意:該指令在1.7.9及以后版本中出現

(6)autoindex_localtime:對應HTML格式,是否在目錄列表上顯示時間。

  • 默認為off,顯示的文件時間為GMT時間。

  • 改為on后,顯示的文件時間為文件的服務器時間

語法 autoindex_localtime on | off;
默認值 autoindex_localtime off;
位置 http、server、location

配置方式如下:

location /download{
root /usr/local;
autoindex on;
autoindex_exact_size on;
autoindex_format html;
autoindex_localtime on;
}

image-20211206133539770

8.6 Nginx的用戶認證模塊

對應系統資源的訪問,我們往往需要限制誰能訪問,誰不能訪問。這塊就是我們通常所說的認證部分,認證需要做的就是根據用戶輸入的用戶名和密碼來判定用戶是否為合法用戶,如果是則放行訪問,如果不是則拒絕訪問。

Nginx對應用戶認證這塊是通過ngx_http_auth_basic_module模塊來實現的,它允許通過使用"HTTP基本身份驗證"協議驗證用戶名和密碼來限制對資源的訪問。默認情況下nginx是已經安裝了該模塊,如果不需要則使用--without-http_auth_basic_module。

該模塊的指令比較簡單,

(1)auth_basic:使用“ HTTP基本認證”協議啟用用戶名和密碼的驗證

語法 auth_basic string|off;
默認值 auth_basic off;
位置 http,server,location,limit_except

開啟后,服務端會返回401,指定的字符串會返回到客戶端,給用戶以提示信息,但是不同的瀏覽器對內容的展示不一致。

(2)auth_basic_user_file:指定用戶名和密碼所在文件

語法 auth_basic_user_file file;
默認值
位置 http,server,location,limit_except

指定文件路徑,該文件中的用戶名和密碼的設置,密碼需要進行加密。可以采用工具自動生成

實現步驟:

1)nginx.conf添加如下內容

location /download{
root /usr/local;
autoindex on;
autoindex_exact_size on;
autoindex_format html;
autoindex_localtime on;
auth_basic 'please input your auth';
auth_basic_user_file htpasswd;
}

image-20211206134144041

2)我們需要使用htpasswd工具生成

yum install -y httpd-tools
htpasswd -c /usr/local/nginx/conf/htpasswd username //創建一個新文件記錄用戶名和密碼
htpasswd -b /usr/local/ng inx/conf/htpasswd username password //在指定文件新增一個用戶名和密碼
htpasswd -D /usr/local/nginx/conf/htpasswd username //從指定文件刪除一個用戶信息
htpasswd -v /usr/local/nginx/conf/htpasswd username //驗證用戶名和密碼是否正確

image-20211206134349866

image-20211206134417991

上述方式雖然能實現用戶名和密碼的驗證,但是大家也看到了,所有的用戶名和密碼信息都記錄在文件里面,如果用戶量過大的話,這種方式就顯得有點麻煩了,這時候我們就得通過后台業務代碼來進行用戶權限的校驗了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM