Linux環境下Nginx及負載均衡

Nginx 簡介

Nginx 是一個高性能的 HTTP 和反向代理 Web 服務器,同時也提供了 IMAP/POP3/SMTP 服務。

前向代理作爲客戶端的代理,服務端只知道代理的 IP 地址而不知道客戶端的 IP 地址。

1557749097576

Nginx 安裝

推薦使用 LNMP 一鍵安裝包,Ubuntu/CentOS 等各平臺都有提供,省去自己配置的過程。

如果需要單獨安裝 Nginx,可以去找各平臺的安裝包名稱。以 Ubuntu Desktop 19.04 爲例,單獨安裝 Nginx 的命令如下:

sudo apt install nginx

1557750229828

Nginx 安裝後默認啓動,打開瀏覽器輸入 http://127.0.0.1 檢查是否安裝成功。

1557750269605

練習 1

使用 tail -f /path/to/nginx/log/access.log 實時監控文件變化,再分別本地訪問 127.0.01 和遠程訪問服務器 IP 地址,比較兩次訪問的日誌有什麼不同?

Tips: Ubuntu Server 版默認沒有桌面,通過 SSH 連接到服務器

  1. 打開新終端,通過 SSH 連接到服務器,再使用 curl 127.0.0.1 命令返回頁面源文件
  2. 打開客戶端瀏覽器,輸入服務器 IP 地址
  3. 比較上面兩步對應的操作日誌有什麼區別

剛纔在 Ubuntu 默認的火狐瀏覽器打開 127.0.0.1 時的訪問日誌如圖。

1557750357418

接下來換一臺電腦訪問 192.168.23.129。

1557750398919

1557750411791

首先可以看到,UA 是不一樣的,這是因爲我用了不同的瀏覽器,當然,訪問時間等也是不一樣的。

最關鍵的一點,第一次訪問的 IP 是 127.0.0.1,是環回地址,而後一次訪問的 IP 是 192.168.23.1,這個是我 Windows 10 的 IP 地址。

最後看一點實戰的內容——我的博客的訪問日誌:

1557750709656

1557750722075

從中可以看到類似的日誌記錄,不僅記錄了訪問者的 IP、UA,還記錄了訪問資源 URL 以及一些附加的信息。

同樣的,還有錯誤日誌,例如看一下 gitlab.error.log

1557750810498

有了這些日誌,管理員就方便排查問題了。

Nginx 默認配置

配置文件:/etc/nginx/nginx.conf(如果是 LNMP 安裝的,則可能在 /usr/local/nginx/conf/nginx.conf)。

可以用 less 查看配置文件,配置文件默認的環境是全局環境,即一個 main{},後面會定義用戶、工作進程等,以及 HTTP 服務、郵件服務。

1557817139159

下面主要講一下 HTTP 配置文件。

1557817159052

首先在 HTTP{} 會有一些全局的配置,包括訪問日誌、連接超時等信息,隨後會給出一個或多個 server 表示多個虛擬主機。

來看一下實戰的配置文件。

1557817278775

1557817334696

用戶和用戶組都是 www,配置了錯誤日誌的訪問路徑,工作模式是 epoll、IO 多路複用,單個進程的最大連接數是 51200。

1557817394587

配置了 fastcgi 相關信息。

Nginx 作爲 HTTP 服務器的配置

Nginx 默認的靜態資源文件夾爲 /var/www/html(不同的安裝包可能有不同的默認路徑,例如可能爲 /usr/local/nginx/www/html/default 或者其他目錄,也可以自己指定)。

在默認目錄下,新建一個叫做 jxtxzzw.html 的文件,隨便寫一點東西。

1557817758381

1557817709063

然後在 nginx.conf 的 HTTP 結點中新增一個虛擬服務器,並 sudo nginx -s reload 重新加載。

1557817875799

如圖,在 80 端口監聽,當用戶訪問的服務器是 jxtxzzwtest.com 的時候,就定位到 /var/www/html/ 下,並當用戶沒有指定訪問的路徑的時候,默認訪問 jxtxzzw.html

爲了模擬域名解析的過程,修改 /etc/hosts 文件,增加 jxtxzzwtest.com 的 IP 爲 127.0.0.1

1557818114250

修改之後打開瀏覽器訪問 jxtxzzwtest.com,可以看到剛纔的頁面。

1557818165684

如何不購買新的二級域名和服務器,利用該服務器和已有的域名再做一個個人主頁呢?

這就可以添加一個新的虛擬服務器。

重複上面的步驟,只是注意添加虛擬服務器的時候取一個新的 server_name,例如 new.jxtxzzwtest.com,至於 location 寫什麼,就看個人主頁放在了哪個文件夾下面了。這些都可以根據自己需要修改。

server {
    listen 80;
    server_name new.jxtxzzwtest.com;
    location / {
        index a_new_page.html;
        root /home/jxtxzzw/web/;
    }
}

