【腾讯面试题】Nginx
什么是Nginx?
Nginx是一個(gè)輕量級(jí)/高性能的反向代理Web服務(wù)器,實(shí)現(xiàn)非常高效的反向代理、負(fù)載均衡,可以處理2-3萬(wàn)并發(fā)連接數(shù),官方監(jiān)測(cè)能支持5萬(wàn)并發(fā),現(xiàn)在中國(guó)使用Nginx網(wǎng)站有很多,例如:新浪,網(wǎng)易,騰訊等。
為什么要用Nginx?
- 跨平臺(tái)、配置簡(jiǎn)單、反向代理、高并發(fā)連接:處理2-3萬(wàn)并發(fā)連接數(shù),官方檢測(cè)能支持5萬(wàn)并發(fā),內(nèi)存消耗少:開(kāi)啟10個(gè)Nginx才占150M內(nèi)存,nginx處理靜態(tài)文件好,耗費(fèi)內(nèi)存少。
- Nginx內(nèi)置的健康檢查功能:如果有一個(gè)服務(wù)器宕機(jī),會(huì)做一個(gè)健康檢查,再發(fā)送請(qǐng)求就不會(huì)發(fā)送到宕機(jī)的服務(wù)器了,而是重新將請(qǐng)求提交到其他節(jié)點(diǎn)上。
- 使用Nginx的話還能:
- 節(jié)省寬帶:支持GZIP壓縮,可以添加瀏覽器本地緩存
- 穩(wěn)定性高:宕機(jī)的概率非常小
- 接受用戶請(qǐng)求是異步的
為什么Nginx性能這么高?
Nginx事件處理機(jī)制:異步非阻塞事件處理機(jī)制,運(yùn)用了epoll模型,提供了一個(gè)隊(duì)列,排隊(duì)解決
Nginx怎么處理請(qǐng)求?
Nginx接收一個(gè)請(qǐng)求后,首先由listen和server_name指令匹配server模塊,再匹配server模塊里的location,location就是實(shí)際地址。
server { # 第一個(gè)Server區(qū)塊開(kāi)始,表示一個(gè)獨(dú)立的虛擬主機(jī)站點(diǎn)listen 80; # 提供服務(wù)的端口,默認(rèn)80server_name localhost; # 提供服務(wù)的域名主機(jī)名location / { # 第一個(gè)location區(qū)塊開(kāi)始root html; # 站點(diǎn)的根目錄,相當(dāng)于Nginx的安裝目錄index index.html index.htm; # 默認(rèn)的首頁(yè)文件,多個(gè)用空格分開(kāi)} # 第一個(gè)location區(qū)塊結(jié)果正向代理和反向代理
- 正向代理就是一個(gè)人發(fā)送一個(gè)請(qǐng)求直接就到達(dá)了目標(biāo)的服務(wù)器
- 反方代理就是請(qǐng)求統(tǒng)一被Nginx接收,nginx反向代理服務(wù)器接收到之后,按照一定的規(guī) 則分發(fā)給了后端的業(yè)務(wù)處理服務(wù)器進(jìn)行處理了
使用反向代理服務(wù)器的優(yōu)點(diǎn)是什么
反向代理服務(wù)器可以隱藏源服務(wù)器的存在和特征。它充當(dāng)互聯(lián)網(wǎng)云和web服務(wù)器之間的中間層。這對(duì)于安全方面來(lái)說(shuō)是很好的,特別是當(dāng)您使用web托管服務(wù)時(shí)。
Nginx的優(yōu)缺點(diǎn)?
-
優(yōu)點(diǎn)
- 內(nèi)存占用少,可實(shí)現(xiàn)高并發(fā)連接,處理響應(yīng)快
- 可實(shí)現(xiàn)Http服務(wù)器、虛擬主機(jī)、反向代理、負(fù)載均衡
- 配置簡(jiǎn)單
- 可以不暴露正式的服務(wù)器IP地址
-
缺點(diǎn):動(dòng)態(tài)處理差,Nginx處理靜態(tài)文件較好,耗費(fèi)內(nèi)存小,但處理動(dòng)態(tài)頁(yè)面則很雞肋,現(xiàn)在一般前端用Nginx作為反向代理
Nginx應(yīng)用場(chǎng)景
Nginx目錄結(jié)構(gòu)有哪些?
[root@localhost ~]# 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è)面優(yōu)雅替代顯示文件,例如當(dāng)出現(xiàn)502錯(cuò)誤時(shí)會(huì)調(diào)用此頁(yè)面 │ └── index.html # 默認(rèn)的首頁(yè)文件 ├── logs # Nginx日志目錄 │ ├── access.log # 訪問(wèn)日志文件 │ ├── 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ū)塊開(kāi)始worker_connections 1024; # 每個(gè)worker進(jìn)程支持的最大連接數(shù) } # 事件區(qū)塊結(jié)束 http { # HTTP區(qū)塊開(kāi)始include mime.types; # Nginx支持的媒體類型庫(kù)文件default_type application/octet-stream; # 默認(rèn)的媒體類型sendfile on; # 開(kāi)啟高效傳輸模式keepalive_timeout 65; # 連接超時(shí)server { # 第一個(gè)Server區(qū)塊開(kāi)始,表示一個(gè)獨(dú)立的虛擬主機(jī)站點(diǎn)listen 80; # 提供服務(wù)的端口,默認(rèn)80server_name localhost; # 提供服務(wù)的域名主機(jī)名location / { # 第一個(gè)location區(qū)塊開(kāi)始root html; # 站點(diǎn)的根目錄,相當(dāng)于Nginx的安裝目錄index index.html index.htm; # 默認(rèn)的首頁(yè)文件,多個(gè)用空格分開(kāi)} # 第一個(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ū)塊開(kāi)始,訪問(wèn)50x.htmlroot html; # 指定對(duì)應(yīng)的站點(diǎn)目錄為html}} ......Nginx的靜態(tài)資源?
靜態(tài)資源訪問(wèn),就是存放在nginx的html頁(yè)面,我們可以自己編寫
如何利用Nginx解決前端跨域問(wèn)題?
使用Nginx轉(zhuǎn)發(fā)請(qǐng)求。把跨域的接口寫成調(diào)本域的接口,然后將這些接口轉(zhuǎn)發(fā)到真正的請(qǐng)求地址。
Nginx虛擬主機(jī)怎么配置?
1、基于域名的虛擬主機(jī),通過(guò)域名來(lái)區(qū)分虛擬主機(jī)——應(yīng)用:外部網(wǎng)站
2、基于端口的虛擬主機(jī),通過(guò)端口來(lái)區(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)客戶端訪問(wèn)www.lijie.com,監(jiān)聽(tīng)端口號(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)客戶端訪問(wèn)www.lijie.com,監(jiān)聽(tīng)端口號(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ī)
使用端口來(lái)區(qū)分,瀏覽器使用域名或ip地址:端口號(hào) 訪問(wèn)
#當(dāng)客戶端訪問(wèn)www.lijie.com,監(jiān)聽(tīng)端口號(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)客戶端訪問(wèn)www.lijie.com,監(jiān)聽(tīng)端口號(hào)為80直接跳轉(zhuǎn)到真實(shí)ip服務(wù)器地址 127.0.0.1:8080server {listen 80;server_name www.lijie.com;location / {proxy_pass http://127.0.0.1:8080;index index.html index.htm;}}Location正則案例
#優(yōu)先級(jí)1,精確匹配,根路徑location =/ {return 400;}#優(yōu)先級(jí)2,以某個(gè)字符串開(kāi)頭,以av開(kāi)頭的,優(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;}三種限流算法
1.正常限制訪問(wèn)頻率(正常流量)
- 限制一個(gè)用戶發(fā)送的請(qǐng)求,Nginx多久接收一個(gè)請(qǐng)求。
- Nginx中使用ngx_http_limit_req_module模塊來(lái)限制的訪問(wèn)頻率,限制的原理實(shí)質(zhì)是基于漏桶算法原理來(lái)實(shí)現(xiàn)的。在nginx.conf配置文件中可以使用limit_req_zone命令及l(fā)imit_req命令限制單個(gè)IP的請(qǐng)求處理頻率。
1r/s代表1秒一個(gè)請(qǐng)求,1r/m一分鐘接收一個(gè)請(qǐng)求, 如果Nginx這時(shí)還有別人的請(qǐng)求沒(méi)有處理完,Nginx就會(huì)拒絕處理該用戶請(qǐng)求。
2.突發(fā)限制訪問(wèn)頻率(突發(fā)流量)
- 限制一個(gè)用戶發(fā)送的請(qǐng)求,Nginx多久接收一個(gè)。
- 上面的配置一定程度可以限制訪問(wèn)頻率,但是也存在著一個(gè)問(wèn)題:如果突發(fā)流量超出請(qǐng)求被拒絕處理,無(wú)法處理活動(dòng)時(shí)候的突發(fā)流量,這時(shí)候應(yīng)該如何進(jìn)一步處理呢?Nginx提供burst參數(shù)結(jié)合nodelay參數(shù)可以解決流量突發(fā)的問(wèn)題,可以設(shè)置能處理的超過(guò)設(shè)置的請(qǐng)求數(shù)外能額外處理的請(qǐng)求數(shù)。我們可以將之前的例子添加burst參數(shù)以及nodelay參數(shù):
- 為什么就多了一個(gè) burst=5 nodelay; 呢,多了這個(gè)可以代表Nginx對(duì)于一個(gè)用戶的請(qǐng)求會(huì)立即處理前五個(gè),多余的就慢慢來(lái)落,沒(méi)有其他用戶的請(qǐng)求我就處理你的,有其他的請(qǐng)求的話我Nginx就漏掉不接受你的請(qǐng)求
3.限制并發(fā)連接數(shù)
Nginx中的ngx_http_limit_conn_module模塊提供了限制并發(fā)連接數(shù)的功能,可以使用limit_conn_zone指令以及l(fā)imit_conn執(zhí)行進(jìn)行配置。接下來(lái)我們可以通過(guò)一個(gè)簡(jiǎn)單的例子來(lái)看下:
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ù)。剛才有提到過(guò)Nginx是基于漏桶算法原理實(shí)現(xiàn)的,實(shí)際上限流一般都是基于漏桶算法和令牌桶算法實(shí)現(xiàn)的。
漏桶算法和令牌算法
漏桶算法
漏桶算法是網(wǎng)絡(luò)世界中流量整形或速率限制時(shí)經(jīng)常使用的一種算法,它的主要目的是控制數(shù)據(jù)注入到網(wǎng)絡(luò)的速率,平滑網(wǎng)絡(luò)上的突發(fā)流量。漏桶算法提供了一種機(jī)制,通過(guò)它,突發(fā)流量可以被整形以便為網(wǎng)絡(luò)提供一個(gè)穩(wěn)定的流量。也就是我們剛才所講的情況。漏桶算法提供的機(jī)制實(shí)際上就是剛才的案例:突發(fā)流量會(huì)進(jìn)入到一個(gè)漏桶,漏桶會(huì)按照我們定義的速率依次處理請(qǐng)求,如果水流過(guò)大也就是突發(fā)流量過(guò)大就會(huì)直接溢出,則多余的請(qǐng)求會(huì)被拒絕。所以漏桶算法能控制數(shù)據(jù)的傳輸速率。
令牌桶算法
令牌桶算法是網(wǎng)絡(luò)流量整形和速率限制中最常使用的一種算法。典型情況下,令牌桶算法用來(lái)控制發(fā)送到網(wǎng)絡(luò)上的數(shù)據(jù)的數(shù)目,并允許突發(fā)數(shù)據(jù)的發(fā)送。Google開(kāi)源項(xiàng)目Guava中的RateLimiter使用的就是令牌桶控制算法。令牌桶算法的機(jī)制如下:存在一個(gè)大小固定的令牌桶,會(huì)以恒定的速率源源不斷產(chǎn)生令牌。如果令牌消耗速率小于生產(chǎn)令牌的速度,令牌就會(huì)一直產(chǎn)生直至裝滿整個(gè)令牌桶。
為什么要做動(dòng)靜分離?
-
Nginx是當(dāng)下最熱的Web容器,網(wǎng)站優(yōu)化的重要點(diǎn)在于靜態(tài)化網(wǎng)站,網(wǎng)站靜態(tài)化的關(guān)鍵點(diǎn)則是是動(dòng)靜分離,動(dòng)靜分離是讓動(dòng)態(tài)網(wǎng)站里的動(dòng)態(tài)網(wǎng)頁(yè)根據(jù)一定規(guī)則把不變的資源和經(jīng)常變的資源區(qū)分開(kāi)來(lái),動(dòng)靜資源做好了拆分以后,我們則根據(jù)靜態(tài)資源的特點(diǎn)將其做緩存操作。
-
讓靜態(tài)的資源只走靜態(tài)資源服務(wù)器,動(dòng)態(tài)的走動(dòng)態(tài)的服務(wù)器。
-
Nginx的靜態(tài)處理能力很強(qiáng),但是動(dòng)態(tài)處理能力不足,因此,在企業(yè)中常用動(dòng)靜分離技術(shù)。
-
對(duì)于靜態(tài)資源比如圖片,js,css等文件,我們則在反向代理服務(wù)器nginx中進(jìn)行緩存。這樣瀏覽器在請(qǐng)求一個(gè)靜態(tài)資源時(shí),代理服務(wù)器nginx就可以直接處理,無(wú)需將請(qǐng)求轉(zhuǎn)發(fā)給后端服務(wù)器tomcat。
-
若用戶請(qǐng)求的動(dòng)態(tài)文件,比如servlet,jsp則轉(zhuǎn)發(fā)給Tomcat服務(wù)器處理,從而實(shí)現(xiàn)動(dòng)靜分離。這也是反向代理服務(wù)器的一個(gè)重要的作用。
Nginx負(fù)載均衡的算法怎么實(shí)現(xiàn)的?策略有哪些?
- 為了避免服務(wù)器崩潰,大家會(huì)通過(guò)負(fù)載均衡的方式來(lái)分擔(dān)服務(wù)器壓力。將對(duì)多臺(tái)服務(wù)器組成一個(gè)集群,當(dāng)用戶訪問(wèn)時(shí),先訪問(wèn)到一個(gè)轉(zhuǎn)發(fā)服務(wù)器,再由轉(zhuǎn)發(fā)服務(wù)器將訪問(wèn)分發(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的值越大分配到的訪問(wèn)概率越高,主要用于后端每臺(tái)服務(wù)器性能不均衡的情況下。其次是為在主從的情況下設(shè)置不同的權(quán)值,達(dá)到合理有效的地利用主機(jī)資源。
upstream backserver { server 192.168.0.12 weight=2; server 192.168.0.13 weight=8; }權(quán)重越高,在被訪問(wèn)的概率越大,如上例,分別是20%,80%。
3.ip_hash(IP綁定)
每個(gè)請(qǐng)求按訪問(wèn)IP的哈希結(jié)果分配,使來(lái)自同一個(gè)IP的訪客固定訪問(wèn)一臺(tái)后端服務(wù)器,并且可以有效解決動(dòng)態(tài)網(wǎng)頁(yè)存在的session共享問(wèn)題
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ù)頁(yè)面大小和加載時(shí)間長(zhǎng)短智能地進(jìn)行負(fù)載均衡,響應(yīng)時(shí)間短的優(yōu)先分配。
upstream backserver { server server1; server server2; fair; }哪個(gè)服務(wù)器的響應(yīng)速度快,就將請(qǐng)求分配到那個(gè)服務(wù)器上。
5.url_hash(第三方插件)
必須安裝Nginx的hash軟件包。按訪問(wèn)url的hash結(jié)果來(lái)分配請(qǐng)求,使每個(gè)url定向到同一個(gè)后端服務(wù)器,可以進(jìn)一步提高后端緩存服務(wù)器的效率。
upstream backserver { server squid1:3128; server squid2:3128; hash $request_uri; hash_method crc32; }Nginx高可用性怎么配置?
當(dāng)上游服務(wù)器(真實(shí)訪問(wèn)服務(wù)器),一旦出現(xiàn)故障或者是沒(méi)有及時(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èn)的服務(wù)器)超時(shí)時(shí)間 后端服務(wù)器連接的超時(shí)時(shí)間_發(fā)起握手等候響應(yīng)超時(shí)時(shí)間proxy_connect_timeout 1s;###nginx發(fā)送給上游服務(wù)器(真實(shí)訪問(wèn)的服務(wù)器)超時(shí)時(shí)間proxy_send_timeout 1s;### nginx接受上游服務(wù)器(真實(shí)訪問(wèn)的服務(wù)器)超時(shí)時(shí)間proxy_read_timeout 1s;index index.html index.htm;}}總結(jié)
以上是生活随笔為你收集整理的【腾讯面试题】Nginx的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: tableau-参数
- 下一篇: 用Transformer完全代替CNN: