前言
參考鏈接:nginx_百度百科
- Nginx 是一個(gè)非常輕量級(jí)的服務(wù)器,他雖輕但是他最大的優(yōu)點(diǎn)就是可以承載大量的并發(fā),所以說(shuō)一般的話很少有用 Node 直接去做服務(wù)器讓用戶去訪問(wèn)的,因?yàn)?Node 本身就需要做非 常非常多的事情,雖然說(shuō)簡(jiǎn)單的可以使用 Node 直接開(kāi)啟,但是對(duì)于負(fù)載和并發(fā) Node 是弱項(xiàng),就是反向代理和并發(fā)是 Node 整個(gè)的弱項(xiàng),所以我們需要在前面用 Nginx 擋一層,這樣的話對(duì)于我們整個(gè)的系統(tǒng)的運(yùn)維架構(gòu)來(lái)講也是一個(gè)非常得力的一個(gè)助手,還有就是跟其他的比如說(shuō)我們后層整個(gè)架構(gòu)的設(shè)計(jì)屬于運(yùn)維的這一塊,它也是有一種先天優(yōu)勢(shì)的這樣的服務(wù)器
概述
主要結(jié)構(gòu)
- 什么是反向代理與負(fù)載均衡
- 反向代理
- 負(fù)載均衡
- Nginx 負(fù)載均衡的實(shí)現(xiàn)
- HTTP UPstream 模塊
- 什么是 HTTP Upstream 模塊
- ip_hash 指令 -- 落到哪個(gè)上
- server 指令 -- server 的權(quán)重
- UPstream 指令
- 其他負(fù)載均衡的方法
- 對(duì)于我們前端而言只需要將負(fù)載子我們的項(xiàng)目里面配置好就可以了不需要去太深入的學(xué)習(xí),只要給人家運(yùn)維一眼一口,然后知道怎么配合就完了,因?yàn)閷?duì)于運(yùn)維來(lái)講,他們是不太懂 Node 的什么什么東西的,他們只會(huì)配這個(gè) Nginx 的,所以說(shuō)我們學(xué)這個(gè)的話只要學(xué)的夠用就 ok 了
1. 什么是反向代理與負(fù)載均衡
- 反向代理
image.png
- 舉例說(shuō)明:
- 比如說(shuō)平時(shí)我們上谷歌上不了然后需要翻墻,谷歌是我們明確的去要訪問(wèn)的站點(diǎn),這個(gè)時(shí)候我們會(huì)用一些翻墻的工具(代理服務(wù)器),這個(gè)代理服務(wù)器幫我們?nèi)』毓雀杞o我們看,這個(gè)就是一個(gè)正向的代理
- 那么反向 代理剛好是相反的:我們不知道去取哪一臺(tái)機(jī)器,然后代理幫我們?nèi)ト。缓蟀讶〉降膬?nèi)容返回給我們
- 一個(gè)是明確的知道,一個(gè)是不知道,這就是正向代理和反向代理
- 上圖解釋
- 就是用自己的計(jì)算機(jī) A 想訪問(wèn)國(guó)外的網(wǎng)站 B ,訪問(wèn)不了,就有一個(gè)中間的服務(wù)器 C 它去訪問(wèn)國(guó)外的網(wǎng)站 B ,其實(shí)如果是把這個(gè) C 裝到我們自己的電腦上,我們自己的電腦訪問(wèn) C ,然后 C 再去訪問(wèn) B ,這個(gè)時(shí)候這個(gè) C 就叫代理服務(wù)器,這個(gè)時(shí)候就是正向代理,他有一個(gè)特點(diǎn),就是我們一定知道要訪問(wèn)哪個(gè)網(wǎng)站
- 還有就是當(dāng)我們有一個(gè)服務(wù)器集群,而且服務(wù)器集群中的每臺(tái)服務(wù)器的內(nèi)容都是一樣的時(shí)候,同樣我們從個(gè)人的電腦訪問(wèn)到比如說(shuō) 現(xiàn)在我們有四臺(tái) Node 的機(jī)器 ,但是我們無(wú)法訪問(wèn),這個(gè)時(shí)候有第三方的服務(wù)器是可以訪問(wèn)到 那四個(gè) Node 的機(jī)器的 ,這個(gè)時(shí)候我們就可以借助這個(gè)第三方的服務(wù)器去訪問(wèn), 但是我們并不知道它最后會(huì)落到四臺(tái)中的哪一臺(tái)機(jī)器上,這個(gè)就是反向代理
- 負(fù)載均衡
image.png
- 跟上面的反向代理有一個(gè)息息相關(guān)的東西就是負(fù)載均衡
- 就是上面的四臺(tái)機(jī)器,你不知道最終要找的是誰(shuí),但是 Nginx 知道,它會(huì)幫你找到壓力最小的那個(gè)服務(wù)器然后返回給你,就這樣的可以分擔(dān)你的壓力
- 上圖需要注意的點(diǎn)
- 在建立很多很多個(gè)服務(wù)器的時(shí)候,要確保每臺(tái)服務(wù)器上的東西得是一樣的
- 上圖中所說(shuō)的中間服務(wù)器,在本章中指的就是 Nginx
2. Nginx 負(fù)載均衡的實(shí)現(xiàn)
image.png
3. HTTP UPstream 模塊
- 什么是 HTTP UPstream 模塊
image.png
- ip_hash 指令
image.png
- 這個(gè)是比如用戶落在這樣一臺(tái)服務(wù)器上了,然后下次用戶一刷新又落到別的上面了,這個(gè)就不太對(duì)了,所以 ip_hash 是為了保證用戶再次刷新的時(shí)候還能落到他之前落到的那臺(tái)服務(wù)器上,這樣就 ok 了
- server 指令
image.png
- 這個(gè)是:你可以指定這臺(tái)服務(wù)器的權(quán)重,就是說(shuō)如果你知道了這臺(tái)機(jī)器要比別的優(yōu)秀,那么你可以給它的權(quán)重給標(biāo)的高一點(diǎn),那么更多的請(qǐng)求就會(huì)落到這個(gè)你認(rèn)為優(yōu)秀的機(jī)器上面,默認(rèn)是 1:1:1 的,這個(gè) 1:1:1 可以舉成 2:1:1 的例子來(lái)說(shuō)明:就是現(xiàn)在有三臺(tái)機(jī)器,第一臺(tái)的權(quán)重被設(shè)置為了 2 后面兩臺(tái)都是 1 ,這樣的話落到第一臺(tái)的幾率就是 2 / 3,后面兩臺(tái)的都是 1 / 3
- UPstream 指令
image.png
4. 其他負(fù)載均衡的方法
image.png
上面的主要是理論下面是實(shí)戰(zhàn)操作
macOS 部署 Nginx
image.png
- 第一步的網(wǎng)址是 MAC 系統(tǒng)下的一個(gè)神器,它是一個(gè) macOS 缺失的軟件包管理器 https://brew.sh/index_zh-cn.html
- 接著就是打開(kāi)命令行終端依次輸入命令
//安裝 Homebrew
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
//查看是否有 nginx 的包
brew search nginx
命令行輸出如下:打了一個(gè)對(duì)勾就證明是有的,接下來(lái)就可以安裝了
image.png
//安裝 nginx
brew install nginx
//裝過(guò)之后可以查看 nginx 對(duì)應(yīng)的一些版本的信息
brew info nginx
//查看 nginx 版本信息
nginx -v
//啟動(dòng) nginx ,這個(gè)默認(rèn)的端口號(hào)是 8080
nginx
//可以暫停 nginx
nginx -s stop
//再次啟動(dòng) nginx
nginx
- 這個(gè)是時(shí)候在瀏覽器中輸入 localhost:8080 就可以打開(kāi) nginx 首頁(yè)了
image.png
- 這個(gè)時(shí)候你會(huì)發(fā)現(xiàn)頁(yè)面 title 的 icon 是 Jenkins 的頭像,這個(gè)原因是因?yàn)槿绻阊b過(guò) Jenkins 的話,它是非常頑固的會(huì)不停的去折騰、重啟你的 8080 端口,你如果是
kill是殺不掉的,你需要用下面的命令就可以把它給停掉了
//停掉 jenkins
sudo launchctl unload/Library/LaunchDaemons/org.jenkins-ci.plist
//停掉之后如果想啟動(dòng) jenkins
systemctl start jenkins
- 想要進(jìn)行上面的 反向代理和負(fù)載均衡 還需要對(duì) nginx 進(jìn)行配置
//停止 nginx 服務(wù)
nginx -s stop
//重新加載 nginx 配置文件
nginx -s reload
- 打開(kāi) nginx 具體安裝目錄 查看配置文件
-
/usr/local/etc/nginx/這個(gè)是 macOS 下 nginx 的安裝目錄,其他系統(tǒng)的可能會(huì)不大一樣
//先進(jìn)入 nginx 目錄的上一級(jí)目錄
cd /usr/local/etc/
//查看該目錄下的所有文件,可以在下圖看到 nginx 目錄
ls
image.png
//再進(jìn)入 nginx 目錄
cd nginx
//查看該目錄下的所有文件,可以在下圖看到 nginx 目錄下的所有文件
ls
image.png
- 可以看到里面有個(gè) nginx.conf 的文件,這個(gè)就是 nginx 的配置文件,上面的 nginx2.conf 是之前做的備份可以忽略掉
//查看配置文件的內(nèi)容,下圖是內(nèi)容的一部分,這個(gè)里面的內(nèi)容就是 nginx 默認(rèn)的配置內(nèi)容
cat nginx.conf
image.png
- 對(duì)上圖的一些解釋
-
#user指的是哪個(gè)用戶能用,可以將后面的 nobody 修改成你指定誰(shuí)用的那個(gè)用戶的用戶名 -
worker_processes這個(gè)是你的一個(gè)工作的進(jìn)程,其實(shí)實(shí)際上指的就是 CPU 的核數(shù),如果你是 4 核的話,這個(gè)值就是 4,你需要看到自己的電腦是幾核的處理器,然后你可以在這里面做相應(yīng)的設(shè)置,最多就是 2 倍,一般就是標(biāo)準(zhǔn)的幾核就是幾個(gè) 或者 2 倍,這個(gè)不能亂設(shè) -
#error_log這個(gè)就是整個(gè)產(chǎn)生錯(cuò)誤的日志- nginx 的日志跟我們 Node 的日志比一點(diǎn)都不遜色,它們的區(qū)別是:nginx 可以完全的記錄所有的請(qǐng)求的日志,因?yàn)樗且粋€(gè)向外去擴(kuò)散的一個(gè)去做負(fù)載均衡的口子,你的那個(gè) Node 是你的項(xiàng)目里的一些 log ,兩個(gè)人都各自有分工
- 這個(gè) log 是會(huì)非常龐大的,所以像有的一些大公司會(huì)有專門去存 log 的服務(wù)器,那些數(shù)據(jù)挖掘的人或者是運(yùn)維會(huì)每天去查這個(gè)日志,從這些日志里其實(shí)可以拿到很多很多的東西,所以這個(gè)日志是至關(guān)重要的,對(duì)于大公司來(lái)講這個(gè)是比命還重要的東西,所以 nginx 的日志是萬(wàn)萬(wàn)不能丟的,任何語(yǔ)言里的日志它們都會(huì)分成 level(級(jí)別)
- 上面的第一行就是 出錯(cuò)的日志 ,第二行是警告的,第三行是基本信息
-
#pid這個(gè)是 nginx 非常重要的一個(gè)配置文件,這個(gè)就別動(dòng)就好了 -
events -> worker_connections這個(gè)就是整個(gè)的連接數(shù),就是說(shuō)你一下子往你的這個(gè)上面壓多少 -
http模塊 在這個(gè)里面可以去指定一下所謂的我們平時(shí)的 gzip 、Etag 等等都是從這里去開(kāi)啟的-
#gzip把前面的#號(hào)去掉,然后這個(gè) gzip 就開(kāi)啟了,在我們?nèi)プ鲂阅軆?yōu)化的時(shí)候在這里面把 Etag 一開(kāi)就很簡(jiǎn)單,還包括那個(gè) express 過(guò)期時(shí)間都在這里 - server
- listen 這里是監(jiān)聽(tīng) 8080 端口
-
#charset koi8-r這個(gè)是它輸出的語(yǔ)言 - access_log 這個(gè)是它的日志
- location 這個(gè)非常重要,里面的 root 不是指的同戶名,而是當(dāng)前的 html 文件夾,它會(huì)從下面的順序依次開(kāi)始找,直到找到對(duì)應(yīng)的一個(gè)文件然后去給你吐
-
error_page這個(gè)是 Node 控制出錯(cuò)的,有時(shí)你會(huì)發(fā)現(xiàn)百度、騰訊或者是其他的一些公司的 404 是一樣的,原因就是在這的,所有的請(qǐng)求都固定到這,然后他把一些出錯(cuò)都控制好 是這樣的一個(gè)原因 - 下面還有一些 500 502 503 504 ,他都把這些出錯(cuò)導(dǎo)到 50x 去了,所以這些不是真正的內(nèi)部的系統(tǒng)去做的。而是一些做負(fù)載均衡的服務(wù)器去做的
-
location ~ \.php$這些就是用正則去匹配一些更復(fù)雜的,就是你真正的路由都可以在這里面去寫(xiě)
-
-
- 接下來(lái)就是我們要給運(yùn)維做什么
- 我們要給運(yùn)維做的東西相對(duì)來(lái)說(shuō)比較簡(jiǎn)單,不用去搞那些雜七雜八的,注意:修改文件的時(shí)候要記得把注釋刪掉
//這個(gè)就是我們前端需要給運(yùn)維做的東西,這個(gè)是從復(fù)雜的 nginx 里去抽出來(lái)的
worker_processes 4;//這個(gè)是你的一個(gè)工作的進(jìn)程,其實(shí)實(shí)際上指的就是 CPU 的核數(shù)
events{
worker_connections 1024;//這個(gè)就是整個(gè)的連接數(shù),就是說(shuō)你一下子往你的這個(gè)上面壓多少
}
//上面兩個(gè)其實(shí)你不給運(yùn)維的話也是可以的,他都不要,你寫(xiě)了也沒(méi)用,關(guān)鍵的就是下面的 http
http{
//這個(gè)是負(fù)載均衡的所有的 server ,這里的 IP 地址需要寫(xiě)成你需要用到的真實(shí)有效的才行
upstream firsttest{
server 192.168.230.128;
server 192.168.230.129;
}
server{
//通過(guò) server 監(jiān)聽(tīng)的是 8080
listen 8080;
//當(dāng)你訪問(wèn) / 這個(gè)路由地址的時(shí)候 通過(guò)下面的 proxy_pass 代理去訪問(wèn) firsttest 然后就可以了
location / {
proxy_pass http://firsttest;
}
}
}
- 無(wú)注釋版本
worker_processes 4;
events{
worker_connections 1024;
}
http{
upstream firsttest{
server 192.168.230.128;
server 192.168.230.129;
}
server{
listen 8080;
location / {
proxy_pass http://firsttest;
}
}
}
-
接著是對(duì)照上面的設(shè)置修改你的 nginx.conf 文件
- 先要對(duì)之前的 nginx.conf 文件進(jìn)行備份
//先進(jìn)入到系統(tǒng)安裝的 nginx 目錄下 cd /usr/local/etc/nginx //備份配置文件 cp nginx.conf nginx.conf.back //備份之后再查看是否已成功生成文件 lsimage.png- 修改 nginx.conf 文件,將下面的代碼片段里面的設(shè)置相應(yīng)的復(fù)制按照規(guī)則復(fù)制進(jìn)這個(gè)文件中,之后保存即可
worker_processes 4; events{ worker_connections 1024; } http{ upstream firsttest{ server 192.168.230.128; server 192.168.230.129; } server{ listen 8080; location / { proxy_pass http://firsttest; } } } 修改并保存之后,在瀏覽器中打開(kāi)你設(shè)置的兩個(gè)服務(wù)器 ip 地址進(jìn)行查看,打不開(kāi)的原因也會(huì)出現(xiàn),比如:防火墻未關(guān)閉導(dǎo)致的
image.png
image.png
- 為了顯示區(qū)別 我將兩臺(tái)服務(wù)器上的文字稍作了修改,修改之后,還需要重載 nginx 才會(huì)生效哦
//先暫停
nginx -s stop
//進(jìn)入 html 目錄修改 index.html
cd /usr/share/nginx/html
vi html
//修改之后保存并退出
ESC 鍵
:
wq
//重載
nginx -s reload
//啟動(dòng)
nginx
- 現(xiàn)在刷新瀏覽器,會(huì)發(fā)現(xiàn) 128 和 129 兩臺(tái)服務(wù)器分別能落到的幾率為 50%
Animation10.gif
-
這里我發(fā)現(xiàn)了一個(gè)問(wèn)題,因?yàn)槲业膬膳_(tái)服務(wù)器一個(gè)是 Centos 一個(gè)是 Ubuntu 128,Centos 129 的里面的 index.html 文件修改成功了多了 192.168.230.129 端口號(hào),但是 Ubuntu 那個(gè)沒(méi)有
- 解決上面 Ubuntu 的問(wèn)題
//先查看 nginx 配置文件 cat /etc/nginx/nginx.conf- 會(huì)發(fā)現(xiàn) http 設(shè)置里面有這樣的默認(rèn)設(shè)置
image.png- 這里我再次分別進(jìn)入這兩個(gè)目錄
//發(fā)現(xiàn)只有這個(gè)目錄下有個(gè) default 文件 cd /etc/nginx/sites-enabled ls //查看該文件 cat default- 發(fā)現(xiàn)里面引用的是 root 用戶下的
/var/www/html目錄中的 html
image.png- 這時(shí)去修改
/var/www/html目錄下的 html 文件
cd /var/www/html //查看目錄下包含的文件 發(fā)現(xiàn)只有 index.nginx-debian.html 文件 ls //使用下面的命令以圖形化的方式打開(kāi)該目錄(適合 Ubuntu 下使用的命令) 再在編輯器中 修改 index.nginx-debian.html 文件 保存并退出 nautilus ./ //先將 nginx 運(yùn)行暫停 //再重載 //最后啟動(dòng) systemctl start nginx //最后查看是否是 running 狀態(tài) systemctl status nginximage.png- Ubuntu 下重啟期間總是會(huì)出現(xiàn)一些莫名奇妙的問(wèn)題,我的解決方法就是
//先找到在運(yùn)行中的與 nginx 相關(guān)的所有進(jìn)程 ps -eaf |grep nginx //然后使用 kill -9 命令將他們一個(gè)一個(gè)的殺掉 kill -9 1250 //再重新啟動(dòng) nginx systemctl start nginx
- 這個(gè)時(shí)候再去刷新查看瀏覽器,會(huì)發(fā)現(xiàn)已經(jīng)成功了 129 128 每次落到的幾率都是 50%
Animation11.gif
- 還可以在修改 nginx.conf 配置文件中的 http 對(duì)象,這里我是在 Ubuntu 下里面的文件
//先暫停 nginx
systemctl stop nginx
//進(jìn)入配置文件目錄
cd /etc/nginx
//以圖形化的界面打開(kāi)該目錄
nautilus ./
//在編輯器中編輯 nginx.conf 配置文件
//在 firsttest 里面增加一個(gè) ip_hash 屬性 一定記得要加 分號(hào)
upstream firsttest{
ip_hash;
}
//之后再重載一遍
nginx -s reload
//運(yùn)行
nginx
image.png
- 再刷新瀏覽器,會(huì)發(fā)現(xiàn)訪問(wèn)的是 Ubuntu 這個(gè) 128
的增加了 ip_hash 的服務(wù)器時(shí),只要你第一個(gè)訪問(wèn)成功了,那么它下次就會(huì)默認(rèn)還訪問(wèn)這個(gè)上次訪問(wèn)成功了的服務(wù)器 ,不會(huì)再落到另一臺(tái)服務(wù)器上了,Centos 129 那個(gè)服務(wù)器就還是之前的 50% 幾率的動(dòng)態(tài)落
Animation12.gif
- 還可以在里面加一個(gè)權(quán)重的東西,參照上面的方法,權(quán)重是添加到 IP 地址后面的,下圖中加了屬性 值為 2 這樣的話如果是頁(yè)面刷新三次的話 落到 128 Ubuntu 這臺(tái)服務(wù)器上的幾率就是 3 / 2 ,要先把上面加的 ip_hash 刪掉,測(cè)試才會(huì)有效
image.png
下面主要是一些 在 Ubuntu 和 Centos 下與上面的 MAC 下的具體操作差異,還有就是操作時(shí)遇到的一些坑
- 裝包,Centos 的話需要 先將Centos的yum源更換為國(guó)內(nèi)的阿里云源 參考地址:將Centos的yum源更換為國(guó)內(nèi)的阿里云源 再進(jìn)行安裝
//Centos
yum install nginx
//Ubuntu
sudo apt-get install nginx
-
在修改完 nginx.conf 文件并保存后 重載時(shí)會(huì)報(bào)錯(cuò)
- 下面是報(bào)錯(cuò)的文本
nginx: [error] invalid PID number "" in "/run/nginx.pid"
- 需要先執(zhí)行一行命令,才能再執(zhí)行重載
// /etc/nginx 是 ubuntu 和 centos 下的安裝目錄 cd /etc/nginx nginx -c /etc/nginx/nginx.conf //然后再進(jìn)行重載 nginx -s reload 啟動(dòng)和暫停命令使用
systemctl
//啟動(dòng) nginx
systemctl start nginx
//暫停 nginx
systemctl stop nginx
//重啟 nginx
systemctl restart nginx
- 如果在啟動(dòng)時(shí)遇到下面的錯(cuò)誤,可移步至 centos7安裝nginx
Job for nginx.service failed because the control process exited with error code. See "systemctl status nginx.service" and "journalctl -xe" for details.
- Ubuntu 和 Centos nginx 的具體文件位置
- nginx 配置文件的目錄 /etc/nginx/
- nginx 項(xiàng)目資源文件的目錄 /usr/share/nginx/
- 有時(shí)在本機(jī)打不開(kāi)的原因:防火墻未關(guān)閉、nginx 未啟動(dòng)
- 在 Ubuntu 下修改文件時(shí)先進(jìn)入目錄下再使用
nautilus ./命令以圖形化的形式打開(kāi)目錄,再在編輯器中進(jìn)行編輯并保存比較方便 - 這里我使用的是 Centos 和 Ubuntu 兩個(gè)虛擬機(jī)來(lái)模擬的服務(wù)器
image.png

























