Nginx常見的面試題—限流、正向、反向、負(fù)載均衡策略

1、什么是Nginx,談?wù)剛€(gè)人都理解,項(xiàng)目中是否用到,為什么要用,有什么優(yōu)點(diǎn)?

Nginx ,是一個(gè) Web 服務(wù)器和反向代理服務(wù)器用于 HTTP、HTTPS、SMTP、POP3 和 IMAP 協(xié)議。

主要功能如下:

1、正向、反向代理
2、負(fù)載均衡、分流
3、虛擬主機(jī)(綁定host)

優(yōu)點(diǎn):

跨平臺(tái)、配置簡(jiǎn)單,非阻塞、高并發(fā)連接、內(nèi)存消耗小、成本低廉。

2、正向代理和反向代理的區(qū)別是什么?

正向代理是一個(gè)位于客戶端和原始服務(wù)器之間的服務(wù)器,為了從原始服務(wù)器取得內(nèi)容,客戶端向代理發(fā)送一個(gè)請(qǐng)求并指定原始服務(wù)器,然后代理向原始服務(wù)器轉(zhuǎn)交請(qǐng)求并將獲得的內(nèi)容返回給客戶端。代理服務(wù)器和客戶端處于同一個(gè)局域網(wǎng)內(nèi)。

比如說fanqiang。我知道我要訪問谷歌,于是我就告訴代理服務(wù)器讓它幫我轉(zhuǎn)發(fā)。

反向代理實(shí)際運(yùn)行方式是代理服務(wù)器接受網(wǎng)絡(luò)上的連接請(qǐng)求。它將請(qǐng)求轉(zhuǎn)發(fā)給內(nèi)部網(wǎng)絡(luò)上的服務(wù)器,并將從服務(wù)器上得到的結(jié)果返回給網(wǎng)絡(luò)上請(qǐng)求連接的客戶端 。代理服務(wù)器和原始服務(wù)器處于同一個(gè)局域網(wǎng)內(nèi)。

比如說我要訪問taobao,對(duì)我來說不知道圖片、json、css 是不是同一個(gè)服務(wù)器返回回來的,但是我不關(guān)心,是反向代理 處理的,我不知道原始服務(wù)器。

3、Nginx如何處理HTTP請(qǐng)求的?

它結(jié)合多進(jìn)程機(jī)制(單線程)和異步非阻塞方式。

1、多進(jìn)程機(jī)制(單線程)

服務(wù)器每當(dāng)收到一個(gè)客戶端時(shí),就有 服務(wù)器主進(jìn)程 ( master process )生成一個(gè) 子進(jìn)程( worker process )出來和客戶端建立連接進(jìn)行交互,直到連接斷開,該子進(jìn)程就結(jié)束了。

2、異步非阻塞機(jī)制

每個(gè)工作進(jìn)程 使用 異步非阻塞方式 ,可以處理 多個(gè)客戶端請(qǐng)求 。 運(yùn)用了epoll模型,提供了一個(gè)隊(duì)列,排隊(duì)解決。

當(dāng)某個(gè) 工作進(jìn)程 接收到客戶端的請(qǐng)求以后,調(diào)用 IO 進(jìn)行處理,如果不能立即得到結(jié)果,就去 處理其他請(qǐng)求 (即為 非阻塞 );而 客戶端 在此期間也 無需等待響應(yīng) ,可以去處理其他事情(即為 異步 )。

當(dāng) IO 返回時(shí),就會(huì)通知此 工作進(jìn)程 ;該進(jìn)程得到通知,暫時(shí) 掛起 當(dāng)前處理的事務(wù)去 響應(yīng)客戶端請(qǐng)求 。

為什么這么快?可以參考一下Nginx官方介紹:http://www.aosabook.org/en/nginx.html

4、Nginx的master和worker是如何工作的?

這跟Nginx的多進(jìn)程、單線程有關(guān)。(一個(gè)進(jìn)程只有一個(gè)主線程)。

為什么要用單線程?

采用單線程來異步非阻塞處理請(qǐng)求(管理員可以配置Nginx主進(jìn)程的工作進(jìn)程的數(shù)量),不會(huì)為每個(gè)請(qǐng)求分配cpu和內(nèi)存資源,節(jié)省了大量資源,同時(shí)也減少了大量的CPU的上下文切換,所以才使得Nginx支持更高的并發(fā)。

簡(jiǎn)單過程:

主程序 Master process 啟動(dòng)后,通過一個(gè) for 循環(huán)來 接收 和 處理外部信號(hào) ;

主進(jìn)程通過 fork() 函數(shù)產(chǎn)生 worker 子進(jìn)程 ,每個(gè)子進(jìn)程執(zhí)行一個(gè) for循環(huán)來實(shí)現(xiàn)Nginx服務(wù)器對(duì)事件的接收和處理 。

詳細(xì)過程:

1、Nginx 在啟動(dòng)后,會(huì)有一個(gè) master 進(jìn)程和多個(gè)相互獨(dú)立的 worker 進(jìn)程。
2、master 接收來自外界的信號(hào),先建立好需要 listen 的 socket(listenfd) 之后,然后再 fork 出多個(gè) worker 進(jìn)程,然后向各worker進(jìn)程發(fā)送信號(hào),每個(gè)進(jìn)程都有可能來處理這個(gè)連接。
3、所有 worker 進(jìn)程的 listenfd 會(huì)在新連接到來時(shí)變得可讀 ,為保證只有一個(gè)進(jìn)程處理該連接,所有 worker 進(jìn)程在注冊(cè) listenfd 讀事件前搶占 accept_mutex ,搶到互斥鎖的那個(gè)進(jìn)程注冊(cè) listenfd 讀事件 ,在讀事件里調(diào)用 accept 接受該連接。
4、當(dāng)一個(gè) worker 進(jìn)程在 accept 這個(gè)連接之后,就開始讀取請(qǐng)求、解析請(qǐng)求、處理請(qǐng)求,產(chǎn)生數(shù)據(jù)后,再返回給客戶端 ,最后才斷開連接。

5、Nginx 常用命令有哪些?

  • 啟動(dòng) nginx 。
  • 停止 nginx -s stopnginx -s quit 。
  • 重啟 nginx -s reloadservice nginx reload 。
  • 重載指定配置文件 .nginx -c /usr/local/nginx/conf/nginx.conf 。
  • 查看 nginx 版本 nginx -v 。

6、nginx中500、502、503、504 有什么區(qū)別?

500

Internal Server Error 內(nèi)部服務(wù)錯(cuò)誤,比如腳本錯(cuò)誤,編程語言語法錯(cuò)誤。

502

Bad Gateway錯(cuò)誤,網(wǎng)關(guān)錯(cuò)誤。比如服務(wù)器當(dāng)前連接太多,響應(yīng)太慢,頁面素材太多、帶寬慢。

503

Service Temporarily Unavailable,服務(wù)不可用,web服務(wù)器不能處理HTTP請(qǐng)求,可能是臨時(shí)超載或者是服務(wù)器進(jìn)行停機(jī)維護(hù)。

504

Gateway timeout 網(wǎng)關(guān)超時(shí),程序執(zhí)行時(shí)間過長(zhǎng)導(dǎo)致響應(yīng)超時(shí),例如程序需要執(zhí)行20秒,而nginx最大響應(yīng)等待時(shí)間為10秒,這樣就會(huì)出現(xiàn)超時(shí)。

7、Nginx 壓縮了解嗎,如何開啟壓縮?

開啟nginx gzip壓縮后,圖片、css、js等靜態(tài)資源的大小會(huì)減小,可節(jié)省帶寬,提高傳輸效率,但是會(huì)消耗CPU資源。

開啟:

    # 開啟gzip
    gzip off;

    # 啟用gzip壓縮的最小文件,小于設(shè)置值的文件將不會(huì)壓縮
    gzip_min_length 1k;

    # gzip 壓縮級(jí)別,1-9,數(shù)字越大壓縮的越好,也越占用CPU時(shí)間,后面會(huì)有詳細(xì)說明
    gzip_comp_level 1;

    # 進(jìn)行壓縮的文件類型。javascript有多種形式。其中的值可以在 mime.types 文件中找到。
    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 application/vnd.ms-fontobject font/ttf font/opentype font/x-woff image/svg+xml;

