Nginx 面試 40 問
點(diǎn)擊上方?前端Q,關(guān)注公眾號(hào)
回復(fù)加群,加入前端Q技術(shù)交流群
來自:CSDN,作者:夏目 "
鏈接:https://blog.csdn.net/wuzhiwei549/article/details/122758937
什么是Nginx? Nginx 有哪些優(yōu)點(diǎn)? Nginx應(yīng)用場(chǎng)景? Nginx怎么處理請(qǐng)求的? Nginx 是如何實(shí)現(xiàn)高并發(fā)的? 什么是正向代理? 什么是反向代理? 反向代理服務(wù)器的優(yōu)點(diǎn)是什么? Nginx目錄結(jié)構(gòu)有哪些? Nginx配置文件nginx.conf有哪些屬性模塊? cookie和session區(qū)別? 為什么 Nginx 不使用多線程? nginx和apache的區(qū)別 什么是動(dòng)態(tài)資源、靜態(tài)資源分離? 為什么要做動(dòng)、靜分離? 什么叫 CDN 服務(wù)? Nginx怎么做的動(dòng)靜分離? Nginx負(fù)載均衡的算法怎么實(shí)現(xiàn)的?策略有哪些? 如何用Nginx解決前端跨域問題? Nginx虛擬主機(jī)怎么配置? location的作用是什么? 限流怎么做的? 漏桶流算法和令牌桶算法知道? Nginx配置高可用性怎么配置? Nginx怎么判斷別IP不可訪問? 在nginx中,如何使用未定義的服務(wù)器名稱來阻止處理請(qǐng)求? 怎么限制瀏覽器訪問? Rewrite全局變量是什么? Nginx 如何實(shí)現(xiàn)后端服務(wù)的健康檢查? Nginx 如何開啟壓縮? ngx_http_upstream_module的作用是什么? 什么是C10K問題? Nginx是否支持將請(qǐng)求壓縮到上游? 如何在Nginx中獲得當(dāng)前的時(shí)間? 用Nginx服務(wù)器解釋-s的目的是什么? 如何在Nginx服務(wù)器上添加模塊? 生產(chǎn)中如何設(shè)置worker進(jìn)程的數(shù)量呢? nginx狀態(tài)碼
省內(nèi)存空間
什么是Nginx?
Nginx是一個(gè) 輕量級(jí)/高性能的反向代理Web服務(wù)器,用于 HTTP、HTTPS、SMTP、POP3 和 IMAP 協(xié)議。他實(shí)現(xiàn)非常高效的反向代理、負(fù)載平衡,他可以處理2-3萬并發(fā)連接數(shù),官方監(jiān)測(cè)能支持5萬并發(fā),現(xiàn)在中國(guó)使用nginx網(wǎng)站用戶有很多,例如:新浪、網(wǎng)易、 騰訊等。
Nginx 有哪些優(yōu)點(diǎn)?
跨平臺(tái)、配置簡(jiǎn)單。 非阻塞、高并發(fā)連接:處理 2-3 萬并發(fā)連接數(shù),官方監(jiān)測(cè)能支持 5 萬并發(fā)。 內(nèi)存消耗?。洪_啟 10 個(gè) Nginx 才占 150M 內(nèi)存。 成本低廉,且開源。 穩(wěn)定性高,宕機(jī)的概率非常小。 內(nèi)置的健康檢查功能:如果有一個(gè)服務(wù)器宕機(jī),會(huì)做一個(gè)健康檢查,再發(fā)送的請(qǐng)求就不會(huì)發(fā)送到宕機(jī)的服務(wù)器了。重新將請(qǐng)求提交到其他的節(jié)點(diǎn)上
Nginx應(yīng)用場(chǎng)景?
http服務(wù)器。Nginx是一個(gè)http服務(wù)可以獨(dú)立提供http服務(wù)。可以做網(wǎng)頁靜態(tài)服務(wù)器。 虛擬主機(jī)??梢詫?shí)現(xiàn)在一臺(tái)服務(wù)器虛擬出多個(gè)網(wǎng)站,例如個(gè)人網(wǎng)站使用的虛擬機(jī)。 反向代理,負(fù)載均衡。當(dāng)網(wǎng)站的訪問量達(dá)到一定程度后,單臺(tái)服務(wù)器不能滿足用戶的請(qǐng)求時(shí),需要用多臺(tái)服務(wù)器集群可以使用nginx做反向代理。并且多臺(tái)服務(wù)器可以平均分擔(dān)負(fù)載,不會(huì)應(yīng)為某臺(tái)服務(wù)器負(fù)載高宕機(jī)而某臺(tái)服務(wù)器閑置的情況。 nginz 中也可以配置安全管理、比如可以使用Nginx搭建API接口網(wǎng)關(guān),對(duì)每個(gè)接口服務(wù)進(jìn)行攔截。
Nginx怎么處理請(qǐng)求的?
server?{?????????#?第一個(gè)Server區(qū)塊開始,表示一個(gè)獨(dú)立的虛擬主機(jī)站點(diǎn)
?? listen ????? 80;?#?提供服務(wù)的端口,默認(rèn)80
???server_name??localhost;?#?提供服務(wù)的域名主機(jī)名
???location?/?{?#?第一個(gè)location區(qū)塊開始
?????root???html;?#?站點(diǎn)的根目錄,相當(dāng)于Nginx的安裝目錄
?????index??index.html?index.html;??#?默認(rèn)的首頁文件,多個(gè)用空格分開
}?#?第一個(gè)location區(qū)塊結(jié)果
首先,Nginx 在啟動(dòng)時(shí),會(huì)解析配置文件,得到需要監(jiān)聽的端口與 IP 地址,然后在 Nginx 的 Master 進(jìn)程里面先初始化好這個(gè)監(jiān)控的Socket(創(chuàng)建 S ocket,設(shè)置 addr、reuse 等選項(xiàng),綁定到指定的 ip 地址端口,再 listen 監(jiān)聽)。 然后,再 fork(一個(gè)現(xiàn)有進(jìn)程可以調(diào)用 fork 函數(shù)創(chuàng)建一個(gè)新進(jìn)程。由 fork 創(chuàng)建的新進(jìn)程被稱為子進(jìn)程 )出多個(gè)子進(jìn)程出來。 之后,子進(jìn)程會(huì)競(jìng)爭(zhēng) accept 新的連接。此時(shí),客戶端就可以向 nginx 發(fā)起連接了。當(dāng)客戶端與nginx進(jìn)行三次握手,與 nginx 建立好一個(gè)連接后。此時(shí),某一個(gè)子進(jìn)程會(huì) accept 成功,得到這個(gè)建立好的連接的 Socket ,然后創(chuàng)建 nginx 對(duì)連接的封裝,即 ngx_connection_t 結(jié)構(gòu)體。 接著,設(shè)置讀寫事件處理函數(shù),并添加讀寫事件來與客戶端進(jìn)行數(shù)據(jù)的交換。 最后,Nginx 或客戶端來主動(dòng)關(guān)掉連接,到此,一個(gè)連接就壽終正寢了。
Nginx 是如何實(shí)現(xiàn)高并發(fā)的?
如果一個(gè) server 采用一個(gè)進(jìn)程(或者線程)負(fù)責(zé)一個(gè)request的方式,那么進(jìn)程數(shù)就是并發(fā)數(shù)。那么顯而易見的,就是會(huì)有很多進(jìn)程在等待中。等什么?最多的應(yīng)該是等待網(wǎng)絡(luò)傳輸。
而 Nginx 的異步非阻塞工作方式正是利用了這點(diǎn)等待的時(shí)間。在需要等待的時(shí)候,這些進(jìn)程就空閑出來待命了。因此表現(xiàn)為少數(shù)幾個(gè)進(jìn)程就解決了大量的并發(fā)問題。
Nginx是如何利用的呢,簡(jiǎn)單來說:同樣的 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)?4 個(gè)進(jìn)程都沒干完活呢,因此,一般有個(gè)調(diào)度進(jìn)程,每當(dāng)新進(jìn)來了一個(gè) request ,就新開個(gè)進(jìn)程來處理。
回想下,BIO 是不是存在醬紫的問題?
Nginx 不這樣,每進(jìn)來一個(gè) request ,會(huì)有一個(gè) worker 進(jìn)程去處理。但不是全程的處理,處理到什么程度呢?處理到可能發(fā)生阻塞的地方,比如向上游(后端)服務(wù)器轉(zhuǎn)發(fā) request ,并等待請(qǐng)求返回。那么,這個(gè)處理的 worker 不會(huì)這么傻等著,他會(huì)在發(fā)送完請(qǐng)求后,注冊(cè)一個(gè)事件:“如果 upstream 返回了,告訴我一聲,我再接著干”。于是他就休息去了。此時(shí),如果再有 request 進(jìn)來,他就可以很快再按這種方式處理。而一旦上游服務(wù)器返回了,就會(huì)觸發(fā)這個(gè)事件,worker 才會(huì)來接手,這個(gè) request 才會(huì)接著往下走。
這就是為什么說,Nginx 基于事件模型。
由于 web server 的工作性質(zhì)決定了每個(gè) request 的大部份生命都是在網(wǎng)絡(luò)傳輸中,實(shí)際上花費(fèi)在 server 機(jī)器上的時(shí)間片不多。這是幾個(gè)進(jìn)程就解決高并發(fā)的秘密所在。即:
webserver 剛好屬于網(wǎng)絡(luò) IO 密集型應(yīng)用,不算是計(jì)算密集型。
異步,非阻塞,使用 epoll ,和大量細(xì)節(jié)處的優(yōu)化。也正是 Nginx 之所以然的技術(shù)基石。
什么是正向代理?
一個(gè)位于客戶端和原始服務(wù)器(origin server)之間的服務(wù)器,為了從原始服務(wù)器取得內(nèi)容,客戶端向代理發(fā)送一個(gè)請(qǐng)求并指定目標(biāo)(原始服務(wù)器),然后代理向原始服務(wù)器轉(zhuǎn)交請(qǐng)求并將獲得的內(nèi)容返回給客戶端。
客戶端才能使用正向代理。正向代理總結(jié)就一句話:代理端代理的是客戶端。例如說:我們使用的OpenVPN 等等。
什么是反向代理?
反向代理(Reverse Proxy)方式,是指以代理服務(wù)器來接受 Internet上的連接請(qǐng)求,然后將請(qǐng)求,發(fā)給內(nèi)部網(wǎng)絡(luò)上的服務(wù)器并將從服務(wù)器上得到的結(jié)果返回給 Internet 上請(qǐng)求連接的客戶端,此時(shí)代理服務(wù)器對(duì)外就表現(xiàn)為一個(gè)反向代理服務(wù)器。
反向代理總結(jié)就一句話:代理端代理的是服務(wù)端。
反向代理服務(wù)器的優(yōu)點(diǎn)是什么?
反向代理服務(wù)器可以隱藏源服務(wù)器的存在和特征。它充當(dāng)互聯(lián)網(wǎng)云和web服務(wù)器之間的中間層。這對(duì)于安全方面來說是很好的,特別是當(dāng)您使用web托管服務(wù)時(shí)。
Nginx目錄結(jié)構(gòu)有哪些?
tree?/usr/local/nginx
/usr/local/nginx
├──?client_body_temp
├──?conf?????????????????????????????#?Nginx所有配置文件的目錄
│???├──?fastcgi.conf?????????????????#?fastcgi相關(guān)參數(shù)的配置文件
│???├──?fastcgi.conf.default?????????#?fastcgi.conf的原始備份文件
│???├──?fastcgi_params???????????????#?fastcgi的參數(shù)文件
│???├──?fastcgi_params.default???????
│???├──?koi-utf
│???├──?koi-win
│???├──?mime.types???????????????????#?媒體類型
│???├──?mime.types.default
│???├──?nginx.conf???????????????????#?Nginx主配置文件
│???├──?nginx.conf.default
│???├──?scgi_params??????????????????#?scgi相關(guān)參數(shù)文件
│???├──?scgi_params.default??
│???├──?uwsgi_params?????????????????#?uwsgi相關(guān)參數(shù)文件
│???├──?uwsgi_params.default
│???└──?win-utf
├──?fastcgi_temp?????????????????????#?fastcgi臨時(shí)數(shù)據(jù)目錄
├──?html?????????????????????????????#?Nginx默認(rèn)站點(diǎn)目錄
│???├──?50x.html?????????????????????#?錯(cuò)誤頁面優(yōu)雅替代顯示文件,例如當(dāng)出現(xiàn)502錯(cuò)誤時(shí)會(huì)調(diào)用此頁面
│???└──?index.html???????????????????#?默認(rèn)的首頁文件
├──?logs?????????????????????????????#?Nginx日志目錄
│???├──?access.log???????????????????#?訪問日志文件
│???├──?error.log????????????????????#?錯(cuò)誤日志文件
│???└──?nginx.pid????????????????????#?pid文件,Nginx進(jìn)程啟動(dòng)后,會(huì)把所有進(jìn)程的ID號(hào)寫到此文件
├──?proxy_temp???????????????????????#?臨時(shí)目錄
├──?sbin?????????????????????????????#?Nginx命令目錄
│???└──?nginx????????????????????????#?Nginx的啟動(dòng)命令
├──?scgi_temp????????????????????????#?臨時(shí)目錄
└──?uwsgi_temp???????????????????????#?臨時(shí)目錄
Nginx配置文件nginx.conf有哪些屬性模塊?
worker_processes 1;????????????????????????????????????#?worker進(jìn)程的數(shù)量
events?{??????????????????????????????????????????????????#?事件區(qū)塊開始
??? worker_connections 1024;????????????????????????????#?每個(gè)worker進(jìn)程支持的最大連接數(shù)
}????????????????????????????????????????????????????????#?事件區(qū)塊結(jié)束
http?{???????????????????????????????????????????????????#?HTTP區(qū)塊開始
??? include ????? mime.types;????????????????????????????#?Nginx支持的媒體類型庫(kù)文件
??? default_type application/octet-stream;?????????????#?默認(rèn)的媒體類型
??? sendfile ?????? on;???????????????????????????????????#?開啟高效傳輸模式
??? keepalive_timeout 65;???????????????????????????????#?連接超時(shí)
????server?{????????????????????????????????????????????#?第一個(gè)Server區(qū)塊開始,表示一個(gè)獨(dú)立的虛擬主機(jī)站點(diǎn)
??????? listen ????? 80;??????????????????????????????????#?提供服務(wù)的端口,默認(rèn)80
??????? server_name localhost;???????????????????????????#?提供服務(wù)的域名主機(jī)名
????????location?/?{????????????????????????????????????#?第一個(gè)location區(qū)塊開始
??????????? root ? html;???????????????????????????????#?站點(diǎn)的根目錄,相當(dāng)于Nginx的安裝目錄
??????????? index index.html index.htm;??????????????????#?默認(rèn)的首頁文件,多個(gè)用空格分開
????????}??????????????????????????????????????????????????#?第一個(gè)location區(qū)塊結(jié)果
??????? error_page ? 500502503504 ?/50x.html;?????????????#?出現(xiàn)對(duì)應(yīng)的http狀態(tài)碼時(shí),使用50x.html回應(yīng)客戶
????????location?=?/50x.html?{??????????????????????????#?location區(qū)塊開始,訪問50x.html
??????????? root ? html;??????????????????????????????????#?指定對(duì)應(yīng)的站點(diǎn)目錄為html
????????}
????}??
????......
cookie和session區(qū)別?
共同:
存放用戶信息。存放的形式:key-value格式 變量和變量?jī)?nèi)容鍵值對(duì)。
區(qū)別:
cookie
存放在客戶端瀏覽器 每個(gè)域名對(duì)應(yīng)一個(gè)cookie,不能跨躍域名訪問其他cookie 用戶可以查看或修改cookie http響應(yīng)報(bào)文里面給你瀏覽器設(shè)置 鑰匙(用于打開瀏覽器上鎖頭)
session:
存放在服務(wù)器(文件,數(shù)據(jù)庫(kù),redis) 存放敏感信息 鎖頭
為什么 Nginx 不使用多線程?
Apache:?創(chuàng)建多個(gè)進(jìn)程或線程,而每個(gè)進(jìn)程或線程都會(huì)為其分配 cpu 和內(nèi)存(線程要比進(jìn)程小的多,所以 worker 支持比 perfork 高的并發(fā)),并發(fā)過大會(huì)榨干服務(wù)器資源。
Nginx:?采用單線程來異步非阻塞處理請(qǐng)求(管理員可以配置 Nginx 主進(jìn)程的工作進(jìn)程的數(shù)量)(epoll),不會(huì)為每個(gè)請(qǐng)求分配 cpu 和內(nèi)存資源,節(jié)省了大量資源,同時(shí)也減少了大量的 CPU 的上下文切換。所以才使得 Nginx 支持更高的并發(fā)。
nginx和apache的區(qū)別
輕量級(jí),同樣起web服務(wù),比apache占用更少的內(nèi)存和資源。
抗并發(fā),nginx處理請(qǐng)求是異步非阻塞的,而apache則是阻塞性的,在高并發(fā)下nginx能保持低資源,低消耗高性能。
高度模塊化的設(shè)計(jì),編寫模塊相對(duì)簡(jiǎn)單。
最核心的區(qū)別在于apache是同步多進(jìn)程模型,一個(gè)連接對(duì)應(yīng)一個(gè)進(jìn)程,nginx是異步的,多個(gè)連接可以對(duì)應(yīng)一個(gè)進(jìn)程。

