前言
Nginx 是一個輕量級的、基于http的、高性能的反向代理的服務(wù)器和靜態(tài)web服務(wù)器。
正向代理和反向代理
不管是正向代理還是反向代理都是基于客戶端來說的。
- 正向代理特點正向代理是對客戶端的代理正向代理是架設(shè)在客戶端的主機客戶端在使用正向代理服務(wù)器時是要知道訪問的目標服務(wù)的地址案例隱藏真正的訪問者向服務(wù)端隱藏真正的訪問者。對于服務(wù)端來說,真正的訪問者時代理服務(wù)器。起到了隱藏客戶端的作用。例如:實際生活中的短信轟炸,你根本不知道是誰給你發(fā)的短信;DDoS攻擊也是這個原理,使用很多‘肉雞’機器來攻擊我們的服務(wù)器,我們無法查找真正的攻擊源。翻墻由于很多復(fù)雜的原因,導(dǎo)致服務(wù)器A不能直接訪問服務(wù)器B,但是服務(wù)器C可以訪問服務(wù)器B,而服務(wù)器A又可以訪問服務(wù)器C;這時,服務(wù)器C作為服務(wù)起A的代理服務(wù)器對B進行訪問。目前的翻墻軟件就是使用這個原理。提速同上原理一樣,服務(wù)器A訪問服務(wù)器B速度過慢,而服務(wù)器C訪問服務(wù)器B很快,服務(wù)器A訪問服務(wù)器C很快。則使用代理服務(wù)器提高效率。緩存增加客戶端緩存,減少對服務(wù)器的請求資源的壓力。例如maven的nexus就是一個典型的客戶端緩存例子。授權(quán)例如,在公司中,需要對員工電腦進行外網(wǎng)監(jiān)控授權(quán),則也是使用這種客戶端正向代理服務(wù)器。
- 反向代理特點反向代理是對服務(wù)端的代理反向代理是架設(shè)在服務(wù)端的主機客戶端端訪問的時候不知道真正服務(wù)主機的地址案例保護隱藏真正的服務(wù)客戶端只能訪問服務(wù)端代理服務(wù)器,而真正的服務(wù)端是不能直接訪問的,保護了服務(wù)端。分布式路由根據(jù)客戶端不同的請求,將請求路由到不同的服務(wù)端去。負載均衡服務(wù)端均攤客戶端的請求,保證服務(wù)端的高可用。動靜分離例如圖片、靜態(tài)頁面、css、js等,都為靜態(tài)資源,將其放到對應(yīng)目錄下,客戶端加載靜態(tài)資源時,就不會請求到服務(wù)端,而只會將動態(tài)資源的請求發(fā)送到服務(wù)端,減輕服務(wù)端的壓力。數(shù)據(jù)緩存反向代理同正向代理一樣具有數(shù)據(jù)緩存的功能,都是為了減少服務(wù)端的壓力。
負載均衡
1、nginx的負載均衡策略有兩種:內(nèi)置策略和擴展策略
2、內(nèi)置策略:輪詢、權(quán)重輪詢、IP hash、least_conn
3、擴展策略:自己想怎么實現(xiàn)就怎么實現(xiàn)

輪詢
輪詢是upstream默認的負載均衡策略,每個請求會按時間順序逐一分配到不同的服務(wù)器
參數(shù)如下:

