2022年3月7日 星期一

《面試官別再問》Nginx常見的面試題

1. 什麼是Nginx?

Nginx是一個輕量級/高性能的反向代理Web服務器,他實現非常高效的反向代理、負載平衡,他可以處理2-3萬並發連接數,官方監測能支持5萬並發,現在中國使用nginx網站用戶有很多,例如:新浪、網易、 騰訊等。


2. 為什麼要用Nginx?

跨平台、配置簡單、方向代理、高並發連接:處理2-3萬並發連接數,官方監測能支持5萬並發,內存消耗小:開啟10個nginx才佔150M內存,nginx處理靜態文件好,耗費內存少,

而且Nginx內置的健康檢查功能:如果有一個服務器宕機,會做一個健康檢查,再發送的請求就不會發送到宕機的服務器了。重新將請求提交到其他的節點上。

使用Nginx的話還能:

節省寬帶:支持GZIP壓縮,可以添加瀏覽器本地緩存

穩定性高:宕機的概率非常小

接收用戶請求是異步的


2. 為什麼Nginx性能這麼高?

因為他的事件處理機制:異步非阻塞事件處理機制:運用了epoll模型,提供了一個隊列,排隊解決

Nginx怎麼處理請求的?

nginx接收一個請求後,首先由listen和server_name指令匹配server模塊,再匹配server模塊裡的location,location就是實際地址

    server                                  # 第一個Server區塊開始,表示一個獨立的虛擬主機站點

        listen       80;                    # 提供服務的端口,默認80

        server_name  localhost;             # 提供服務的域名主機名

        location / {                        # 第一個location區塊開始

            root   html;                    # 站點的根目錄,相當於Nginx的安裝目錄

            index  index.html index.htm;    # 默認的首頁文件,多個用空格分開

        }                                   # 第一個location區塊結果

    }


3. 什麼是正向代理和反向代理?

正向代理就是一個人發送一個請求直接就到達了目標的服務器

反方代理就是請求統一被Nginx接收,nginx反向代理服務器接收到之後,按照一定的規 則分發給了後端的業務處理服務器進行處理了

使用“反向代理服務器的優點是什麼?

反向代理服務器可以隱藏源服務器的存在和特徵。它充當互聯網雲和web服務器之間的中間層。這對於安全方面來說是很好的,特別是當您使用web託管服務時。


4. Nginx的優缺點?

優點:

佔內存小,可實現高並發連接,處理響應快

可實現http服務器、虛擬主機、方向代理、負載均衡

Nginx配置簡單

可以不暴露正式的服務器IP地址

缺點: 動態處理差:nginx處理靜態文件好,耗費內存少,但是處理動態頁面則很雞肋,現在一般前端用nginx作為反向代理抗住壓力,


5. Nginx應用場景?

http服務器。Nginx是一個http服務可以獨立提供http服務。可以做網頁靜態服務器。

虛擬主機。可以實現在一台服務器虛擬出多個網站,例如個人網站使用的虛擬機。

反向代理,負載均衡。當網站的訪問量達到一定程度後,單台服務器不能滿足用戶的請求時,需要用多台服務器集群可以使用nginx做反向代理。並且多台服務器可以平均分擔負載,不會應為某台服務器負載高宕機而某台服務器閒置的情況。

nginz 中也可以配置安全管理、比如可以使用Nginx搭建API接口網關,對每個接口服務進行攔截。


6. 限流怎麼做的?

Nginx限流就是限制用戶請求速度,防止服務器受不了

限流有3種

正常限制訪問頻率(正常流量)

突發限制訪問頻率(突發流量)

限制並發連接數


1、正常限制訪問頻率(正常流量):

限制一個用戶發送的請求,我Nginx多久接收一個請求。

Nginx中使用ngx_http_limit_req_module模塊來限制的訪問頻率,限制的原理實質是基於漏桶算法原理來實現的。在nginx.conf配置文件中可以使用limit_req_zone命令及limit_req命令限制單個IP的請求處理頻率。

    #定義限流維度,一個用戶一分鐘一個請求進來,多餘的全部漏掉

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秒一個請求,1r/m一分鐘接收一個請求, 如果Nginx這時還有別人的請求沒有處理完,Nginx就會拒絕處理該用戶請求。