什么是動(dòng)態(tài)資源、靜態(tài)資源分離?
動(dòng)態(tài)資源、靜態(tài)資源分離,是讓動(dòng)態(tài)網(wǎng)站里的動(dòng)態(tài)網(wǎng)頁根據(jù)一定規(guī)則把不變的資源和經(jīng)常變的資源區(qū)分開來,動(dòng)靜資源做好了拆分以后我們就可以根據(jù)靜態(tài)資源的特點(diǎn)將其做緩存操作,這就是網(wǎng)站靜態(tài)化處理的核心思路。
動(dòng)態(tài)資源、靜態(tài)資源分離簡(jiǎn)單的概括是:動(dòng)態(tài)文件與靜態(tài)文件的分離。
為什么要做動(dòng)、靜分離?
在我們的軟件開發(fā)中,有些請(qǐng)求是需要后臺(tái)處理的(如:.jsp,.do 等等),有些請(qǐng)求是不需要經(jīng)過后臺(tái)處理的(如:css、html、jpg、js 等等文件),這些不需要經(jīng)過后臺(tái)處理的文件稱為靜態(tài)文件,否則動(dòng)態(tài)文件。
因此我們后臺(tái)處理忽略靜態(tài)文件。這會(huì)有人又說那我后臺(tái)忽略靜態(tài)文件不就完了嗎?當(dāng)然這是可以的,但是這樣后臺(tái)的請(qǐng)求次數(shù)就明顯增多了。在我們對(duì)資源的響應(yīng)速度有要求的時(shí)候,我們應(yīng)該使用這種動(dòng)靜分離的策略去解決動(dòng)、靜分離將網(wǎng)站靜態(tài)資源(HTML,JavaScript,CSS,img等文件)與后臺(tái)應(yīng)用分開部署,提高用戶訪問靜態(tài)代碼的速度,降低對(duì)后臺(tái)應(yīng)用訪問
這里我們將靜態(tài)資源放到 Nginx 中,動(dòng)態(tài)資源轉(zhuǎn)發(fā)到 Tomcat 服務(wù)器中去。
當(dāng)然,因?yàn)楝F(xiàn)在七牛、阿里云等 CDN 服務(wù)已經(jīng)很成熟,主流的做法,是把靜態(tài)資源緩存到 CDN 服務(wù)中,從而提升訪問速度。
相比本地的 Nginx 來說,CDN 服務(wù)器由于在國(guó)內(nèi)有更多的節(jié)點(diǎn),可以實(shí)現(xiàn)用戶的就近訪問。并且,CDN 服務(wù)可以提供更大的帶寬,不像我們自己的應(yīng)用服務(wù),提供的帶寬是有限的。
什么叫 CDN 服務(wù)?
CDN ,即內(nèi)容分發(fā)網(wǎng)絡(luò)。
其目的是,通過在現(xiàn)有的 Internet中 增加一層新的網(wǎng)絡(luò)架構(gòu),將網(wǎng)站的內(nèi)容發(fā)布到最接近用戶的網(wǎng)絡(luò)邊緣,使用戶可就近取得所需的內(nèi)容,提高用戶訪問網(wǎng)站的速度。
一般來說,因?yàn)楝F(xiàn)在 CDN 服務(wù)比較大眾,所以基本所有公司都會(huì)使用 CDN 服務(wù)。
Nginx怎么做的動(dòng)靜分離?
只需要指定路徑對(duì)應(yīng)的目錄。location/可以使用正則表達(dá)式匹配。并指定對(duì)應(yīng)的硬盤中的目錄。如下:(操作都是在Linux上)
location?/image/?{
????root???/usr/local/static/;
????autoindex?on;
}
步驟:
#?創(chuàng)建目錄
mkdir?/usr/local/static/image
?
#?進(jìn)入目錄
cd??/usr/local/static/image
?
#?上傳照片
photo.jpg
?
#?重啟nginx
sudo?nginx?-s?reload
打開瀏覽器 輸入?server_name/image/1.jpg?就可以訪問該靜態(tài)圖片了
Nginx負(fù)載均衡的算法怎么實(shí)現(xiàn)的?策略有哪些?
為了避免服務(wù)器崩潰,大家會(huì)通過負(fù)載均衡的方式來分擔(dān)服務(wù)器壓力。將對(duì)臺(tái)服務(wù)器組成一個(gè)集群,當(dāng)用戶訪問時(shí),先訪問到一個(gè)轉(zhuǎn)發(fā)服務(wù)器,再由轉(zhuǎn)發(fā)服務(wù)器將訪問分發(fā)到壓力更小的服務(wù)器。
Nginx負(fù)載均衡實(shí)現(xiàn)的策略有以下五種:
1 .輪詢(默認(rèn))
每個(gè)請(qǐng)求按時(shí)間順序逐一分配到不同的后端服務(wù)器,如果后端某個(gè)服務(wù)器宕機(jī),能自動(dòng)剔除故障系統(tǒng)。
upstream?backserver?{?
?server?192.168.0.12;?
?server?192.168.0.13;?
}?
2. 權(quán)重 weight
weight的值越大,分配到的訪問概率越高,主要用于后端每臺(tái)服務(wù)器性能不均衡的情況下。其次是為在主從的情況下設(shè)置不同的權(quán)值,達(dá)到合理有效的地利用主機(jī)資源。
#?權(quán)重越高,在被訪問的概率越大,如上例,分別是20%,80%。
upstream?backserver?{?
?server?192.168.0.12?weight=2;?
?server?192.168.0.13?weight=8;?
}?
3. ip_hash( IP綁定)
每個(gè)請(qǐng)求按訪問IP的哈希結(jié)果分配,使來自同一個(gè)IP的訪客固定訪問一臺(tái)后端服務(wù)器,并且可以有效解決動(dòng)態(tài)網(wǎng)頁存在的session共享問題
upstream?backserver?{?
?ip_hash;?
?server?192.168.0.12:88;?
?server?192.168.0.13:80;?
}?
4. fair(第三方插件)
必須安裝upstream_fair模塊。
對(duì)比 weight、ip_hash更加智能的負(fù)載均衡算法,fair算法可以根據(jù)頁面大小和加載時(shí)間長(zhǎng)短智能地進(jìn)行負(fù)載均衡,響應(yīng)時(shí)間短的優(yōu)先分配。
#?哪個(gè)服務(wù)器的響應(yīng)速度快,就將請(qǐng)求分配到那個(gè)服務(wù)器上。
upstream?backserver?{?
?server?server1;?
?server?server2;?
?fair;?
}?
5.url_hash(第三方插件)
必須安裝Nginx的hash軟件包
按訪問url的hash結(jié)果來分配請(qǐng)求,使每個(gè)url定向到同一個(gè)后端服務(wù)器,可以進(jìn)一步提高后端緩存服務(wù)器的效率。
upstream?backserver?{?
?server?squid1:3128;?
?server?squid2:3128;?
?hash?$request_uri;?
?hash_method?crc32;?
}
如何用Nginx解決前端跨域問題?
使用Nginx轉(zhuǎn)發(fā)請(qǐng)求。把跨域的接口寫成調(diào)本域的接口,然后將這些接口轉(zhuǎn)發(fā)到真正的請(qǐng)求地址。
Nginx虛擬主機(jī)怎么配置?
1、基于域名的虛擬主機(jī),通過域名來區(qū)分虛擬主機(jī)——應(yīng)用:外部網(wǎng)站
2、基于端口的虛擬主機(jī),通過端口來區(qū)分虛擬主機(jī)——應(yīng)用:公司內(nèi)部網(wǎng)站,外部網(wǎng)站的管理后臺(tái)
3、基于ip的虛擬主機(jī)。
基于虛擬主機(jī)配置域名
需要建立/data/www /data/bbs目錄,windows本地hosts添加虛擬機(jī)ip地址對(duì)應(yīng)的域名解析;對(duì)應(yīng)域名網(wǎng)站目錄下新增index.html文件;
#?當(dāng)客戶端訪問www.lijie.com,監(jiān)聽端口號(hào)為80,直接跳轉(zhuǎn)到data/www目錄下文件
server?{
????listen???????80;
????server_name??www.lijie.com;
????location?/?{
????????root???data/www;
????????index??index.html?index.htm;
????}
}
#?當(dāng)客戶端訪問www.lijie.com,監(jiān)聽端口號(hào)為80,直接跳轉(zhuǎn)到data/bbs目錄下文件
?server?{
????listen???????80;
????server_name??bbs.lijie.com;
????location?/?{
????????root???data/bbs;
????????index??index.html?index.htm;
????}
}
基于端口的虛擬主機(jī)
使用端口來區(qū)分,瀏覽器使用域名或ip地址:端口號(hào) 訪問
#?當(dāng)客戶端訪問www.lijie.com,監(jiān)聽端口號(hào)為8080,直接跳轉(zhuǎn)到data/www目錄下文件
?server?{
????listen???????8080;
????server_name??8080.lijie.com;
????location?/?{
????????root???data/www;
????????index??index.html?index.htm;
????}
}
#?當(dāng)客戶端訪問www.lijie.com,監(jiān)聽端口號(hào)為80直接跳轉(zhuǎn)到真實(shí)ip服務(wù)器地址?127.0.0.1:8080
server?{
????listen???????80;
????server_name??www.lijie.com;
????location?/?{
?????????proxy_pass?http://127.0.0.1:8080;
????????index??index.html?index.htm;
????}
}
location的作用是什么?
location指令的作用是根據(jù)用戶請(qǐng)求的URI來執(zhí)行不同的應(yīng)用,也就是根據(jù)用戶請(qǐng)求的網(wǎng)站URL進(jìn)行匹配,匹配成功即進(jìn)行相關(guān)的操作。
location的語法能說出來嗎?
注意:~ 代表自己輸入的英文字母

