前言
Nginx 是一個輕量級的、基于http的、高性能的反向代理的服務器和靜態web服務器。
正向代理和反向代理
不管是正向代理還是反向代理都是基于客戶端來說的。
- 正向代理特點正向代理是對客戶端的代理正向代理是架設在客戶端的主機客戶端在使用正向代理服務器時是要知道訪問的目標服務的地址案例隱藏真正的訪問者向服務端隱藏真正的訪問者。對于服務端來說,真正的訪問者時代理服務器。起到了隱藏客戶端的作用。例如:實際生活中的短信轟炸,你根本不知道是誰給你發的短信;DDoS攻擊也是這個原理,使用很多‘肉雞’機器來攻擊我們的服務器,我們無法查找真正的攻擊源。翻墻由于很多復雜的原因,導致服務器A不能直接訪問服務器B,但是服務器C可以訪問服務器B,而服務器A又可以訪問服務器C;這時,服務器C作為服務起A的代理服務器對B進行訪問。目前的翻墻軟件就是使用這個原理。提速同上原理一樣,服務器A訪問服務器B速度過慢,而服務器C訪問服務器B很快,服務器A訪問服務器C很快。則使用代理服務器提高效率。緩存增加客戶端緩存,減少對服務器的請求資源的壓力。例如maven的nexus就是一個典型的客戶端緩存例子。授權例如,在公司中,需要對員工電腦進行外網監控授權,則也是使用這種客戶端正向代理服務器。
- 反向代理特點反向代理是對服務端的代理反向代理是架設在服務端的主機客戶端端訪問的時候不知道真正服務主機的地址案例保護隱藏真正的服務客戶端只能訪問服務端代理服務器,而真正的服務端是不能直接訪問的,保護了服務端。分布式路由根據客戶端不同的請求,將請求路由到不同的服務端去。負載均衡服務端均攤客戶端的請求,保證服務端的高可用。動靜分離例如圖片、靜態頁面、css、js等,都為靜態資源,將其放到對應目錄下,客戶端加載靜態資源時,就不會請求到服務端,而只會將動態資源的請求發送到服務端,減輕服務端的壓力。數據緩存反向代理同正向代理一樣具有數據緩存的功能,都是為了減少服務端的壓力。
負載均衡
1、nginx的負載均衡策略有兩種:內置策略和擴展策略
2、內置策略:輪詢、權重輪詢、IP hash、least_conn
3、擴展策略:自己想怎么實現就怎么實現
輪詢
輪詢是upstream默認的負載均衡策略,每個請求會按時間順序逐一分配到不同的服務器
參數如下:
例子:
#動態服務器組
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
}
注:此策略適合服務器配置相當,無狀態且短平快的服務使用
權重
權重的方式,是在輪詢基礎上制定輪詢的幾率;權重分配越高,需要處理的請求越多;此策略也可和ip_hash、least_conn結合使用。
例子:
#動態服務器組
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
}
注:此策略適合服務器硬件配置差異比較大時使用
ip_hash
ip哈希的方式,基于客戶端IP來分配,確保統一IP地址的客戶端請求都到同一臺服務器,保證session會話。可以解決session不能跨域的問題
例子:
#動態服務器組
upstream dynamic_zuoyu {
ip_hash; #保證每個訪客固定訪問一個后端服務器
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
}
注:此策略適合服務器解決session不能跨域的問題時使用
least_conn
最少連接方式,將請求轉發給連接數較少的服務端。由于輪詢的方式是平均將請求轉發給各個服務器,使得負載大致相同。但是也存在其中某些請求的鏈路過長,占用時間長,導致某一些服務器的負載較高。所以最少連接的方式可以平衡輪詢會出現的這種問題
例子:
#動態服務器組
upstream dynamic_zuoyu {
least_conn; #把請求轉發給連接數較少的后端服務器
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
}
注:此策略適合請求時間長短不一造成服務器負載的情況時使用
fair(第三方,需要單獨安裝插件)
按照服務器的響應時間來分配請求,響應時間短的服務器優先分配(能者多勞)
例子:
#動態服務器組
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; #實現響應時間短的優先分配
}
url_hash(第三方,需要單獨安裝插件)
按照url哈希來分配請求到服務器,使得相同的url每次到的服務器一致,這樣也可以減輕對服務器的壓力(配合緩存命中來使用)
例子:
#動態服務器組
upstream dynamic_zuoyu {
hash $request_uri; #實現每個url定向到同一個后端服務器
server localhost:8080; #tomcat 7.0
server localhost:8081; #tomcat 8.0
server localhost:8082; #tomcat 8.5
server localhost:8083; #tomcat 9.0
}
注:此策略適合同一個資源多次請求的情況時使用
靜態web服務器
前后端分離
location / {
root /data/paibo_web_8081_css; #前端代碼存放路徑
index index.html index.htm;
}
靜態資源(文件、圖片等)
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,官方網站是 http://nginx.org ,自己找到需要的版本,右鍵復制下載鏈接
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的方式關閉不需要的模塊。可以使用--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
#關閉防火墻
systemctl stop firewalld
systemctl disable firewalld
#外部訪問,nginx默認監聽80端口
192.168.198.98:80
#重新載入配置文件
nginx -s reload
#重啟nginx
nginx -s reopen
#停止nginx
nginx -s stop
Nginx+Keepalived實現高可用
#在兩臺服務器安裝nginx,參考<Nginx的下載與安裝>
#我這里用的是下面兩臺服務器,為了區分,做了以下修改
192.168.198.6 #編輯index.html,<h1>Welcome to nginx! 2</h1>
192.168.198.98 #編輯index.html,<h1>Welcome to nginx! 1</h1>
#兩臺服務器都需要執行以下操作
#下載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主程序加入到環境變量(安裝目錄下)
cp /usr/local/keepalived/sbin/keepalived /usr/sbin/keepalived
#keepalived啟動腳本(源碼目錄下),放到/etc/init.d/目錄下就可以使用service命令便捷調用
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
#加為系統服務
chkconfig –add keepalived
#開機啟動
chkconfig keepalived on
#查看開機啟動的服務
chkconfig –list
#啟動、關閉、重啟
service keepalived start|stop|restart
######################### 至此,安裝完成;以下就是在keepalived.conf做HA的配置 #########################
vim /etc/keepalived/keepalived.conf
##### master #####
! Configuration File for keepalived
# 全局定義塊
global_defs {
router_id redis-rocketMQ #標志本節點的字符串,建議使用hostname
}
# keepalived 會定時執行腳本并對腳本執行的結果進行分析,動態調整 vrrp_instance 的優先級。如果腳本執行結果為 0,并且 weight 配置的值大于 0,則優先級相應>的增加。如果腳本執行結果非 0,并且 weight配置的值小于 0,則優先級相應的減少。其他情況,維持原本配置的優先級,即配置文件中 priority 對應的值。
vrrp_script chk_nginx {
script "/etc/keepalived/nginx_check.sh" #檢測 nginx 狀態的腳本路徑
interval 2 #檢測時間間隔
weight -20 #如果條件成立,權重-20
}
# 定義虛擬路由,VI_1 為虛擬路由的標示符,自己定義名稱
vrrp_instance VI_1 {
state MASTER #主節點為MASTER,備用節點為BACKUP
interface eno16777736 #與本機網卡名稱一致
virtual_router_id 51 #虛擬路由的id號,兩個節點必須設置一樣
mcast_src_ip 192.168.198.98
priority 100 #設置優先級,值范圍 0~254,master要比backup高
nopreempt #優先級高的設置 nopreempt 解決異常恢復后再次搶占的問題
advert_int 1 #組播信息發送間隔,節點必須設置一致
authentication { #設置驗證信息,節點必須設置一致
auth_type PASS
auth_pass 1111
}
#將 track_script 塊加入 instance 配置塊
track_script {
chk_nginx #執行 Nginx 監控的服務
}
virtual_ipaddress { #虛擬節點池,節點必須設置一樣
192.168.198.111 #虛擬ip,可設置多個
}
}
##### 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 狀態檢測腳本
#ps -C nginx | wc -l,查看當前有多少個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
#賦權限
chmod +x /etc/keepalived/nginx_check.sh
#啟動 兩臺Keepalived
service keepalived start
#訪問虛擬IP
192.168.198.111 # Welcome to nginx! 1
######################### HA測試 #########################
#由于我們寫了一個自動啟動nginx的腳本再keepalived中,故關閉時,先關閉keepalived,再關閉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高并發處理原理
高并發一般是由多進程、多線程和異步機制來處理的,而正好nginx采用了這三種有效的處理高并發的方式。
Nginx的進程模型
進程模型采用Master/Worker 方式。當 nginx 啟動的時候,會創建一個 Master 進程,Master進程會根據nginx.conf配置文件中相應的配置項來fork出多個worker子進程去處理請求(怎么處理也是根據配置文件中相應的配置文件)。
? Master進程負責管理Worker進程的生命周期、處理網絡事件、接收外界信號等。由于Master進程可以fork出多個Worker進程,所以說Nginx是多進程的。
Nginx的線程模型
? 線程模型是指worker進程用于接收和處理客戶端請求。每個worker進程可以同時處理多個用戶請求。
Nginx的異步處理模型
? 異步處理模式是指nginx處理請求的時候是采用I/O多路復用技術(select | poll | epoll 模型),即多個 I/O 可以復用一個進程。當 worker 進程接收到客戶端的請求后,會調用服務端對其請求進行處理,如果沒有立即得到響應結果, worker 進程沒有阻塞,而是去處理其他請求,知道有請求被服務端處理完成并返回響應結果。
? 這里的 worker 進程默認就是采用 epoll 多路復用機制來對服務端進行處理的。當服務端返回響應結果時,回調 epoll 多路復用器,epoll 告知 worker 進程,worker 會掛起當前正在處理的線程,去獲取響應結果返回客戶端,完成后再去執行被掛起的線程。整個過程中不會出現等待的情況,所以理論上Ngnix的一個進程就可以處理無限數量的連接,而且無需輪詢。
? 注:worker 進程接收客戶端請求不是采用的 epoll 模型,而是互斥鎖機制;只有對服務端的請求和響應采用的是 epoll 模型。
Nginx的特點
高并發
一個nginx的默認并發量為1024,是因為默認一個woker進程,每個進程處理量為1024,故1*1024;但是,在硬件條件滿足的條件下,nginx可以支持5~10w的并發量。具體做法如下:
####################### 操作系統配置 start #######################
#查看當前會話中所有的linux核心配置,而我們只需要關注open file這項
ulimit -a
#查看linux系統的“進程最大可打開文件數的設置”,默認時1024
ulimit -n
#修改“進程最大可打開文件數的設置”
vim /etc/security/limit.conf
#添加下面兩行
soft nofile 65535 #應用軟件級別限制的最大可打開文件數的限制
hard nofile 65535 #操作系統級別限制的最大可打開文件數的限制
#文件保存后不會馬上生效,所以還得更改當前會話級別的配置
ulimit -n 65535
####################### 操作系統配置 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 #######################
#查看當前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
#第一種很好理解,進程數*每個進程并發數
#第二種為什么要除以4呢?是因為在nginx官網有這么一段話
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也會建立兩條鏈接到服務端,故就是4
####################### max client計算方式 end #######################
低消耗
一萬個非活躍性鏈接,消耗內存僅暫用2.5M,故對于一般的dos攻擊不受影響,但是ddos還是有問題。
熱部署
可以在7*24小時不間斷服務提供,進行版本和配置平滑升級
#命令
nginx -s reload
####################### 命令過程解析 start #######################
1、當上面的命令一執行,如果發現配置文件已更改,會創建一個新的主進程
2、當前所有的worker進程不會再接收新的請求并把當前正在處理的請求執行完就關閉
3、master主進程會創建新的worker進程來接收并處理新的請求
####################### 命令過程解析 end #######################
高可用
之所以實現高可用,是因為在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,一定不要執行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配置文件詳解
整體結構
全局塊
配置影響nginx的全局指令。包括:
- 配置運行nginx的服務器用戶組
- worker process數
- nginx進程
- pid存放路徑
- 錯誤日志存放路徑
- 配置文件的引入
events塊
配置影響nginx服務器或與用戶的網絡連接。包括:
- 設置網絡連接的序列化(驚群)
- 是否允許同時接收多個網絡連接
- 選擇事件驅動模型
- 設置最大連接數
http塊
可以嵌套多個server模塊,配置代理、緩存、日志定義等和第三方模塊的配置。包括:
- 定義MIMI-Type
- 自定義服務日志格式
- 允許sendfile方式傳輸文件
- 連接超時時間
- 單連接請求數上限
server塊
配置虛擬主機相關參數。包括:
- 配置網絡監聽
- 配置基于名稱的虛擬主機
- 配置基于IP的虛擬主機
location塊
配置請求的路由,以及頁面和其他靜態資源的處理。包括:
- location配置
- 請求根目錄配置更改
- URL
- 網站默認首頁配置
配置清單例析
總結
文章到這里就結束了!Nginx 是一個高性能的 HTTP 和反向代理服務器,特點是占用內存少,并發能力強,事實上 Nginx 的并發能力確實在同類型的網頁服務器中表現較好。Nginx 專為性能優化而開發,性能是其最重要的要求,十分注重效率,有報告 Nginx 能支持高達 50000 個并發連接數。
最后
大家看完有什么不懂的可以在下方留言討論.
謝謝你的觀看。
覺得文章對你有幫助的話記得關注我點個贊支持一下!
作者:麒麟才子
鏈接:https://juejin.cn/post/6912616466513100807