例子:
#動態(tài)服務(wù)器組
upstream dynamic_zuoyu {
server localhost:8080; #Tomcat 7.0
server localhost:8081; #tomcat 8.0
server localhost:8082 backup; #tomcat 8.5
server localhost:8083 max_fails=3 fail_timeout=20s; #tomcat 9.0
}
注:此策略適合服務(wù)器配置相當(dāng),無狀態(tài)且短平快的服務(wù)使用
權(quán)重
權(quán)重的方式,是在輪詢基礎(chǔ)上制定輪詢的幾率;權(quán)重分配越高,需要處理的請求越多;此策略也可和ip_hash、least_conn結(jié)合使用。
例子:
#動態(tài)服務(wù)器組
upstream dynamic_zuoyu {
server localhost:8080 weight=2; #tomcat 7.0
server localhost:8081; #tomcat 8.0
server localhost:8082 backup; #tomcat 8.5
server localhost:8083 max_fails=3 fail_timeout=20s; #tomcat 9.0
}
注:此策略適合服務(wù)器硬件配置差異比較大時使用
ip_hash
ip哈希的方式,基于客戶端IP來分配,確保統(tǒng)一IP地址的客戶端請求都到同一臺服務(wù)器,保證session會話。可以解決session不能跨域的問題
例子:
#動態(tài)服務(wù)器組
upstream dynamic_zuoyu {
ip_hash; #保證每個訪客固定訪問一個后端服務(wù)器
server localhost:8080 weight=2; #tomcat 7.0
server localhost:8081; #tomcat 8.0
server localhost:8082; #tomcat 8.5
server localhost:8083 max_fails=3 fail_timeout=20s; #tomcat 9.0
}
注:此策略適合服務(wù)器解決session不能跨域的問題時使用
least_conn
最少連接方式,將請求轉(zhuǎn)發(fā)給連接數(shù)較少的服務(wù)端。由于輪詢的方式是平均將請求轉(zhuǎn)發(fā)給各個服務(wù)器,使得負載大致相同。但是也存在其中某些請求的鏈路過長,占用時間長,導(dǎo)致某一些服務(wù)器的負載較高。所以最少連接的方式可以平衡輪詢會出現(xiàn)的這種問題
例子:
#動態(tài)服務(wù)器組
upstream dynamic_zuoyu {
least_conn; #把請求轉(zhuǎn)發(fā)給連接數(shù)較少的后端服務(wù)器
server localhost:8080 weight=2; #tomcat 7.0
server localhost:8081; #tomcat 8.0
server localhost:8082 backup; #tomcat 8.5
server localhost:8083 max_fails=3 fail_timeout=20s; #tomcat 9.0
}
注:此策略適合請求時間長短不一造成服務(wù)器負載的情況時使用
fair(第三方,需要單獨安裝插件)
按照服務(wù)器的響應(yīng)時間來分配請求,響應(yīng)時間短的服務(wù)器優(yōu)先分配(能者多勞)
例子:
#動態(tài)服務(wù)器組
upstream dynamic_zuoyu {
server localhost:8080; #tomcat 7.0
server localhost:8081; #tomcat 8.0
server localhost:8082; #tomcat 8.5
server localhost:8083; #tomcat 9.0
fair; #實現(xiàn)響應(yīng)時間短的優(yōu)先分配
}
url_hash(第三方,需要單獨安裝插件)
按照url哈希來分配請求到服務(wù)器,使得相同的url每次到的服務(wù)器一致,這樣也可以減輕對服務(wù)器的壓力(配合緩存命中來使用)
例子:
#動態(tài)服務(wù)器組
upstream dynamic_zuoyu {
hash $request_uri; #實現(xiàn)每個url定向到同一個后端服務(wù)器
server localhost:8080; #tomcat 7.0
server localhost:8081; #tomcat 8.0
server localhost:8082; #tomcat 8.5
server localhost:8083; #tomcat 9.0
}
注:此策略適合同一個資源多次請求的情況時使用
靜態(tài)web服務(wù)器
前后端分離
location / {
root /data/paibo_web_8081_css; #前端代碼存放路徑
index index.html index.htm;
}
靜態(tài)資源(文件、圖片等)
location /upfile/ {
root /home/audit_files/; #文件存放路徑
index index.html;
}
Nginx的下載與安裝
#下載gcc編譯器
yum -y install gcc gcc-c++
#下載PCRE
yum -y install pcre-devel openssl-devel
#下載nginx,官方網(wǎng)站是 http://nginx.org ,自己找到需要的版本,右鍵復(fù)制下載鏈接
wget http://nginx.org/download/nginx-1.19.2.tar.gz
#解壓
tar -zxvf nginx-1.19.2.tar.gz
#生成makefile。使用./configure --help查看各個模塊的使用情況,使用--without-http_ssi_module的方式關(guān)閉不需要的模塊。可以使用--with-http_perl_modules方式安裝需要的模塊
cd nginx-1.19.2
./configure --prefix=/usr/local/nginx --with-http_stub_status_module --with-http_ssl_module
#編譯安裝
make && make install
#進入到安裝目錄
cd /usr/local/nginx/
#將 /usr/local/nginx/sbin/nginx 軟連接到 /usr/local/sbin 下,就可以在任意地方使用nginx命令
ln -s /usr/local/nginx/sbin/nginx /usr/local/sbin/
#修改配置文件
vim /usr/local/nginx/conf/nginx.conf
#測試nginx配置文件是否正常
nginx -t
#啟動nginx
nginx
#關(guān)閉防火墻
systemctl stop firewalld
systemctl disable firewalld
#外部訪問,nginx默認監(jiān)聽80端口
192.168.198.98:80
#重新載入配置文件
nginx -s reload
#重啟nginx
nginx -s reopen
#停止nginx
nginx -s stop
Nginx+Keepalived實現(xiàn)高可用
#在兩臺服務(wù)器安裝nginx,參考<Nginx的下載與安裝>
#我這里用的是下面兩臺服務(wù)器,為了區(qū)分,做了以下修改
192.168.198.6 #編輯index.html,<h1>Welcome to nginx! 2</h1>
192.168.198.98 #編輯index.html,<h1>Welcome to nginx! 1</h1>
#兩臺服務(wù)器都需要執(zhí)行以下操作
#下載keepalived安裝包
cd /data/soft/
wget https://www.keepalived.org/software/keepalived-2.1.0.tar.gz
#解壓安裝包
tar -zxvf keepalived-2.1.0.tar.gz
#編譯安裝
cd keepalived-2.1.0
./configure --prefix=/usr/local/keepalived
make && make install
#keepalived啟動腳本變量引用文件,默認文件路徑是/etc/sysconfig/,也可以不做軟鏈接,直接修改啟動腳本中文件路徑即可(安裝目錄下)
cp /usr/local/keepalived/etc/sysconfig/keepalived /etc/sysconfig/keepalived
#將keepalived主程序加入到環(huán)境變量(安裝目錄下)
cp /usr/local/keepalived/sbin/keepalived /usr/sbin/keepalived
#keepalived啟動腳本(源碼目錄下),放到/etc/init.d/目錄下就可以使用service命令便捷調(diào)用
cp /data/soft/keepalived-2.1.0/keepalived/etc/init.d/keepalived /etc/init.d/keepalived
#將配置文件放到默認路徑下
mkdir /etc/keepalived
cp /usr/local/keepalived/etc/keepalived/keepalived.conf /etc/keepalived/keepalived.conf
#加為系統(tǒng)服務(wù)
chkconfig –add keepalived
#開機啟動
chkconfig keepalived on
#查看開機啟動的服務(wù)
chkconfig –list
#啟動、關(guān)閉、重啟
service keepalived start|stop|restart
######################### 至此,安裝完成;以下就是在keepalived.conf做HA的配置 #########################
vim /etc/keepalived/keepalived.conf
##### master #####
! Configuration File for keepalived
# 全局定義塊
global_defs {
router_id redis-rocketMQ #標志本節(jié)點的字符串,建議使用hostname
}
# keepalived 會定時執(zhí)行腳本并對腳本執(zhí)行的結(jié)果進行分析,動態(tài)調(diào)整 vrrp_instance 的優(yōu)先級。如果腳本執(zhí)行結(jié)果為 0,并且 weight 配置的值大于 0,則優(yōu)先級相應(yīng)>的增加。如果腳本執(zhí)行結(jié)果非 0,并且 weight配置的值小于 0,則優(yōu)先級相應(yīng)的減少。其他情況,維持原本配置的優(yōu)先級,即配置文件中 priority 對應(yīng)的值。
vrrp_script chk_nginx {
script "/etc/keepalived/nginx_check.sh" #檢測 nginx 狀態(tài)的腳本路徑
interval 2 #檢測時間間隔
weight -20 #如果條件成立,權(quán)重-20
}
# 定義虛擬路由,VI_1 為虛擬路由的標示符,自己定義名稱
vrrp_instance VI_1 {
state MASTER #主節(jié)點為MASTER,備用節(jié)點為BACKUP
interface eno16777736 #與本機網(wǎng)卡名稱一致
virtual_router_id 51 #虛擬路由的id號,兩個節(jié)點必須設(shè)置一樣
mcast_src_ip 192.168.198.98
priority 100 #設(shè)置優(yōu)先級,值范圍 0~254,master要比backup高
nopreempt #優(yōu)先級高的設(shè)置 nopreempt 解決異常恢復(fù)后再次搶占的問題
advert_int 1 #組播信息發(fā)送間隔,節(jié)點必須設(shè)置一致
authentication { #設(shè)置驗證信息,節(jié)點必須設(shè)置一致
auth_type PASS
auth_pass 1111
}
#將 track_script 塊加入 instance 配置塊
track_script {
chk_nginx #執(zhí)行 Nginx 監(jiān)控的服務(wù)
}
virtual_ipaddress { #虛擬節(jié)點池,節(jié)點必須設(shè)置一樣
192.168.198.111 #虛擬ip,可設(shè)置多個
}
}
##### backup #####
! Configuration File for keepalived
global_defs {
router_id zk_alone
}
vrrp_script chk_nginx {
script "/etc/keepalived/nginx_check.sh"
interval 2
weight -20
}
vrrp_instance VI_1 {
state BACKUP
interface eno16777736
virtual_router_id 51
mcast_src_ip 192.168.198.6
priority 90
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
track_script {
chk_nginx
}
virtual_ipaddress {
192.168.198.111
}
}
#編寫 Nginx 狀態(tài)檢測腳本
#ps -C nginx | wc -l,查看當(dāng)前有多少個nginx進程
#邏輯:如果 nginx 停止運行,嘗試啟動,如果無法啟動則殺死本機的 keepalived 進程, keepalied將虛擬 ip 綁定到 BACKUP 機器上
vi /etc/keepalived/nginx_check.sh
#!/bin/bash
A=`ps -C nginx –no-header |wc -l`
if [ $A -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
#賦權(quán)限
chmod +x /etc/keepalived/nginx_check.sh
#啟動 兩臺Keepalived
service keepalived start
#訪問虛擬IP
192.168.198.111 # Welcome to nginx! 1
######################### HA測試 #########################
#由于我們寫了一個自動啟動nginx的腳本再keepalived中,故關(guān)閉時,先關(guān)閉keepalived,再關(guān)閉nginx
192.168.198.98
service keepalived stop
nginx -s stop
#再次訪問192.168.198.111查看變化 Welcome to nginx! 2
192.168.198.98
service keepalived start #由于有啟動nginx的腳本,故省去啟動nginx的操作
#再次訪問192.168.198.111查看變化 Welcome to nginx! 1
Nginx高并發(fā)處理原理
高并發(fā)一般是由多進程、多線程和異步機制來處理的,而正好nginx采用了這三種有效的處理高并發(fā)的方式。
Nginx的進程模型
進程模型采用Master/Worker 方式。當(dāng) nginx 啟動的時候,會創(chuàng)建一個 Master 進程,Master進程會根據(jù)nginx.conf配置文件中相應(yīng)的配置項來fork出多個worker子進程去處理請求(怎么處理也是根據(jù)配置文件中相應(yīng)的配置文件)。
? Master進程負責(zé)管理Worker進程的生命周期、處理網(wǎng)絡(luò)事件、接收外界信號等。由于Master進程可以fork出多個Worker進程,所以說Nginx是多進程的。

Nginx的線程模型
? 線程模型是指worker進程用于接收和處理客戶端請求。每個worker進程可以同時處理多個用戶請求。

Nginx的異步處理模型
? 異步處理模式是指nginx處理請求的時候是采用I/O多路復(fù)用技術(shù)(select | poll | epoll 模型),即多個 I/O 可以復(fù)用一個進程。當(dāng) worker 進程接收到客戶端的請求后,會調(diào)用服務(wù)端對其請求進行處理,如果沒有立即得到響應(yīng)結(jié)果, worker 進程沒有阻塞,而是去處理其他請求,知道有請求被服務(wù)端處理完成并返回響應(yīng)結(jié)果。
? 這里的 worker 進程默認就是采用 epoll 多路復(fù)用機制來對服務(wù)端進行處理的。當(dāng)服務(wù)端返回響應(yīng)結(jié)果時,回調(diào) epoll 多路復(fù)用器,epoll 告知 worker 進程,worker 會掛起當(dāng)前正在處理的線程,去獲取響應(yīng)結(jié)果返回客戶端,完成后再去執(zhí)行被掛起的線程。整個過程中不會出現(xiàn)等待的情況,所以理論上Ngnix的一個進程就可以處理無限數(shù)量的連接,而且無需輪詢。
? 注:worker 進程接收客戶端請求不是采用的 epoll 模型,而是互斥鎖機制;只有對服務(wù)端的請求和響應(yīng)采用的是 epoll 模型。

Nginx的特點
高并發(fā)
一個nginx的默認并發(fā)量為1024,是因為默認一個woker進程,每個進程處理量為1024,故1*1024;但是,在硬件條件滿足的條件下,nginx可以支持5~10w的并發(fā)量。具體做法如下:
####################### 操作系統(tǒng)配置 start #######################
#查看當(dāng)前會話中所有的linux核心配置,而我們只需要關(guān)注open file這項
ulimit -a
#查看linux系統(tǒng)的“進程最大可打開文件數(shù)的設(shè)置”,默認時1024
ulimit -n
#修改“進程最大可打開文件數(shù)的設(shè)置”
vim /etc/security/limit.conf
#添加下面兩行
soft nofile 65535 #應(yīng)用軟件級別限制的最大可打開文件數(shù)的限制
hard nofile 65535 #操作系統(tǒng)級別限制的最大可打開文件數(shù)的限制
#文件保存后不會馬上生效,所以還得更改當(dāng)前會話級別的配置
ulimit -n 65535
####################### 操作系統(tǒng)配置 end #######################
####################### nginx配置 start #######################
#修改nginx配置文件(下面兩行)
vim /src/local/nginx/conf/nginx.conf
user root root;
worker_processes 4;
worker_rlimit_nofile 65535; #這行,看這里看這里
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid;
events {
use epoll;
worker_connections 65535; #這行,看這里看這里
}
#熱部署重新加載配置文件
nginx -s reload
####################### nginx配置 end #######################
####################### 驗證配置是否正確 start #######################
#查看當(dāng)前nginx進程信息
ps -ef | grep nginx
root 103734 1 0 13:27 ? 00:00:00 nginx: master process nginx
nobody 103735 103734 0 13:27 ? 00:00:00 nginx: worker process
root 105129 3066 0 14:50 pts/0 00:00:00 grep --color=auto nginx
#注意,也是看open files這項
cat /proc/103735/limits
####################### 驗證配置是否正確 start #######################
####################### max client計算方式 start #######################
max client = worker_processes * worker_connections
或
max client = worker_processes * worker_connections / 4
#第一種很好理解,進程數(shù)*每個進程并發(fā)數(shù)
#第二種為什么要除以4呢?是因為在nginx官網(wǎng)有這么一段話
Since a browser opens 2 connections by default to a server and nginx uses the fds (file descriptors) from the same pool to connect to the upstream backend。
#就是說,瀏覽器會建立兩條鏈接到nginx,而nginx也會建立兩條鏈接到服務(wù)端,故就是4
####################### max client計算方式 end #######################
低消耗
一萬個非活躍性鏈接,消耗內(nèi)存僅暫用2.5M,故對于一般的dos攻擊不受影響,但是ddos還是有問題。
熱部署
可以在7*24小時不間斷服務(wù)提供,進行版本和配置平滑升級
#命令
nginx -s reload
####################### 命令過程解析 start #######################
1、當(dāng)上面的命令一執(zhí)行,如果發(fā)現(xiàn)配置文件已更改,會創(chuàng)建一個新的主進程
2、當(dāng)前所有的worker進程不會再接收新的請求并把當(dāng)前正在處理的請求執(zhí)行完就關(guān)閉
3、master主進程會創(chuàng)建新的worker進程來接收并處理新的請求
####################### 命令過程解析 end #######################
高可用
之所以實現(xiàn)高可用,是因為在nginx中,woker都一個一個的進程,就算其中某個進程掛掉了,也對其他的進程沒得影響,而且其他的進程會接替出問題的進程。
高擴展
由于nginx是模塊化集成,故在我們使用中,缺少什么模塊我們就安裝什么模塊(模塊一般分為C語言擴展模塊和Lua腳本擴展模塊)
#下載模塊
git clone https://github.com/agentzh/echo-nginx-module
#放入指定位置
mv echo-nginx-module-master /usr/local/nginx/echo-nginx-module
#就用這個命令生成新的makefile
./configure
--prefix=/usr/local/nginx
--with-http_stub_status_module
--with-http_ssl_module
--add-module=/usr/local/nginx/echo-nginx-module
#編譯(這里只需要make,一定不要執(zhí)行make install,不然會被覆蓋)
make
#備份原文件
cp /usr/local/nginx/sbin/nginx /usr/local/nginx/sbin/nginx.bak
#替換nginx二進制文件
cp /usr/local/nginx/objs/nginx /usr/local/nginx/sbin/nginx
#重新建立軟連接,檢測配置文件并平滑啟動
ln -s /usr/local/nginx/sbin/nginx /usr/local/bin/nginx
nginx -t
nginx -s reload
Nginx配置文件詳解

整體結(jié)構(gòu)
全局塊
配置影響nginx的全局指令。包括:
- 配置運行nginx的服務(wù)器用戶組
- worker process數(shù)
- nginx進程
- pid存放路徑
- 錯誤日志存放路徑
- 配置文件的引入
events塊
配置影響nginx服務(wù)器或與用戶的網(wǎng)絡(luò)連接。包括:
- 設(shè)置網(wǎng)絡(luò)連接的序列化(驚群)
- 是否允許同時接收多個網(wǎng)絡(luò)連接
- 選擇事件驅(qū)動模型
- 設(shè)置最大連接數(shù)
http塊
可以嵌套多個server模塊,配置代理、緩存、日志定義等和第三方模塊的配置。包括:
- 定義MIMI-Type
- 自定義服務(wù)日志格式
- 允許sendfile方式傳輸文件
- 連接超時時間
- 單連接請求數(shù)上限
server塊
配置虛擬主機相關(guān)參數(shù)。包括:
- 配置網(wǎng)絡(luò)監(jiān)聽
- 配置基于名稱的虛擬主機
- 配置基于IP的虛擬主機
location塊
配置請求的路由,以及頁面和其他靜態(tài)資源的處理。包括:
- location配置
- 請求根目錄配置更改
- URL
- 網(wǎng)站默認首頁配置
配置清單例析

總結(jié)
文章到這里就結(jié)束了!Nginx 是一個高性能的 HTTP 和反向代理服務(wù)器,特點是占用內(nèi)存少,并發(fā)能力強,事實上 Nginx 的并發(fā)能力確實在同類型的網(wǎng)頁服務(wù)器中表現(xiàn)較好。Nginx 專為性能優(yōu)化而開發(fā),性能是其最重要的要求,十分注重效率,有報告 Nginx 能支持高達 50000 個并發(fā)連接數(shù)。
最后
大家看完有什么不懂的可以在下方留言討論.
謝謝你的觀看。
覺得文章對你有幫助的話記得關(guān)注我點個贊支持一下!
作者:麒麟才子
鏈接:https://juejin.cn/post/6912616466513100807