隨後,在 hosts 模擬 DNS 解析,添加 127.0.0.1 new.jxtxzzwtest.com 之後就可以在瀏覽器訪問 new.jxtxzzwtest.com 來看到個人主頁了。

練習 2

  1. 在配置文件 nginx.conf 的 http 節點內新增一個虛擬服務器,新建 /var/www/EXAMPLE.com 文件夾,該文件夾下新建 index.html 文件寫入文字,重加載配置 sudo nginx -s reload (注:將本頁中的 EXAMPLE 替換成自己的名字拼音)
  2. 瀏覽器輸入 IP 地址,檢查是否生成 /var/log/nginx/EXAMPLE.access.log 文件,同時檢查 /var/log/nginx/access.log 文件是否有變化
  3. 修改自己客戶端電腦上的 hosts 文件,添加兩行解析到服務器 IP 地址
  4. 瀏覽器輸入 www.EXAMPLE.com,檢查是否生成 /var/log/nginx/EXAMPLE.access.log,同時監測 /var/log/nginx/access.log 和 /var/log/nginx/EXAMPLE.access.log 文件的變化
server {
	listen 80;
	server_name www.zzw.com;
	access_log /var/log/nginx/zzw.access.log;
	location / {
		index index.html;
		root /var/www/html/zzw.com/;
	}
}

1557818970811

輸入 IP 地址,不論是本機訪問 127.0.0.1 還是另一臺電腦訪問 192.168.23.129,發現都只訪問了 Nginx 默認的安裝成功頁面,沒有進入 zzw.com

顯然的,只有 access.log 會有變化,記錄了本次訪問信息。

1557819148817

而在添加了 hosts 以後,訪問 www.zzw.com 就會看到剛纔輸入的信息。

1557819224946

需要注意的是,在配置文件中只定義了 www.zzw.com,沒有定義 zzw.com,所以,在訪問 zzw.com 的時候還是會跳轉到 Nginx 安裝成功的那個頁面。

解決這個辦法可以在 server_name 後面增加一個別名。

server_name www.zzw.com zzw.com;

看到 zzw.access.log 和 access.log 都有了新的記錄。

來看一些實戰的內容。

1557819404635

我的博客,監聽了 80 端口,同時處理 www.jxtxzzw.comjxtxzzw.com 兩個服務器名字,並對 80 端口的請求全部轉發到 443 端口。

443 端口配置了一些關於 SSL 相關的信息,並且導入了 PHP 相關的配置。

1557819497443

同時,還有一個 gitlab.jxtxzzw.com 的虛擬主機,這個配置文件將在下面詳述。

負載均衡簡介

1557900464912

1557900479572

1557900487750

負載均衡轉發算法:

  • 輪詢(Round Robin):爲第一個請求選擇列表中的第一個服務器,然後按順序向下移動列表直到結尾,然後循環
  • 最小連接(Least Connection):優先選擇連接數最少的服務器,在普遍會話較長的情況下推薦使用
  • 散列(Hash):根據請求源的 IP 的散列來選擇要轉發的服務器,這種方式可以一定程度上保證特定用戶能鏈接到相同的服務器

負載均衡算法:

  • round:每個請求按時間順序逐一分配到不同的後端服務器,如果後端服務器宕機,能自動刪除
  • weight:指定輪詢機率,weight 和訪問比率成正比,用於後端服務器性能不均的情況
  • fiar(第三方):按後端服務器的響應時間來分配請求,響應時間短的優先分配
  • ip_hash:每個請求按訪問 IP 的散列結果分配,每個訪客固定訪問一個後端服務器,可以解決 session 的問題
  • url_hash(第三方):每個請求按 URL 的散列結果分配,不同訪客訪問相同的服務器

1557900812070

預備 Web 服務器環境:

  1. 配置兩臺 Apache(httpd) 作爲 Web 服務器,例如可以使用 XAMPP
  2. XAMPP 的訪問日誌在 /opt/lampp/logs/access.log
  3. 一臺 Ubuntu Desktop 的虛擬機,192.168.23.129,作爲 Nginx 服務器
  4. 一臺 Ubuntu Desktop 的虛擬機,192.168.23.128,作爲第 1 臺 XAMPP 服務器
  5. 一臺 Ubuntu Server 的虛擬機,192.168.23.130,作爲第 2 臺 XAMPP 服務器
  6. 一臺 Windows 的物理機,192.168.23.1,用來訪問

1557904366933

1557904412893

1557904436313

在 nginx.conf 的 http 節點下添加以下代碼後重新加載配置

upstream first {
    server 192.168.23.128;
    server 192.168.23.130;
}

server {
    listen 80;
    server_name load.jxtxzzwtest.com;
    location / {
        proxy_pass http://first;
    }
}

修改電腦的 host 文件,添加一個域名解析