2、突發限制訪問頻率(突發流量):

限制一個用戶發送的請求,我Nginx多久接收一個。

    #定義限流維度,一個用戶一分鐘一個請求進來,多餘的全部漏掉

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;

}


}

上面的配置一定程度可以限制訪問頻率,但是也存在著一個問題:如果突發流量超出請求被拒絕處理,無法處理活動時候的突發流量,這時候應該如何進一步處理呢?Nginx提供burst參數結合nodelay參數可以解決流量突發的問題,可以設置能處理的超過設置的請求數外能額外處理的請求數。我們可以將之前的例子添加burst參數以及nodelay參數:

為什麼就多了一個burst=5 nodelay; 呢,多了這個可以代表Nginx對於一個用戶的請求會立即處理前五個,多餘的就慢慢來落,沒有其他用戶的請求我就處理你的,有其他的請求的話我Nginx就漏掉不接受你的請求

3、 限制並發連接數

Nginx中的ngx_http_limit_conn_module模塊提供了限制並發連接數的功能,可以使用limit_conn_zone指令以及limit_conn執行進行配置。

    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;

        }

    }

面配置了單個IP同時並發連接數最多只能10個連接,並且設置了整個虛擬服務器同時最大並發數最多只能100個鏈接。當然,只有當請求的header被服務器處理後,虛擬服務器的連接數才會計數。剛才有提到過Nginx是基於漏桶算法原理實現的,實際上限流一般都是基於漏桶算法和令牌桶算法實現的。


7. 為什麼要做動靜分離?

Nginx是當下最熱的Web容器,網站優化的重要點在於靜態化網站,網站靜態化的關鍵點則是是動靜分離,動靜分離是讓動態網站裡的動態網頁根據一定規則把不變的資源和經常變的資源區分開來,動靜資源做好了拆分以後,我們則根據靜態資源的特點將其做緩存操作。

讓靜態的資源只走靜態資源服務器,動態的走動態的服務器

Nginx的靜態處理能力很強,但是動態處理能力不足,因此,在企業中常用動靜分離技術。

對於靜態資源比如圖片,js,css等文件,我們則在反向代理服務器nginx中進行緩存。這樣瀏覽器在請求一個靜態資源時,代理服務器nginx就可以直接處理,無需將請求轉發給後端服務器tomcat。若用戶請求的動態文件,比如servlet,jsp則轉發給Tomcat服務器處理,從而實現動靜分離。這也是反向代理服務器的一個重要的作用。

Nginx怎麼做的動靜分離?

只需要指定路徑對應的目錄。location/可以使用正則表達式匹配。並指定對應的硬盤中的目錄。如下:

    location /image/ {

        root   /usr/local/static/;

        autoindex on;

    }

    

8. Nginx負載均衡的算法怎麼實現的?策略有哪些?

為了避免服務器崩潰,大家會通過負載均衡的方式來分擔服務器壓力。將對台服務器組成一個集群,當用戶訪問時,先訪問到一個轉發服務器,再由轉發服務器將訪問分發到壓力更小的服務器。

Nginx負載均衡實現的策略有以下五種:

1 輪詢(默認)

每個請求按時間順序逐一分配到不同的後端服務器,如果後端某個服務器宕機,能自動剔除故障系統。

    upstream backserver { 

        server 192.168.0.12; 

        server 192.168.0.13; 

    } 

2 權重weight

weight的值越大分配

到的訪問概率越高,主要用於後端每台服務器性能不均衡的情況下。其次是為在主從的情況下設置不同的權值,達到合理有效的地利用主機資源。

    upstream backserver { 

        erver 192.168.0.12 weight=2; 

        erver 192.168.0.13 weight=8; 

    } 

權重越高,在被訪問的概率越大,如上例,分別是20%,80%。

3 ip_hash( IP綁定)

每個請求按訪問IP的哈希結果分配,使來自同一個IP的訪客固定訪問一台後端服務器,并且可以有效解决动态网页存在的session共享问题

    upstream backserver { 

        ip_hash; 

        server 192.168.0.12:88; 

        server 192.168.0.13:80; 

    } 

4 fair(第三方插件)

必須安裝upstream_fair模塊。