Location正則案例
#?優(yōu)先級(jí)1,精確匹配,根路徑
location?=/?{
????return?400;
}
#?優(yōu)先級(jí)2,以某個(gè)字符串開頭,以av開頭的,優(yōu)先匹配這里,區(qū)分大小寫
location?^~?/av?{
???root?/data/av/;
}
#?優(yōu)先級(jí)3,區(qū)分大小寫的正則匹配,匹配/media*****路徑
location?~?/media?{
??????alias?/data/static/;
}
#?優(yōu)先級(jí)4?,不區(qū)分大小寫的正則匹配,所有的****.jpg|gif|png?都走這里
location?~*?.*\.(jpg|gif|png|js|css)$?{
???root??/data/av/;
}
#?優(yōu)先7,通用匹配
location?/?{
????return?403;
}
限流怎么做的?
Nginx限流就是限制用戶請(qǐng)求速度,防止服務(wù)器受不了
限流有3種
正常限制訪問頻率(正常流量) 突發(fā)限制訪問頻率(突發(fā)流量) 限制并發(fā)連接數(shù)
Nginx的限流都是基于漏桶流算法
實(shí)現(xiàn)三種限流算法
1、正常限制訪問頻率(正常流量):
限制一個(gè)用戶發(fā)送的請(qǐng)求,我Nginx多久接收一個(gè)請(qǐng)求。
Nginx中使用ngx_http_limit_req_module模塊來限制的訪問頻率,限制的原理實(shí)質(zhì)是基于漏桶算法原理來實(shí)現(xiàn)的。在nginx.conf配置文件中可以使用limit_req_zone命令及limit_req命令限制單個(gè)IP的請(qǐng)求處理頻率。
#?定義限流維度,一個(gè)用戶一分鐘一個(gè)請(qǐng)求進(jìn)來,多余的全部漏掉
limit_req_zone?$binary_remote_addr?zone=one:10m?rate=1r/m;
#?綁定限流維度
server{
????
????location/seckill.html{
????????limit_req?zone=zone;????
????????proxy_pass?http://lj_seckill;
????}
}
1r/s代表1秒一個(gè)請(qǐng)求,1r/m一分鐘接收一個(gè)請(qǐng)求, 如果Nginx這時(shí)還有別人的請(qǐng)求沒有處理完,Nginx就會(huì)拒絕處理該用戶請(qǐng)求。
2、突發(fā)限制訪問頻率(突發(fā)流量):
限制一個(gè)用戶發(fā)送的請(qǐng)求,我Nginx多久接收一個(gè)。
上面的配置一定程度可以限制訪問頻率,但是也存在著一個(gè)問題:如果突發(fā)流量超出請(qǐng)求被拒絕處理,無法處理活動(dòng)時(shí)候的突發(fā)流量,這時(shí)候應(yīng)該如何進(jìn)一步處理呢?
Nginx提供burst參數(shù)結(jié)合nodelay參數(shù)可以解決流量突發(fā)的問題,可以設(shè)置能處理的超過設(shè)置的請(qǐng)求數(shù)外能額外處理的請(qǐng)求數(shù)。我們可以將之前的例子添加burst參數(shù)以及nodelay參數(shù):
#?定義限流維度,一個(gè)用戶一分鐘一個(gè)請(qǐng)求進(jìn)來,多余的全部漏掉
limit_req_zone?$binary_remote_addr?zone=one:10m?rate=1r/m;
#?綁定限流維度
server{
????
????location/seckill.html{
????????limit_req?zone=zone?burst=5?nodelay;
????????proxy_pass?http://lj_seckill;
????}
}
為什么就多了一個(gè) burst=5 nodelay; 呢,多了這個(gè)可以代表Nginx對(duì)于一個(gè)用戶的請(qǐng)求會(huì)立即處理前五個(gè),多余的就慢慢來落,沒有其他用戶的請(qǐng)求我就處理你的,有其他的請(qǐng)求的話我Nginx就漏掉不接受你的請(qǐng)求
3、 限制并發(fā)連接數(shù)
Nginx中的ngx_http_limit_conn_module模塊提供了限制并發(fā)連接數(shù)的功能,可以使用limit_conn_zone指令以及limit_conn執(zhí)行進(jìn)行配置。接下來我們可以通過一個(gè)簡(jiǎn)單的例子來看下:
http?{
????limit_conn_zone?$binary_remote_addr?zone=myip:10m;
????limit_conn_zone?$server_name?zone=myServerName:10m;
}
server?{
????location?/?{
????????limit_conn?myip?10;
????????limit_conn?myServerName?100;
????????rewrite?/?http://www.lijie.net?permanent;
????}
}?
上面配置了單個(gè)IP同時(shí)并發(fā)連接數(shù)最多只能10個(gè)連接,并且設(shè)置了整個(gè)虛擬服務(wù)器同時(shí)最大并發(fā)數(shù)最多只能100個(gè)鏈接。當(dāng)然,只有當(dāng)請(qǐng)求的header被服務(wù)器處理后,虛擬服務(wù)器的連接數(shù)才會(huì)計(jì)數(shù)。剛才有提到過Nginx是基于漏桶算法原理實(shí)現(xiàn)的,實(shí)際上限流一般都是基于漏桶算法和令牌桶算法實(shí)現(xiàn)的。
漏桶流算法和令牌桶算法知道?
漏桶算法
漏桶算法思路很簡(jiǎn)單,我們把水比作是請(qǐng)求,漏桶比作是系統(tǒng)處理能力極限,水先進(jìn)入到漏桶里,漏桶里的水按一定速率流出,當(dāng)流出的速率小于流入的速率時(shí),由于漏桶容量有限,后續(xù)進(jìn)入的水直接溢出(拒絕請(qǐng)求),以此實(shí)現(xiàn)限流。