192.168.23.129 load.jxtxzzwtest.com

1557904573224

瀏覽器訪問 load.jxtxzzwtest.com,發現打開了 XAMPP 的一個界面,說明代理成功了。

但是到底訪問的是哪一個 XAMPP 呢?可以看一下日誌。

在此之前,刷新幾次,看看日誌會不會訪問了不同的頁面。

日誌的觀察結果,可以看到 128 的那臺服務器上收到了若干次來自 129 的轉發請求,而 130 的那臺服務器上也收到了若干請求,但是觀察時間可以看到,兩臺服務器上接受的請求是先後交替的,這意味着符合輪詢算法的期望結果。

更加直觀的方法,是可以修改其中一個 Apache 服務器的主頁顯示。

1557905255583

簡單粗暴的方法,刪掉了 128 那臺服務器的 index.html。

然後刷新頁面的效果就是交替出現 XAMPP 的 dashboard 和 Directory Listing。

1557905322496

刷新以後變成下面這個頁面,兩個頁面在每次刷新後交替顯示。

1557905359160

如果沒有交替顯示,有可能是瀏覽器做了緩存,強制刷新一下就好了。

練習 3

  1. 在 nginx.conf 的 http 節點下新增 upstream second 方案,將 server 節點下的 proxy_pass 設爲 second 後重加載配置,其中 IP 地址要換成自己服務器的地址,瀏覽器訪問域名,監測 Nginx 服務器的 /var/log/nginx/access.log 和兩臺 Web 服務器的 /opt/lampp/logs/access.log 發現有什麼規律

    upstream second {
        server 192.168.1.102:80;
        server 192.168.1.103 weight=3;
    }
    
  2. 新增 upstream third 方案,重複上述實驗

    upstream third {
        ip_hash;
        server 192.168.1.102;
        server 192.168.1.103;
    }
    

1557905657267

1557905818420

訪問日誌可以看出,交替比例變爲 3:1。

需要特別說明的是,瀏覽器可能存在緩存,所以一定要去看日誌。

換成 hash 以後,我只能刷出 Index of /dashboard 這個頁面,不論刷新多少次,而查看訪問日誌也確實發現我被轉發到了 130 這個服務器上。

換一臺設備,可能(如果正好 hash 計算結果不同)就會被轉發到 128 的服務器上。也可能還是訪問的 130 的服務器。

再來看一些關於 Nginx 代理的實戰的例子。

第一個例子是 HTTPS 反向代理到 Docker,具體的配置過程可以看我的另一篇文章《Nginx代理HTTPS到Docker指定端口》(https://www.jxtxzzw.com/archives/4241),這裏只簡要的給出與反向代理、負載均衡相關的代碼。

1557906259949

1557906274170

第二個例子是 GitLab。

如果不想用 GitLab 自帶的 Nginx 服務,而想要把 GitLab 作爲一個虛擬主機統一在已有的 LNMP 服務中一起管理,可以用到反向代理。

由於 GitLab 默認的是在 socket 中通信,所以有點不太一樣。

1557906387237

1557906405665

1557906423386

這兩張截圖省略了 GitLab 中與 SSL 配置相關的代碼。

練習 4

  1. 利用 XAMPP,搭建一個能訪問數據庫的動態網站,並通過負載均衡服務器訪問
  2. 比較 Nginx 服務器和 Apache 服務器的異同

第一個練習,比較簡單,基本上只要復現本文內容即可,唯一的區別在於需要把本文中簡陋的 HTML 代碼複雜化,加上與數據庫通信的部分,例如,訪問數據庫並列出所有學生的姓名……

由於上一次練習《MySQL備份與主備配置》已經配置了雙主結構,所以,在一個 PHP 頁面中加入增刪改查的功能,並把頁面複製到另一臺服務器上就可以了,訪問會通過負載均衡,數據庫的訪問會通過雙主備份,保證了數據的一致。

代碼就不貼了。

另外,歡迎訪問我的個人博客呀,https://www.jxtxzzw.com/

第二個練習,簡單說一下。

Nginx 相對於 Apache 的優勢:

  • Apache 是同步多進程模型,一個連接對應一個進程,Nginx 是異步的,多個連接(萬級別)可以對應一個進程
  • Nginx 的抗併發能力強很多,對資源需求更少
  • Nginx 支持反向代理
  • Nginx 支持 7 層負載均衡

Apache 相對 Nginx 的優點:

  • Rewrite,比 Nginx 的 Rewrite 強大
  • 模塊超多,基本想到的都可以找到

一般來說,需要性能的 Web 服務,用 Nginx,如果不需要性能只求穩定,那就 Apache 吧。總之,就是看自己需求的。

但是從個人使用經歷來看,我會推薦 Nginx 作爲 Web 服務器的首選。如果你是新手,什麼都沒接觸過,不妨先試試 Nginx?

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章