8、Nginx 和 Apache、Tomcat 之間的不同點(diǎn)

1、Nginx/Apache 是Web Server,而Apache Tomact是一個(gè)servlet container
2、tomcat可以對(duì)jsp進(jìn)行解析,nginx和apache只是web服務(wù)器,可以簡(jiǎn)單理解為只能提供html靜態(tài)文件服務(wù)。

Nginx和Apache區(qū)別:

1)Nginx輕量級(jí),同樣起web 服務(wù),比apache占用更少的內(nèi)存及資源 。

2)Nginx 抗并發(fā),nginx 處理請(qǐng)求是異步非阻塞的,而apache 則是阻塞型的,在高并發(fā)下nginx 能保持低資源低消耗高性能 。

3)Nginx提供負(fù)載均衡,可以做做反向代理,前端服務(wù)器

4)Nginx多進(jìn)程單線程,異步非阻塞;Apache多進(jìn)程同步,阻塞。

9、Nginx 有哪些負(fù)載均衡策略

Nginx 默認(rèn)提供的負(fù)載均衡策略:

  • 1、輪詢(默認(rèn))round_robin

    每個(gè)請(qǐng)求按時(shí)間順序逐一分配到不同的后端服務(wù)器,如果后端服務(wù)器 down 掉,能自動(dòng)剔除。

  • 2、IP 哈希 ip_hash

    每個(gè)請(qǐng)求按訪問 ip 的 hash 結(jié)果分配,這樣每個(gè)訪客固定訪問一個(gè)后端服務(wù)器,可以解決 session 共享的問題。

    當(dāng)然,實(shí)際場(chǎng)景下,一般不考慮使用 ip_hash 解決 session 共享。

  • 3、最少連接 least_conn

    下一個(gè)請(qǐng)求將被分派到活動(dòng)連接數(shù)量最少的服務(wù)器

  • 4、權(quán)重 weight

    weight的值越大分配到的訪問概率越高,主要用于后端每臺(tái)服務(wù)器性能不均衡的情況下,達(dá)到合理的資源利用率。

還可以通過插件支持其他策略。

10、Nginx動(dòng)靜態(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ū)分開來 路。

比如說 js、css、hrml從A服務(wù)器返回。圖片 從B服務(wù)器返回,其他請(qǐng)求從Tomcat服務(wù)器C返回。

后臺(tái)應(yīng)用分開部署,提高用戶訪問靜態(tài)代碼的速度。而且現(xiàn)在還有CDN服務(wù),不需要限制于服務(wù)器的帶寬。

11、ngx_http_upstream_module模塊了解嗎?

ngx_http_upstream_module模塊用于將多個(gè)服務(wù)器定義成服務(wù)器組,可通過fastcgi傳遞、proxy傳遞、uwsgi傳遞、memcached傳遞和scgi傳遞指令來引用的服務(wù)器組。

比如訪問www.a.com 緩存+調(diào)度:

http{
    proxy_cache_path /var/cache/nginx/proxy_cache levels=1:2:2 keys_zone=proxycache:20m inactive=120s max_si #緩存
ze=1g;
    upstream mysqlsrvs{
        ip_hash; #源地址hash調(diào)度方法 寫了backup就不可用
        server 172.18.99.1:80 weight=2; #weight權(quán)重
        server 172.18.99.2:80;          #標(biāo)記down,配合ip_hash使用,實(shí)現(xiàn)灰度發(fā)布
        server 172.18.99.3:80 backup;   #backup將服務(wù)器標(biāo)記為“備用”,即所有服務(wù)器均不可用時(shí)才啟用 
    }
}
server{
    server_name www.a.com;
    proxy_cache proxycache;
    proxy_cache_key $request_uri;
    proxy_cache_valid 200 302 301 1h;
    proxy_cache_valid any 1m;
    location / {
        proxy_pass http://mysqlsrvs;
    }
}

12、限流了解嗎,怎么限流的?

Nginx 提供兩種限流方式,一是控制速率,二是控制并發(fā)連接數(shù)。

1、控制速率

ngx_http_limit_req_module 模塊提供了漏桶算法(leaky bucket),可以限制單個(gè)IP的請(qǐng)求處理頻率。

