Nginx是一款輕量級的 Web服務(wù)器 / 反向代理服務(wù)器 / 電子郵件(IMAP/POP3)代理服務(wù)器,主要的優(yōu)點(diǎn)是:
支持高并發(fā)連接,尤其是靜態(tài)界面,官方測試Nginx能夠支撐5萬并發(fā)連接
內(nèi)存占用極低
配置簡單,使用靈活,可以基于自身需要增強(qiáng)其功能,同時(shí)支持自定義模塊的開發(fā)使用靈活:可以根據(jù)需要,配置不同的負(fù)載均衡模式,URL地址重寫等功能
穩(wěn)定性高,在進(jìn)行反向代理時(shí),宕機(jī)的概率很低
支持熱部署,應(yīng)用啟動重載非常迅速
基本命令
# 啟動# 建議使用第一種,第二種會使窗口一直處于執(zhí)行中,不能進(jìn)行其他命令操作C:\server\nginx-1.19.2> start nginxC:\server\nginx-1.19.2> nginx.exe# 停止# stop是快速停止nginx,可能并不保存相關(guān)信息;quit是完整有序的停止nginx,并保存相關(guān)信息C:\server\nginx-1.19.2> nginx.exe -s stopC:\server\nginx-1.19.2> nginx.exe -s quit# 重載Nginx# 當(dāng)配置信息修改,需要重新載入這些配置時(shí)使用此命令C:\server\nginx-1.19.2> nginx.exe -s reload# 重新打開日志文件C:\server\nginx-1.19.2> nginx.exe -s reopen# 查看Nginx版本C:\server\nginx-1.19.2> nginx -v# 查看配置文件是否正確C:\server\nginx-1.19.2> nginx -t
簡單Demo
利用SwitchHost軟件編輯域名和IP的映射關(guān)系,或到目錄C:\Windows\System32\drivers\etc下,編輯hosts文件,增加配置如下(Mac 同理)127.0.0.1 kerwin.demo.com PS:推薦使用軟件SwitchHost,工作時(shí)幾乎是必用的
修改配置,如圖所示:
效果如圖所示:
網(wǎng)關(guān) (面向客戶的總?cè)肟冢?/p>
虛擬主機(jī)(為不同域名 / ip / 端口提供服務(wù)。如:VPS虛擬服務(wù)器)
路由(正向代理 / 反向代理)
靜態(tài)服務(wù)器
負(fù)載集群(提供負(fù)載均衡)
網(wǎng)關(guān):可以簡單的理解為用戶請求和服務(wù)器響應(yīng)的關(guān)口,即面向用戶的總?cè)肟?/p>
網(wǎng)關(guān)可以攔截客戶端所有請求,對該請求進(jìn)行權(quán)限控制、負(fù)載均衡、日志管理、接口調(diào)用監(jiān)控等,因此無論使用什么架構(gòu)體系,都可以使用Nginx作為最外層的網(wǎng)關(guān)
虛擬主機(jī)的定義:虛擬主機(jī)是一種特殊的軟硬件技術(shù),它可以將網(wǎng)絡(luò)上的每一臺計(jì)算機(jī)分成多個(gè)虛擬主機(jī),每個(gè)虛擬主機(jī)可以獨(dú)立對外提供 www 服務(wù),這樣就可以實(shí)現(xiàn)一臺主機(jī)對外提供多個(gè) web 服務(wù),每個(gè)虛擬主機(jī)之間是獨(dú)立的,互不影響的。
通過 Nginx 可以實(shí)現(xiàn)虛擬主機(jī)的配置,Nginx 支持三種類型的虛擬主機(jī)配置
基于 IP 的虛擬主機(jī)
基于域名的虛擬主機(jī)
基于端口的虛擬主機(jī)
表現(xiàn)形式其實(shí)大家多見過,即:
# 每個(gè) server 就是一個(gè)虛擬主機(jī)http { # ... server{ # ... } # ... server{ # ... }}
在Nginx的配置文件中,我們經(jīng)??梢钥吹竭@樣的配置:
location / { #....}
location在此處就起到了路由的作用,比如我們在同一個(gè)虛擬主機(jī)內(nèi)定義兩個(gè)不同的路由,如下:
location / { proxy_pass https://www.baidu.com/;}location /api { proxy_pass https://apinew.juejin.im/user_api/v1/user/get?aid=2608&user_id=1275089220013336?_self=1; }
效果如下:
、
因?yàn)槁酚傻拇嬖?,為我們后續(xù)解決跨域問題提供了一定的思路,同時(shí)配置內(nèi)容和API接口等更加方便
PS:路由的功能非常強(qiáng)大,支持正則匹配
此處額外解釋一下proxy_pass的含義
在Nginx中配置proxy_pass代理轉(zhuǎn)發(fā)時(shí),如果在proxy_pass后面的url加 /,表示絕對根路徑;
如果沒有/,表示相對路徑
正向代理
代理客戶;
隱藏真實(shí)的客戶,為客戶端收發(fā)請求,使真實(shí)客戶端對服務(wù)器不可見;
一個(gè)局域網(wǎng)內(nèi)的所有用戶可能被一臺服務(wù)器做了正向代理,由該臺服務(wù)器負(fù)責(zé) HTTP 請求;
意味著同服務(wù)器做通信的是正向代理服務(wù)器;
反向代理
代理服務(wù)器;
隱藏了真實(shí)的服務(wù)器,為服務(wù)器收發(fā)請求,使真實(shí)服務(wù)器對客戶端不可見;
負(fù)載均衡服務(wù)器,將用戶的請求分發(fā)到空閑的服務(wù)器上;
意味著用戶和負(fù)載均衡服務(wù)器直接通信,即用戶解析服務(wù)器域名時(shí)得到的是負(fù)載均衡服務(wù)器的 IP ;
共同點(diǎn)
都是做為服務(wù)器和客戶端的中間層
都可以加強(qiáng)內(nèi)網(wǎng)的安全性,阻止 web 攻擊
都可以做緩存機(jī)制,提高訪問速度
區(qū)別
正向代理其實(shí)是客戶端的代理,反向代理則是服務(wù)器的代理。
正向代理中,服務(wù)器并不知道真正的客戶端到底是誰;而在反向代理中,客戶端也不知道真正的服務(wù)器是誰。
作用不同。正向代理主要是用來解決訪問限制問題;而反向代理則是提供負(fù)載均衡、安全防護(hù)等作用。
靜態(tài)服務(wù)器是Nginx的強(qiáng)項(xiàng),使用非常容易,在默認(rèn)配置下本身就是指向了靜態(tài)的HTML界面,如:
location / { root html; index index.html index.htm;}
所以前端同學(xué)們,如果構(gòu)建好了界面,可以進(jìn)行相應(yīng)的配置,把界面指向目標(biāo)文件夾中即可,root指的是html文件夾
負(fù)載均衡功能是Nginx另一大殺手锏,一共有5種方式,著重介紹一下。
每個(gè)請求按時(shí)間順序逐一分配到不同的后端服務(wù)器,如果后端服務(wù)器down掉,能自動剔除,配置如下:
upstream tomcatserver { server 192.168.0.1; server 192.168.0.2;}
輪詢策略是默認(rèn)的負(fù)載均衡策略
即在輪詢的基礎(chǔ)之上,增加權(quán)重的概念,weight和訪問比率成正比,用于后端服務(wù)器性能不均的情況,配置如下:
upstream tomcatserver { server 192.168.0.1 weight=1; server 192.168.0.2 weight=10;}
每個(gè)請求按訪問ip的hash結(jié)果分配,這樣每個(gè)訪客固定訪問一個(gè)后端服務(wù)器,可以解決session的問題,配置如下:
upstream tomcatserver { ip_hash; server 192.168.0.14:88; server 192.168.0.15:80;}
第三方提供的負(fù)載均衡策略,按后端服務(wù)器的響應(yīng)時(shí)間來分配請求,響應(yīng)時(shí)間短的優(yōu)先分配,生產(chǎn)環(huán)境中有各種情況可能導(dǎo)致響應(yīng)時(shí)間波動,需要慎用
upstream tomcatserver { server server1; server server2; fair;}
第三方提供的負(fù)載均衡策略,按訪問url的hash結(jié)果來分配請求,使每個(gè)url定向到同一個(gè)后端服務(wù)器
upstream tomcatserver { server squid1:3128; server squid2:3128; hash $request_uri; hash_method crc32;}
先來看看Nginx模塊架構(gòu)圖:
這5個(gè)模塊由上到下重要性一次遞減。
(1)核心模塊;
核心模塊是Nginx服務(wù)器正常運(yùn)行必不可少的模塊,如同操作系統(tǒng)的內(nèi)核。它提供了Nginx最基本的核心服務(wù)。像進(jìn)程管理、權(quán)限控制、錯(cuò)誤日志記錄等;
(2)標(biāo)準(zhǔn)HTTP模塊;
標(biāo)準(zhǔn)HTTP模塊支持標(biāo)準(zhǔn)的HTTP的功能,如:端口配置,網(wǎng)頁編碼設(shè)置,HTTP響應(yīng)頭設(shè)置等;
(3)可選HTTP模塊;
可選HTTP模塊主要用于擴(kuò)展標(biāo)準(zhǔn)的HTTP功能,讓Nginx能處理一些特殊的服務(wù),如:解析GeoIP請求,SSL支持等;
(4)郵件服務(wù)模塊;
郵件服務(wù)模塊主要用于支持Nginx的郵件服務(wù);
(5)第三方模塊;
第三方模塊是為了擴(kuò)展Nginx服務(wù)器應(yīng)用,完成開發(fā)者想要的功能,如:Lua支持,JSON支持等;
模塊化設(shè)計(jì)使得Nginx方便開發(fā)和擴(kuò)展,功能很強(qiáng)大
基于上文中的Nginx模塊化結(jié)構(gòu),我們很容易想到,在請求的處理階段也會經(jīng)歷諸多的過程,Nginx 將各功能模塊組織成一條鏈,當(dāng)有請求到達(dá)的時(shí)候,請求依次經(jīng)過這條鏈上的部分或者全部模塊,進(jìn)行處理,每個(gè)模塊實(shí)現(xiàn)特定的功能。
一個(gè) HTTP Request 的處理過程:
初始化 HTTP Request
處理請求頭、處理請求體
如果有的話,調(diào)用與此請求(URL 或者 Location)關(guān)聯(lián)的 handler
依次調(diào)用各 phase handler 進(jìn)行處理
輸出內(nèi)容依次經(jīng)過 filter 模塊處理
Nginx 在啟動后,會有一個(gè) master 進(jìn)程和多個(gè) worker 進(jìn)程。
master 進(jìn)程主要用來管理worker 進(jìn)程,包括接收來自外界的信號,向各 worker 進(jìn)程發(fā)送信號,監(jiān)控 worker 進(jìn)程的運(yùn)行狀態(tài)以及啟動 worker 進(jìn)程。
worker 進(jìn)程是用來處理來自客戶端的請求事件。多個(gè) worker 進(jìn)程之間是對等的,它們同等競爭來自客戶端的請求,各進(jìn)程互相獨(dú)立,一個(gè)請求只能在一個(gè) worker 進(jìn)程中處理。worker 進(jìn)程的個(gè)數(shù)是可以設(shè)置的,一般會設(shè)置與機(jī)器 CPU 核數(shù)一致,這里面的原因與事件處理模型有關(guān)
Nginx 的進(jìn)程模型,可由下圖來表示:
這種設(shè)計(jì)帶來以下優(yōu)點(diǎn):
1) 利用多核系統(tǒng)的并發(fā)處理能力
現(xiàn)代操作系統(tǒng)已經(jīng)支持多核 CPU 架構(gòu),這使得多個(gè)進(jìn)程可以分別占用不同的 CPU 核心來工作。Nginx 中所有的 worker 工作進(jìn)程都是完全平等的。這提高了網(wǎng)絡(luò)性能、降低了請求的時(shí)延。
2) 負(fù)載均衡
多個(gè) worker 工作進(jìn)程通過進(jìn)程間通信來實(shí)現(xiàn)負(fù)載均衡,即一個(gè)請求到來時(shí)更容易被分配到負(fù)載較輕的 worker 工作進(jìn)程中處理。這也在一定程度上提高了網(wǎng)絡(luò)性能、降低了請求的時(shí)延。
3) 管理進(jìn)程會負(fù)責(zé)監(jiān)控工作進(jìn)程的狀態(tài),并負(fù)責(zé)管理其行為
管理進(jìn)程不會占用多少系統(tǒng)資源,它只是用來啟動、停止、監(jiān)控或使用其他行為來控制工作進(jìn)程。首先,這提高了系統(tǒng)的可靠性,當(dāng) worker 進(jìn)程出現(xiàn)問題時(shí),管理進(jìn)程可以啟動新的工作進(jìn)程來避免系統(tǒng)性能的下降。其次,管理進(jìn)程支持 Nginx 服務(wù)運(yùn)行中的程序升級、配置項(xiàng)修改等操作,這種設(shè)計(jì)使得動態(tài)可擴(kuò)展性、動態(tài)定制性較容易實(shí)現(xiàn)。
什么是驚群現(xiàn)象?
驚群效應(yīng)(thundering herd)是指多進(jìn)程(多線程)在同時(shí)阻塞等待同一個(gè)事件的時(shí)候(休眠狀態(tài)),如果等待的這個(gè)事件發(fā)生,那么他就會喚醒等待的所有進(jìn)程(或者線程),但是最終卻只能有一個(gè)進(jìn)程(線程)獲得這個(gè)時(shí)間的“控制權(quán)”,對該事件進(jìn)行處理,而其他進(jìn)程(線程)獲取“控制權(quán)”失敗,只能重新進(jìn)入休眠狀態(tài),這種現(xiàn)象和性能浪費(fèi)就叫做驚群效應(yīng)。
上文中介紹了Nginx的多進(jìn)程模型,而典型的多進(jìn)程模型正如文中所說,多個(gè)worker進(jìn)程之間是對等的,因此當(dāng)一個(gè)請求到來的時(shí)候,所有進(jìn)程會同時(shí)開始競爭,最終執(zhí)行的又只有一個(gè),這樣勢必會造成資源的浪費(fèi)。
Nginx解決該問題的思路是:不讓多個(gè)進(jìn)程在同一時(shí)間監(jiān)聽接受連接的socket,而是讓每個(gè)進(jìn)程輪流監(jiān)聽,這樣當(dāng)有連接過來的時(shí)候,就只有一個(gè)進(jìn)程在監(jiān)聽那肯定就沒有驚群的問題。
具體做法是:利用一把進(jìn)程間鎖,每個(gè)進(jìn)程中都嘗試獲得這把鎖,如果獲取成功將監(jiān)聽socket加入wait集合中,并設(shè)置超時(shí)等待連接到來,沒有獲得鎖的進(jìn)程則將監(jiān)聽socket從wait集合去除。
承接上文,我們知道了Nginx的多進(jìn)程模型后了解到,其工作進(jìn)程實(shí)際上只有幾個(gè),但為什么依然能獲得如此高的并發(fā)性能,當(dāng)然與其采用的事件驅(qū)動模型和異步非阻塞IO的方式來處理請求有關(guān)。
Nginx服務(wù)器響應(yīng)和處理Web請求的過程,是基于事件驅(qū)動模型的,它包含事件收集器、事件發(fā)送器和事件處理器等三部分基本單元,著重關(guān)注事件處理器,而一般情況下事件處理器有這么幾種辦法:
事件發(fā)送器每傳遞過來一個(gè)請求,目標(biāo)對象就創(chuàng)建一個(gè)新的進(jìn)程
事件發(fā)送器每傳遞過來一個(gè)請求,目標(biāo)對象就創(chuàng)建一個(gè)新的線程,來進(jìn)行處理
事件發(fā)送器每傳遞過來一個(gè)請求,目標(biāo)對象就將其放入一個(gè)待處理事件的列表,使用非阻塞I/O方式調(diào)用
第三種方式,在編寫程序代碼時(shí),邏輯比前面兩種都復(fù)雜。大多數(shù)網(wǎng)絡(luò)服務(wù)器采用了第三種方式,逐漸形成了所謂的事件驅(qū)動處理庫。
事件驅(qū)動處理庫又被稱為多路IO復(fù)用方法,最常見的包括以下三種:select模型,poll模型和epoll模型。
其中Nginx就默認(rèn)使用的是epoll模型,同時(shí)也支持其他事件模型。
epoll的幫助就在于其提供了一種機(jī)制,可以讓進(jìn)程同時(shí)處理多個(gè)并發(fā)請求,不用關(guān)心IO調(diào)用的具體狀態(tài)。IO調(diào)用完全由事件驅(qū)動模型來管理,這樣一來,當(dāng)某個(gè)工作進(jìn)程接收到客戶端的請求以后,調(diào)用IO進(jìn)行處理,如果不能立即得到結(jié)果,就去處理其他的請求;而工作進(jìn)程在此期間也無需等待響應(yīng),可以去處理其他事情;當(dāng)IO返回時(shí),epoll就會通知此工作進(jìn)程;該進(jìn)程得到通知后,會來繼續(xù)處理未完的請求
在生產(chǎn)環(huán)境或者開發(fā)環(huán)境中Nginx一般會代理多個(gè)虛擬主機(jī),如果把所有的配置文件寫在默認(rèn)的nginx.conf中,看起來會非常臃腫,因此建議將每一個(gè)虛擬文件單獨(dú)放置一個(gè)文件夾,Nginx支持這樣的配置,如下:
http { # 省略中間配置 # 引用該目錄下以 .conf 文件結(jié)尾的配置 include /etc/nginx/conf.d/*.conf;}
具體文件配置如:
# Demoupstream web_pro_testin { server 10.42.46.70:6003 max_fails=3 fail_timeout=20s; ip_hash;}server { listen 80; server_name web.pro.testin.cn; location / { proxy_pass http://web_pro_testin; proxy_redirect off; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } location ~ ^/(WEB-INF)/ { deny all; }}
# 運(yùn)行用戶user www-data; # 啟動進(jìn)程,通常設(shè)置成和cpu的數(shù)量相等worker_processes 6;# 全局錯(cuò)誤日志定義類型,[debug | info | notice | warn | error | crit]error_log logs/error.log;error_log logs/error.log notice;error_log logs/error.log info;# 進(jìn)程pid文件pid /var/run/nginx.pid;# 工作模式及連接數(shù)上限events { # 僅用于linux2.6以上內(nèi)核,可以大大提高nginx的性能 use epoll; # 單個(gè)后臺worker process進(jìn)程的最大并發(fā)鏈接數(shù) worker_connections 1024; # 客戶端請求頭部的緩沖區(qū)大小 client_header_buffer_size 4k; # keepalive 超時(shí)時(shí)間 keepalive_timeout 60; # 告訴nginx收到一個(gè)新連接通知后接受盡可能多的連接 # multi_accept on; }#設(shè)定http服務(wù)器,利用它的反向代理功能提供負(fù)載均衡支持http { # 文件擴(kuò)展名與文件類型映射表義 include /etc/nginx/mime.types; # 默認(rèn)文件類型 default_type application/octet-stream; # 默認(rèn)編碼 charset utf-8; # 服務(wù)器名字的hash表大小 server_names_hash_bucket_size 128; # 客戶端請求頭部的緩沖區(qū)大小 client_header_buffer_size 32k; # 客戶請求頭緩沖大小 large_client_header_buffers 4 64k; # 設(shè)定通過nginx上傳文件的大小 client_max_body_size 8m; # 開啟目錄列表訪問,合適下載服務(wù)器,默認(rèn)關(guān)閉。 autoindex on; # sendfile 指令指定 nginx 是否調(diào)用 sendfile 函數(shù)(zero copy 方式)來輸出文件,對于普通應(yīng)用, # 必須設(shè)為 on,如果用來進(jìn)行下載等應(yīng)用磁盤IO重負(fù)載應(yīng)用,可設(shè)置為 off,以平衡磁盤與網(wǎng)絡(luò)I/O處理速度 sendfile on; # 此選項(xiàng)允許或禁止使用socke的TCP_CORK的選項(xiàng),此選項(xiàng)僅在使用sendfile的時(shí)候使用 #tcp_nopush on; # 連接超時(shí)時(shí)間(單秒為秒) keepalive_timeout 65; # gzip模塊設(shè)置 gzip on; #開啟gzip壓縮輸出 gzip_min_length 1k; #最小壓縮文件大小 gzip_buffers 4 16k; #壓縮緩沖區(qū) gzip_http_version 1.0; #壓縮版本(默認(rèn)1.1,前端如果是squid2.5請使用1.0) gzip_comp_level 2; #壓縮等級 gzip_types text/plain application/x-javascript text/css application/xml; gzip_vary on; # 開啟限制IP連接數(shù)的時(shí)候需要使用 #limit_zone crawler $binary_remote_addr 10m; # 指定虛擬主機(jī)的配置文件,方便管理 include /etc/nginx/conf.d/*.conf; # 負(fù)載均衡配置 upstream mysvr { # 請見上文中的五種配置 } # 虛擬主機(jī)的配置 server { # 監(jiān)聽端口 listen 80; # 域名可以有多個(gè),用空格隔開 server_name www.jd.com jd.com; # 默認(rèn)入口文件名稱 index index.html index.htm index.php; root /data/www/jd; # 圖片緩存時(shí)間設(shè)置 location ~ .*.(gif|jpg|jpeg|png|bmp|swf)${ expires 10d; } #JS和CSS緩存時(shí)間設(shè)置 location ~ .*.(js|css)?${ expires 1h; } # 日志格式設(shè)定 #$remote_addr與$http_x_forwarded_for用以記錄客戶端的ip地址; #$remote_user:用來記錄客戶端用戶名稱; #$time_local: 用來記錄訪問時(shí)間與時(shí)區(qū); #$request: 用來記錄請求的url與http協(xié)議; #$status: 用來記錄請求狀態(tài);成功是200, #$body_bytes_sent :記錄發(fā)送給客戶端文件主體內(nèi)容大??; #$http_referer:用來記錄從那個(gè)頁面鏈接訪問過來的; log_format access '$remote_addr - $remote_user [$time_local] '$request' ' '$status $body_bytes_sent '$http_referer' ' ''$http_user_agent' $http_x_forwarded_for'; # 定義本虛擬主機(jī)的訪問日志 access_log /usr/local/nginx/logs/host.access.log main; access_log /usr/local/nginx/logs/host.access.404.log log404; # 對具體路由進(jìn)行反向代理 location /connect-controller { proxy_pass http://127.0.0.1:88; proxy_redirect off; proxy_set_header X-Real-IP $remote_addr; # 后端的Web服務(wù)器可以通過X-Forwarded-For獲取用戶真實(shí)IP proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $host; # 允許客戶端請求的最大單文件字節(jié)數(shù) client_max_body_size 10m; # 緩沖區(qū)代理緩沖用戶端請求的最大字節(jié)數(shù), client_body_buffer_size 128k; # 表示使nginx阻止HTTP應(yīng)答代碼為400或者更高的應(yīng)答。 proxy_intercept_errors on; # nginx跟后端服務(wù)器連接超時(shí)時(shí)間(代理連接超時(shí)) proxy_connect_timeout 90; # 后端服務(wù)器數(shù)據(jù)回傳時(shí)間_就是在規(guī)定時(shí)間之內(nèi)后端服務(wù)器必須傳完所有的數(shù)據(jù) proxy_send_timeout 90; # 連接成功后,后端服務(wù)器響應(yīng)的超時(shí)時(shí)間 proxy_read_timeout 90; # 設(shè)置代理服務(wù)器(nginx)保存用戶頭信息的緩沖區(qū)大小 proxy_buffer_size 4k; # 設(shè)置用于讀取應(yīng)答的緩沖區(qū)數(shù)目和大小,默認(rèn)情況也為分頁大小,根據(jù)操作系統(tǒng)的不同可能是4k或者8k proxy_buffers 4 32k; # 高負(fù)荷下緩沖大?。╬roxy_buffers*2) proxy_busy_buffers_size 64k; # 設(shè)置在寫入proxy_temp_path時(shí)數(shù)據(jù)的大小,預(yù)防一個(gè)工作進(jìn)程在傳遞文件時(shí)阻塞太長 # 設(shè)定緩存文件夾大小,大于這個(gè)值,將從upstream服務(wù)器傳 proxy_temp_file_write_size 64k; } # 動靜分離反向代理配置(多路由指向不同的服務(wù)端或界面) location ~ .(jsp|jspx|do)?$ { proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_pass http://127.0.0.1:8080; } }}
思路有兩個(gè):
基于多路由,把跨域的兩個(gè)請求發(fā)到各自的服務(wù)器,然后統(tǒng)一訪問入口即可避免該問題
利用Nginx配置Headerd的功能,為其附上相應(yīng)的請求頭
根據(jù)用戶設(shè)備不同返回不同樣式的站點(diǎn),以前經(jīng)常使用的是純前端的自適應(yīng)布局,但無論是復(fù)雜性和易用性上面還是不如分開編寫的好,比如我們常見的淘寶、京東......這些大型網(wǎng)站就都沒有采用自適應(yīng),而是用分開制作的方式,根據(jù)用戶請求的 user-agent 來判斷是返回 PC 還是 H5 站點(diǎn)
Nginx按請求速率限速模塊使用的是漏桶算法,即能夠強(qiáng)行保證請求的實(shí)時(shí)處理速度不會超過設(shè)置的閾值,如:
http { limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s; server { location /search/ { limit_req zone=one burst=5 nodelay; } }}
見上文中Nginx在架構(gòu)體系中的作用,配合Nginx還能做什么作答即可
理解網(wǎng)關(guān)的必要性,以及Nginx保證高可用,負(fù)載均衡的能力
如果一個(gè)server采用一個(gè)進(jìn)程負(fù)責(zé)一個(gè)request的方式,那么進(jìn)程數(shù)就是并發(fā)數(shù)。那么顯而易見的,就是會有很多進(jìn)程在等待中。等什么?最多的應(yīng)該是等待網(wǎng)絡(luò)傳輸。
而nginx 的異步非阻塞工作方式正是利用了這點(diǎn)等待的時(shí)間。在需要等待的時(shí)候,這些進(jìn)程就空閑出來待命了。因此表現(xiàn)為少數(shù)幾個(gè)進(jìn)程就解決了大量的并發(fā)問題。
nginx是如何利用的呢,簡單來說:同樣的4個(gè)進(jìn)程,如果采用一個(gè)進(jìn)程負(fù)責(zé)一個(gè)request的方式,那么,同時(shí)進(jìn)來4個(gè)request之后,每個(gè)進(jìn)程就負(fù)責(zé)其中一個(gè),直至?xí)掙P(guān)閉。期間,如果有第5個(gè)request進(jìn)來了。就無法及時(shí)反應(yīng)了,因?yàn)?個(gè)進(jìn)程都沒干完活呢,因此,一般有個(gè)調(diào)度進(jìn)程,每當(dāng)新進(jìn)來了一個(gè)request,就新開個(gè)進(jìn)程來處理。
nginx不這樣,每進(jìn)來一個(gè)request,會有一個(gè)worker進(jìn)程去處理。但不是全程的處理,處理到什么程度呢?處理到可能發(fā)生阻塞的地方,比如向上游(后端)服務(wù)器轉(zhuǎn)發(fā)request,并等待請求返回。那么,這個(gè)處理的worker不會這么傻等著,他會在發(fā)送完請求后,注冊一個(gè)事件:“如果upstream返回了,告訴我一聲,我再接著干”。于是他就休息去了。此時(shí),如果再有request 進(jìn)來,他就可以很快再按這種方式處理。而一旦上游服務(wù)器返回了,就會觸發(fā)這個(gè)事件,worker才會來接手,這個(gè)request才會接著往下走。
由于web server的工作性質(zhì)決定了每個(gè)request的大部份生命都是在網(wǎng)絡(luò)傳輸中,實(shí)際上花費(fèi)在server機(jī)器上的時(shí)間片不多。這是幾個(gè)進(jìn)程就解決高并發(fā)的秘密所在。
總結(jié):事件模型,異步非阻塞,多進(jìn)程模型加上細(xì)節(jié)優(yōu)化的共同作用
見上文
見上文
見上文
深入理解多進(jìn)程模型加上異步非阻塞IO的好處以及多線程模型中上下文切換的劣勢
非常耗費(fèi)服務(wù)器的CPU
實(shí)際上有兩種,多進(jìn)程和單進(jìn)程,但是實(shí)際工作中都是多進(jìn)程的
作者:不假