LNMP 分散式叢集(一):Nginx+PHP平臺搭建與負載均衡配置

dfface發表於2020-03-18

前言

本篇文章是對Nginx學習過程的一個總結提升,所謂LNMP即Linux+Nginx+MySQL+PHP,而分散式是指把一項工作劃分成不同的業務到多個不同的伺服器,使得他們各自進行自己的處理,共同完成該項工作,而叢集就是將多臺伺服器集中起來以實現負載均衡和高可用性,分散式和叢集各有優缺點,將優點結合,就形成了分散式叢集。將一個工作分成多個業務分佈到叢集中處理。除了LNMP還可以部署LNAMP(加入Apache伺服器處理動態資源,Nginx處理靜態資源和反向代理),這裡就不多說了。

把我坑掉的是:起初我用了Nginx的1.16.1版本,PHP的5.6.27,結果他倆不能正常合作,於是Nginx退回到1.10.3。

LNMP分散式部署

由圖可知,我們建立了9臺伺服器各司其職,每臺伺服器都代表了一項服務。

編號 IP 伺服器
1 192.168.177.11 Nginx(www.itshop.test):負載均衡
2 192.168.177.12 Nginx(file.itshop.test):靜態檔案快取
3 192.168.177.13 Nginx+PHP(upload.itshop.test):檔案上傳
4 192.168.177.14 Nginx+PHP
5 192.168.177.15 Nginx+PHP
6 192.168.177.16 NFS:檔案儲存
7 192.168.177.17 MySQL(主)
8 192.168.177.18 MySQL(從)
9 192.168.177.19 Memcached:資料快取

部署

Linux 伺服器的部署

這一節的詳細資訊請看文章:在CentOS中通過原始碼編譯安裝Nginx

install centos minimal

需要先控制好每個虛擬機器的記憶體配額,防止物理機記憶體不足,若物理機有8G記憶體,推薦每臺虛擬機器分配512MB。

在安裝的時候開啟網路

建議安裝net-tools:yum -y install net-tools,也建議此時為系統換tuna的源

在完成了1號伺服器的Linux系統安裝之後克隆出其他4臺不需要安裝的Nginx伺服器,然後再部署Nginx再克隆其他4臺需要Nginx的伺服器,基本流程如圖:

虛擬機器克隆流程

每臺伺服器都要注意按照需求設定網路,主要就是網路的靜態配置。

我們編寫可以一個SHELL指令碼,也可以手動配置:

#! /bin/bash
ens33=/etc/sysconfig/network-scripts/ifcfg-ens33
sed -i 's/BOOTPROTO=.*/BOOTPROTO=\"static\"/g' $ens33
sed -i '$aIPADDR=192.168.177.1'$1'' $ens33
sed -i '$aNETMASK=255.255.255.0' $ens33
sed -i '$aGATEWAY=192.168.177.2' $ens33
sed -i '$aDNS1=192.168.177.2' $ens33
service network restart
複製程式碼

然後使用./network-settings.sh 1設定伺服器的網路,

sed 命令中,i表示直接編輯,s表示替換,$匹配最後的行尾,a表示追加,詳情請看:man.linuxde.net/sed,替換可以使用sed -i 's/IPADDR=.*/IPADDR=192.168.177.1'$1'/g' $ens33

下面就要進行正式的部署了,在這之前我們回顧一張圖,這是需要記住的架構:

架構(序號代表IP地址:192.168.177.1X)

Nginx 環境的部署

首先在1號伺服器中安裝Nginx(參考在CentOS中通過原始碼編譯安裝Nginx):

【友情提示,儘可能按照本文的軟體版本配置,如Nginx為1.10.3,PHP為5.6.27,否則會很要命,因為版本不匹配會出現很大問題,要麼都用最新版,要麼按照本文的配置來】