如:

1.1 正常限流:

http {
limit_req_zone 192.168.1.1 zone=myLimit:10m rate=5r/s;
}

server {
location / {
limit_req zone=myLimit;
rewrite / http://www.hac.cn permanent;
}
}

參數(shù)解釋:

key: 定義需要限流的對(duì)象。
zone: 定義共享內(nèi)存區(qū)來存儲(chǔ)訪問信息。
rate: 用于設(shè)置最大訪問速率。

表示基于客戶端192.168.1.1進(jìn)行限流,定義了一個(gè)大小為10M,名稱為myLimit的內(nèi)存區(qū),用于存儲(chǔ)IP地址訪問信息。rate設(shè)置IP訪問頻率,rate=5r/s表示每秒只能處理每個(gè)IP地址的5個(gè)請(qǐng)求。Nginx限流是按照毫秒級(jí)為單位的,也就是說1秒處理5個(gè)請(qǐng)求會(huì)變成每200ms只處理一個(gè)請(qǐng)求。如果200ms內(nèi)已經(jīng)處理完1個(gè)請(qǐng)求,但是還是有有新的請(qǐng)求到達(dá),這時(shí)候Nginx就會(huì)拒絕處理該請(qǐng)求。

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

上面rate設(shè)置了 5r/s,如果有時(shí)候流量突然變大,超出的請(qǐng)求就被拒絕返回503了,突發(fā)的流量影響業(yè)務(wù)就不好了。

這時(shí)候可以加上burst 參數(shù),一般再結(jié)合 nodelay 一起使用。

server {
location / {
limit_req zone=myLimit burst=20 nodelay;
rewrite / http://www.hac.cn permanent;
}
}

burst=20 nodelay 表示這20個(gè)請(qǐng)求立馬處理,不能延遲,相當(dāng)于特事特辦。不過,即使這20個(gè)突發(fā)請(qǐng)求立馬處理結(jié)束,后續(xù)來了請(qǐng)求也不會(huì)立馬處理。burst=20 相當(dāng)于緩存隊(duì)列中占了20個(gè)坑,即使請(qǐng)求被處理了,這20個(gè)位置這只能按 100ms一個(gè)來釋放。

2、控制并發(fā)連接數(shù)

ngx_http_limit_conn_module 提供了限制連接數(shù)功能。

limit_conn_zone $binary_remote_addr zone=perip:10m;
limit_conn_zone $server_name zone=perserver:10m;

server {
    ...
    limit_conn perip 10;
    limit_conn perserver 100;
}

limit_conn perip 10 作用的key 是 $binary_remote_addr,表示限制單個(gè)IP同時(shí)最多能持有10個(gè)連接。

limit_conn perserver 100 作用的key是 $server_name,表示虛擬主機(jī)(server) 同時(shí)能處理并發(fā)連接的總數(shù)。

注:limit_conn perserver 100 作用的key是 $server_name,表示虛擬主機(jī)(server) 同時(shí)能處理并發(fā)連接的總數(shù)。

拓展:

如果不想做限流,還可以設(shè)置白名單:

利用 Nginx ngx_http_geo_modulengx_http_map_module 兩個(gè)工具模塊提供的功能。

##定義白名單ip列表變量
geo $limit {
    default 1;
    10.0.0.0/8 0;
    192.168.0.0/10 0;
    81.56.0.35 0;
}

map $limit $limit_key {
    0 "";
    1 $binary_remote_addr;
}
# 正常限流設(shè)置
limit_req_zone $limit_key zone=myRateLimit:10m rate=10r/s;

geo 對(duì)于白名單 將返回0,不限流;其他IP將返回1,進(jìn)行限流。

具體參考:http://nginx.org/en/docs/http/ngx_http_geo_module.html

除此之外:

ngx_http_core_module 還提供了限制數(shù)據(jù)傳輸速度的能力(即常說的下載速度)

location /flv/ {
    flv;
    limit_rate_after 500m;
    limit_rate       50k;
}

針對(duì)每個(gè)請(qǐng)求,表示客戶端下載前500m的大小時(shí)不限速,下載超過了500m后就限速50k/s。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容