令牌桶算法
令牌桶算法的原理也比較簡(jiǎn)單,我們可以理解成醫(yī)院的掛號(hào)看病,只有拿到號(hào)以后才可以進(jìn)行診病。
系統(tǒng)會(huì)維護(hù)一個(gè)令牌(token)桶,以一個(gè)恒定的速度往桶里放入令牌(token),這時(shí)如果有請(qǐng)求進(jìn)來想要被處理,則需要先從桶里獲取一個(gè)令牌(token),當(dāng)桶里沒有令牌(token)可取時(shí),則該請(qǐng)求將被拒絕服務(wù)。令牌桶算法通過控制桶的容量、發(fā)放令牌的速率,來達(dá)到對(duì)請(qǐng)求的限制。

Nginx配置高可用性怎么配置?
當(dāng)上游服務(wù)器(真實(shí)訪問服務(wù)器),一旦出現(xiàn)故障或者是沒有及時(shí)相應(yīng)的話,應(yīng)該直接輪訓(xùn)到下一臺(tái)服務(wù)器,保證服務(wù)器的高可用
Nginx配置代碼:
server?{
????????listen???????80;
????????server_name??www.lijie.com;
????????location?/?{
????????????###?指定上游服務(wù)器負(fù)載均衡服務(wù)器
????????????proxy_pass?http://backServer;
????????????###nginx與上游服務(wù)器(真實(shí)訪問的服務(wù)器)超時(shí)時(shí)間?后端服務(wù)器連接的超時(shí)時(shí)間_發(fā)起握手等候響應(yīng)超時(shí)時(shí)間
????????????proxy_connect_timeout?1s;
????????????###nginx發(fā)送給上游服務(wù)器(真實(shí)訪問的服務(wù)器)超時(shí)時(shí)間
????????????proxy_send_timeout?1s;
????????????###?nginx接受上游服務(wù)器(真實(shí)訪問的服務(wù)器)超時(shí)時(shí)間
????????????proxy_read_timeout?1s;
????????????index??index.html?index.htm;
????????}
????}
Nginx怎么判斷別IP不可訪問?
??#?如果訪問的ip地址為192.168.9.115,則返回403
?if??($remote_addr?=?192.168.9.115)?{??
?????return?403;??
?}??
在nginx中,如何使用未定義的服務(wù)器名稱來阻止處理請(qǐng)求?
只需將請(qǐng)求刪除的服務(wù)器就可以定義為:
服務(wù)器名被保留一個(gè)空字符串,他在沒有主機(jī)頭字段的情況下匹配請(qǐng)求,而一個(gè)特殊的nginx的非標(biāo)準(zhǔn)代碼被返回,從而終止連接。
怎么限制瀏覽器訪問?
##?不允許谷歌瀏覽器訪問?如果是谷歌瀏覽器返回500
if?($http_user_agent?~?Chrome)?{???
??return?500;??
}
Rewrite全局變量是什么?
$remote_addr????????//獲取客戶端ip
$binary_remote_addr?//客戶端ip(二進(jìn)制)
$remote_port????????//客戶端port,如:50472
$remote_user????????//已經(jīng)經(jīng)過Auth?Basic?Module驗(yàn)證的用戶名
$host???????????//請(qǐng)求主機(jī)頭字段,否則為服務(wù)器名稱,如:blog.sakmon.com
$request????????//用戶請(qǐng)求信息,如:GET ?a=1&b=2 HTTP/1.1
$request_filename???//當(dāng)前請(qǐng)求的文件的路徑名,由root或alias和URI request組合而成,如:/2013/81.html
$status?????????//請(qǐng)求的響應(yīng)狀態(tài)碼,如:200
$body_bytes_sent????????//?響應(yīng)時(shí)送出的body字節(jié)數(shù)數(shù)量。即使連接中斷,這個(gè)數(shù)據(jù)也是精確的,如:40
$content_length????????//?等于請(qǐng)求行的“Content_Length”的值
$content_type??????????//?等于請(qǐng)求行的“Content_Type”的值
$http_referer??????????//?引用地址
$http_user_agent??????//?客戶端agent信息,如:Mozilla/5.0?(Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.76 Safari/537.36
$args????????????//與$query_string相同?等于當(dāng)中URL的參數(shù)(GET),如a=1&b=2
$document_uri????????//與$uri相同??這個(gè)變量指當(dāng)前的請(qǐng)求URI,不包括任何參數(shù)(見$args)?如:/2013/81.html
$document_root???????//針對(duì)當(dāng)前請(qǐng)求的根路徑設(shè)置值
$hostname????????//如:centos53.localdomain
$http_cookie????????//客戶端cookie信息
$cookie_COOKIE??????//cookie?COOKIE變量的值
$is_args????//如果有$args參數(shù),這個(gè)變量等于”?”,否則等于”",空值,如?
$limit_rate?//這個(gè)變量可以限制連接速率,0表示不限速
$query_string???????//?與$args相同?等于當(dāng)中URL的參數(shù)(GET),如a=1&b=2
$request_body??????//?記錄POST過來的數(shù)據(jù)信息
$request_body_file??//客戶端請(qǐng)求主體信息的臨時(shí)文件名
$request_method???????//客戶端請(qǐng)求的動(dòng)作,通常為GET或POST,如:GET
$request_uri??????????//包含請(qǐng)求參數(shù)的原始URI,不包含主機(jī)名,如:/2013/81.html?a=1&b=2
$scheme????????????//HTTP方法(如http,https),如:http
$uri????????????//這個(gè)變量指當(dāng)前的請(qǐng)求URI,不包括任何參數(shù)(見$args)?如:/2013/81.html
$request_completion?//如果請(qǐng)求結(jié)束,設(shè)置為OK. 當(dāng)請(qǐng)求未結(jié)束或如果該請(qǐng)求不是請(qǐng)求鏈串的最后一個(gè)時(shí),為空(Empty),如:OK
$server_protocol????//請(qǐng)求使用的協(xié)議,通常是HTTP/1.0或HTTP/1.1,如:HTTP/1.1
$server_addr????????//服務(wù)器IP地址,在完成一次系統(tǒng)調(diào)用后可以確定這個(gè)值
$server_name????????//服務(wù)器名稱,如:blog.sakmon.com
$server_port????????//請(qǐng)求到達(dá)服務(wù)器的端口號(hào),如:80
Nginx 如何實(shí)現(xiàn)后端服務(wù)的健康檢查?
方式一,利用 nginx 自帶模塊?ngx_http_proxy_module?和?ngx_http_upstream_module?對(duì)后端節(jié)點(diǎn)做健康檢查。
方式二(推薦),利用?nginx_upstream_check_module?模塊對(duì)后端節(jié)點(diǎn)做健康檢查。
Nginx 如何開啟壓縮?
開啟nginx gzip壓縮后,網(wǎng)頁、css、js等靜態(tài)資源的大小會(huì)大大的減少,從而可以節(jié)約大量的帶寬,提高傳輸效率,給用戶快的體驗(yàn)。雖然會(huì)消耗cpu資源,但是為了給用戶更好的體驗(yàn)是值得的。
開啟的配置如下:
將以上配置放到nginx.conf的http{ … }節(jié)點(diǎn)中。
http?{
??#?開啟gzip
??gzip?on;
?
??#?啟用gzip壓縮的最小文件;小于設(shè)置值的文件將不會(huì)被壓縮
??gzip_min_length?1k;
?
??#?gzip?壓縮級(jí)別?1-10?
??gzip_comp_level?2;
?
??#?進(jìn)行壓縮的文件類型。
?
??gzip_types?text/plain?application/javascript?application/x-javascript?text/css?application/xml?text/javascript?application/x-httpd-php?image/jpeg?image/gif?image/png;
?
??#?是否在http?header中添加Vary:?Accept-Encoding,建議開啟
??gzip_vary?on;
}
保存并重啟nginx,刷新頁面(為了避免緩存,請(qǐng)強(qiáng)制刷新)就能看到效果了。以谷歌瀏覽器為例,通過F12看請(qǐng)求的響應(yīng)頭部:
我們可以先來對(duì)比下,如果我們沒有開啟zip壓縮之前,我們的對(duì)應(yīng)的文件大小,如下所示:

現(xiàn)在我們開啟了gzip進(jìn)行壓縮后的文件的大小,可以看到如下所示:

并且我們查看響應(yīng)頭會(huì)看到gzip這樣的壓縮,如下所示

gzip壓縮前后效果對(duì)比:jquery原大小90kb,壓縮后只有30kb。
gzip雖然好用,但是以下類型的資源不建議啟用。
1、圖片類型
原因:圖片如jpg、png本身就會(huì)有壓縮,所以就算開啟gzip后,壓縮前和壓縮后大小沒有多大區(qū)別,所以開啟了反而會(huì)白白的浪費(fèi)資源。(Tips:可以試試將一張jpg圖片壓縮為zip,觀察大小并沒有多大的變化。雖然zip和gzip算法不一樣,但是可以看出壓縮圖片的價(jià)值并不大)
2、大文件
原因:會(huì)消耗大量的cpu資源,且不一定有明顯的效果。
ngx_http_upstream_module的作用是什么?
ngx_http_upstream_module用于定義可通過fastcgi傳遞、proxy傳遞、uwsgi傳遞、memcached傳遞和scgi傳遞指令來引用的服務(wù)器組。
什么是C10K問題?
C10K問題是指無法同時(shí)處理大量客戶端(10,000)的網(wǎng)絡(luò)套接字。
Nginx是否支持將請(qǐng)求壓縮到上游?
您可以使用Nginx模塊gunzip將請(qǐng)求壓縮到上游。gunzip模塊是一個(gè)過濾器,它可以對(duì)不支持“gzip”編碼方法的客戶機(jī)或服務(wù)器使用“內(nèi)容編碼:gzip”來解壓縮響應(yīng)。
如何在Nginx中獲得當(dāng)前的時(shí)間?
要獲得Nginx的當(dāng)前時(shí)間,必須使用SSI模塊、和date_local的變量。
Proxy_set_header?THE-TIME?$date_gmt;
用Nginx服務(wù)器解釋-s的目的是什么?
用于運(yùn)行Nginx -s參數(shù)的可執(zhí)行文件。
如何在Nginx服務(wù)器上添加模塊?
在編譯過程中,必須選擇Nginx模塊,因?yàn)镹ginx不支持模塊的運(yùn)行時(shí)間選擇。
生產(chǎn)中如何設(shè)置worker進(jìn)程的數(shù)量呢?
在有多個(gè)cpu的情況下,可以設(shè)置多個(gè)worker,worker進(jìn)程的數(shù)量可以設(shè)置到和cpu的核心數(shù)一樣多,如果在單個(gè)cpu上起多個(gè)worker進(jìn)程,那么操作系統(tǒng)會(huì)在多個(gè)worker之間進(jìn)行調(diào)度,這種情況會(huì)降低系統(tǒng)性能,如果只有一個(gè)cpu,那么只啟動(dòng)一個(gè)worker進(jìn)程就可以了。
nginx狀態(tài)碼
499:
服務(wù)端處理時(shí)間過長(zhǎng),客戶端主動(dòng)關(guān)閉了連接。
502:
(1).FastCGI進(jìn)程是否已經(jīng)啟動(dòng)
(2).FastCGI worker進(jìn)程數(shù)是否不夠
(3).FastCGI執(zhí)行時(shí)間過長(zhǎng)
fastcgi_connect_timeout 300; fastcgi_send_timeout 300; fastcgi_read_timeout 300;
(4).FastCGI Buffer不夠,nginx和apache一樣,有前端緩沖限制,可以調(diào)整緩沖參數(shù)
fastcgi_buffer_size 32k; fastcgi_buffers 8 32k;
(5). Proxy Buffer不夠,如果你用了Proxying,調(diào)整
proxy_buffer_size 16k; proxy_buffers 4 16k;
(6).php腳本執(zhí)行時(shí)間過長(zhǎng)
將php-fpm.conf的0s的0s改成一個(gè)時(shí)間

往期推薦



最后
歡迎加我微信,拉你進(jìn)技術(shù)群,長(zhǎng)期交流學(xué)習(xí)...
歡迎關(guān)注「前端Q」,認(rèn)真學(xué)前端,做個(gè)專業(yè)的技術(shù)人...