對比weight、ip_hash更加智能的負載均衡算法,fair算法可以根據頁面大小和加載時間長短智能地進行負載均衡,響應時間短的優先分配。

    upstream backserver { 

        server server1; 

        server server2; 

        fair; 

    } 

哪個服務器的響應速度快,就將請求分配到那個服務器上。

5、url_hash(第三方插件)

必須安裝Nginx的hash軟件包

按訪問url的hash結果來分配請求,使每個url定向到同一個後端服務器,可以進一步提高後端緩存服務器的效率。

    upstream backserver { 

        server squid1:3128; 

        server squid2:3128; 

        hash $request_uri; 

        hash_method crc32; 

    } 

    

9. nginx中500、502、503、504 有什麼區別?

500:Internal Server Error 內部服務錯誤,比如腳本錯誤,編程語言語法錯誤。

502:Bad Gateway錯誤,網關錯誤。比如服務器當前連接太多,響應太慢,頁面素材太多、帶寬慢。

503:Service Temporarily Unavailable,服務不可用,web服務器不能處理HTTP請求,可能是臨時超載或者是服務器進行停機維護。

504:Gateway timeout 網關超時,程序執行時間過長導致響應超時,例如程序需要執行20秒,而nginx最大響應等待時間為10秒,這樣就會出現超時。


10. Nginx服務器上的Master和Worker進程分別是什麼?

Master進程:讀取及評估配置和維持

Worker進程:解決請求


11. 如何用Nginx解決前端跨域問題?

使用Nginx轉發請求。把跨域的接口寫成調本域的接口,然後將這些接口轉發到真正的請求地址。


12. Nginx VS Apache

Apache 通過創建進程和線程來處理其他的連接。管理員可以通過設置來控制服務器所能允許的最大進程數量。這個配置因機器的可用內存而異。過多的進程會耗盡內存從而使得機器使用磁盤上的交換內存,這嚴重的降低了性能。而且,當達到進程的上限之後,Apache 會拒絕新的連接。

Apache可以通過設置來運行在 pre-forked 模式或 worker multi-process 模式 ( MPM )。當其他的用戶連接時,兩種方式都會創建新的進程。區別在於,pre-forked 模式為每一個進程創建一個線程,用來處理一個用戶的請求。worker 模式也創建新的進程,但是每一個進程至少有一個線程,每一個線程用來處理單個用戶的單個請求。所以,一個 worker mode 的進程處理至少一個連接,而一個 per-fork 模式的進程只處理一個連接。

相比於 forked 模式,worker 模式使用更少的內存,原因是進程比線程消耗更多的內存,線程只是運行在進程中的代碼。

此外,worker 模式不是線程安全的。這意味著如果你使用像 mod_php 這樣的非線程安全的模塊來服務 php 頁面時,你需要使用 pre-forked 模式,因此要消耗更多的內存。所以,當選擇模塊和配置服務器時,你必須要面對是線程還是進程更優的問題以及一些約束的問題。

在調整 Apache 時的一個限制因素是內存以及當爭奪同一個 CPU 和內存時潛在的線程死鎖問題。如果一個線程停止了,用戶會一直處於等待頁面出現的狀態,直到進程將該線程回收,以便可以發回頁面。如果一個線程發生了死鎖,它不知道如何重啟,因此會一直處於卡住狀態。

Openresty

和 Apache 相比,Nginx 的工作方式有很大不同,主要是在於它如何處理線程。

Nginx 並不會為每一個的 web 請求創建新的進程,相反,管理員可以配置 Nginx 主進程的工作進程的數量(一個常見的做法是為每一個 CPU 配置一個工作進程)。所有這些進程都是單線程的。每一個工作進程可以處理數千個並發的請求。它通過一個線程來異步的完成了這些工作,而沒有使用多線程的編程模型。

Nginx 還拆分了緩存加載器 ( cache loader ) 和緩存管理器 ( cache manager ) 進程用來從磁盤中讀取數據並將其加載到緩存中,當緩存直接讀取的時候緩存過期。

Nginx 有一系列的模塊組成,這些模塊在編譯的時候就被包含進去了。這意味著,用戶下載源碼並選擇他們要編譯的模塊。這些模塊中包括連接後端應用服務器,負載均衡,代理服務器以及其他。並沒有 PHP 的模塊,因為 Nginx 可以自己編譯 PHP 代碼。

沒有留言:

張貼留言