wget http://nginx.org/download/nginx-1.10.3.tar.gz
tar -zxvf nginx-1.10.3.tar.gz
yum -y install gcc pcre-devel openssl-devel
cd nginx-1.10.3
./configure --preifx=/usr/local/nginx --with-http_ssl_module --with-http_realip_module
make && make install
ln -s /usr/local/nginx/sbin/nginx /usr/local/sbin/nginx
vi /etc/init.d/nginx # 此時參考之前的文章寫一個啟動指令碼於:/etc/init.d/nginx
chmod +x /etc/init.d/nginx
chkconfig --add nginx
# 建立使用者www和站點目錄/data/www
useradd -s /sbin/nologin -M www
mkdir -p /data/www
cp /usr/local/nginx/html/* /data/www
chown -R www:www /data/www
vi /usr/local/nginx/conf/nginx.conf
# 配置使用者
user www
# 修改server塊
server {
    listen 80;
    server_name localhost;
    root /data/www;
    index index.html index.htm;
}
service nginx start
# 更新和配置防火牆
systemctl stop firewalld
systemctl disable firewalld
firewall-cmd --state 
yum -y install iptables-services
systemctl enable iptables
systemctl start iptables
iptables -I INPUT -p tcp --dport 80 -j ACCEPT
service iptables save
複製程式碼

useradd命令,-M:不要自動建立使用者的登入目錄;-s:指定使用者登入後所使用的shell; chown命令,引數有使用者:組:指定所有者和所屬工作組。當省略“:組”,僅改變檔案所有者;-R或——recursive:遞迴處理 user 使用者 [使用者組];命令配置伺服器執行的使用者或組

然後克隆虛擬機器2號和3號,注意執行指令碼配置網路。

這之後修改本地主機的hosts檔案,例如我的MacBook Pro上的vi /etc/hosts

192.168.177.11 itshop.test
192.168.177.11 www.itshop.test
192.168.177.12 file.itshop.test
192.168.177.13 upload.itshop.test
複製程式碼

Nginx + PHP 伺服器的搭建

在3、4、5號的伺服器中安裝PHP,其中3號伺服器提供檔案上傳服務,包括對圖片壓縮、生成縮圖、新增水印等,最後儲存到6號的檔案儲存伺服器中,4、5號伺服器是一個叢集用於執行網站的指令碼程式。

本身來說PHP與Apache的結合是最完美的(PHP以模組方式工作),但是這裡我們要用到Nginx(PHP以CGI方式工作),所以需要配置FastCGI,詳細請閱讀Nginx+Php-fpm 執行原理詳解

在3號伺服器中安裝PHP:

# 安裝依賴,需自行下載[libmcrypt-2.5.8.tar.gz](https://sourceforge.net/projects/mcrypt/files/Libmcrypt/2.5.8/libmcrypt-2.5.8.tar.gz/download)
yum -y install gcc-c++ libxmk2-devel curl-devel libjpeg-devel libpng-devel freetype-devel
tar -zxf libmcrypt-2.5.8.tar.gz
cd libmcrypt-2.5.8
./configure && make && make install && cd ..
# 編譯安裝PHP(演示用,我們採用的是php-5.6.27)
wget https://www.php.net/distributions/php-7.4.0.tar.gz
tar -zxf php-5.6.27.tar.gz
cd php-5.6.27
./configure --prefix=/usr/local/php --enable-fpm --with-zlib --enable-zip --enable-mbstring --with-mcrypt --with mysql \
--with-mysqli --with-pdo-mysql --with-gd --with-jpeg-dir --with-png-dir  \
--with-freetype-dir --with-curl --with-openssl --with-mhash --enable-bcmath \
--enable-opcache && make && make install
# 配置Nginx 和PHP
cp php.ini-production /usr/local/php/lib/php.ini
vi /usr/local/php/lib/php.ini # 配置時區為PRC date.timezone=PRC
cp sapi/fpm/init.d.php-fpm /etc/init.d/php-fpm # 建立服務指令碼、配置開機啟動
chmod +x /etc/init.d/php-fpm
chkconfig --add php-fpm
cd /usr/local/php/etc
cp php-fpm.conf.default php-fpm.conf
vi php-fpm.conf 
# 更改 [www] 下的配置
user=www # 子程式工作使用者
group=www
listen=/dev/shm/php-cgi.sock # 監聽sock檔案
listen.owner=www # socket 檔案的所有者
listen.group=www
service php-fpm start
vi /usr/local/nginx/conf/nginx.conf
# 在server塊中配置:
index index.html index.htm index.php
location ~\.php$ {
    try_files $uri =404;
    fastcgi_pass unix:/dev/shm/php-cgi.sock;
    include fastcgi.conf;
}
service nginx reload
複製程式碼

你可能還想知道這裡使用的unix domain socket連線套接字/dev/shm/php-cgi.sock(很多教程使用路徑/tmp,而路徑/dev/shm是個tmpfs,速度比磁碟快得多)——Nginx 中 fastcgi_pass 監聽埠 unix socket和tcp socket差別

完成上述操作之後,Nginx+PHP平臺就搭建完成。

基於3號虛擬機器,克隆出4、5號虛擬機器,注意配置IP地址和防火牆,這裡的4、5號伺服器不需要直接被外部訪問,因此可以更改防火牆規則,實現只允許1號負載均衡伺服器的IP地址可訪問:

vi /etc/sysconfig/network-scripts/ifcfg-ens33 # 改IP
iptables --list -n --line-numbers# 檢視規則
iptables -R INPUT 1 -s192.168.177.1 -p tcp --dport 80 -j ACCEPT
service iptables save
複製程式碼

關於iptables,訪問本機:在 INPUT 鏈上做過濾;本機訪問外部:在 OUTPUT 鏈上做過濾;通過本機訪問其他主機 : 在 FORWARD 鏈上做過濾。你可能需要補習iptables 教程

配置反向代理和負載均衡

經過前面的配置,4、5號伺服器只能由1號伺服器訪問,下面在1號伺服器中對Nginx進行配置以實現反向代理和負載均衡,編輯/usr/local/nginx/conf/nginx.conf

server {
    listen 80;
    server_name itshop.test www.itshop.test;
    location / {
        proxy_pass http://web_server;
        proxy_http_version 1.1;    # 後盾伺服器使用HTTP1.1
        proxy_set_header Connection "";  # 清空客戶端Connection訊息頭
        proxy_set_header Host $host;  # 傳遞Host頭
        proxy_set_header X-Real-IP $remote_addr;  # 傳遞真實客戶端IP
    }
}
upstream web_server{
    server 192.168.177.14;
    server 192.168.177.15;
    keepalive 32;  # 與後端伺服器保持的長連線數
}
複製程式碼

可以自己在/data/www下編寫index.php:

<?php
echo phpinfo();
?>
複製程式碼

在本機訪問,可以看到REMOTE__ADDR為負載均衡機(1號機)地址:

itshop.test/index.php

上面利用X-Real-IP請求頭傳遞了真實客戶端的IP,為了後盾4、5號伺服器將來自1號伺服器的X-Real_IP請求頭識別為客戶端IP,還需要在4、5號伺服器的server塊中配置:

real_ip_header X-Real-IP;
set_real_ip_from 192.168.177.11;  # 只從來自指定IP的請求中獲取X-Real_IP
複製程式碼

別忘了:service nginx reload

itshop.test/index.php

【其實,部署著部署著,我就覺得太繁瑣了,還不如上docker,但吐槽歸吐槽,我們繼續完成後續的內容】

LNMP 分散式叢集的部署實踐 系列文章:


dfface 的版權宣告:所有文章除特別宣告外,均採用 CC BY-NC-SA 4.0 許可協議。轉載請註明出處,嚴禁商業用途!

相關文章