Nginx面试题
什么是Nginx
Nginx是一個 輕量級/高性能的反向代理Web服務器,他實現非常高效的反向代理、負載平衡,他可以處理2-3萬并發連接數,官方監測能支持5萬并發,現在中國使用nginx網站用戶有很多,例如:新浪、網易、 騰訊等。
為什么要用Nginx
1、跨平臺、配置簡單、方向代理、高并發連接:處理2-3萬并發連接數,官方監測能支持5萬并發,內存消耗小:開啟10個nginx才占150M內存 ,nginx處理靜態文件好,耗費內存少,
2、而且Nginx內置的健康檢查功能:如果有一個服務器宕機,會做一個健康檢查,再發送的請求就不會發送到宕機的服務器了。重新將請求提交到其他的節點上。
3、使用Nginx的話還能:
- 節省寬帶:支持GZIP壓縮,可以添加瀏覽器本地緩存
- 穩定性高:宕機的概率非常小
- 接收用戶請求是異步的
為什么Nginx性能這么高?
因為他的事件處理機制:異步非阻塞事件處理機制:運用了epoll模型,提供了一個隊列,排隊解決
什么是正向代理和反向代理?
- 正向代理就是一個人發送一個請求直接就到達了目標的服務器
- 反方代理就是請求統一被Nginx接收,nginx反向代理服務器接收到之后,按照一定的規 則分發給了后端的業務處理服務器進行處理了
Nginx的優缺點?
優點:
占內存小,可實現高并發連接,處理響應快
可實現http服務器、虛擬主機、方向代理、負載均衡
Nginx配置簡單
可以不暴露正式的服務器IP地址
缺點:
動態處理差:nginx處理靜態文件好,耗費內存少,但是處理動態頁面則很雞肋,現在一般前端用nginx作為反向代理抗住壓力
如何用Nginx解決前端跨域問題?
使用Nginx轉發請求。把跨域的接口寫成調本域的接口,然后將這些接口轉發到真正的請求地址
Nginx負載均衡的算法怎么實現的?策略有哪些?
為了避免服務器崩潰,大家會通過負載均衡的方式來分擔服務器壓力。將對臺服務器組成一個集群,當用戶訪問時,先訪問到一個轉發服務器,再由轉發服務器將訪問分發到壓力更小的服務器。
Nginx負載均衡實現的策略有以下五種:
輪詢(默認):每個請求按時間順序逐一分配到不同的后端服務器,如果后端某個服務器宕機,能自動剔除故障系統。
權重 weight weight的值越大分配到的訪問概率越高,主要用于后端每臺服務器性能不均衡的情況下。其次是為在主從的情況下設置不同的權值,達到合理有效的地利用主機資源。
ip_hash( IP綁定) 每個請求按訪問IP的哈希結果分配,使來自同一個IP的訪客固定訪問一臺后端服務器,并且可以有效解決動態網頁存在的session共享問題
fair(第三方插件) 必須安裝upstream_fair模塊。
對比 weight、ip_hash更加智能的負載均衡算法,fair算法可以根據頁面大小和加載時間長短智能地進行負載均衡,響應時間短的優先分配。哪個服務器的響應速度快,就將請求分配到那個服務器上。
url_hash(第三方插件) 必須安裝Nginx的hash軟件包
按訪問url的hash結果來分配請求,使每個url定向到同一個后端服務器,可以進一步提高后端緩存服務器的效率。
Nginx 是如何實現高并發的?
異步,非阻塞,使用了epoll 和大量的底層代碼優化。
如果一個server采用一個進程負責一個request的方式,那么進程數就是并發數。正常情況下,會有很多進程一直在等待中。
而nginx采用一個master進程,多個woker進程的模式。
- master進程主要負責收集、分發請求。每當一個請求過來時,master就拉起一個worker進程負責處理這個請求。
- 同時master進程也負責監控woker的狀態,保證高可靠性
- woker進程一般設置為跟cpu核心數一致。nginx的woker進程在同一時間可以處理的請求數只受內存限制,可以處理多個請求。
Nginx 的異步非阻塞工作方式正把當中的等待時間利用起來了。在需要等待的時候,這些進程就空閑出來待命了,因此表現為少數幾個進程就解決了大量的并發問題。
限流怎么做的?
Nginx限流就是限制用戶請求速度,防止服務器受不了
限流有3種:
1、正常限制訪問頻率(正常流量)
2、突發限制訪問頻率(突發流量)
3、限制并發連接數
正常限制訪問頻率(正常流量):
限制一個用戶發送的請求,我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就會拒絕處理該用戶請求。
突發限制訪問頻率(突發流量):
限制一個用戶發送的請求,我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就漏掉不接受你的請求
限制并發連接數
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是基于漏桶算法原理實現的,實際上限流一般都是基于漏桶算法和令牌桶算法實現的。接下來我們來看看兩個算法的介紹:
Nginx處理HTTP請求過程
1、Read Request Headers:解析請求頭。
2、Identify Configuration Block:識別由哪一個 location 進行處理,匹配 URL。
3、Apply Rate Limits:判斷是否限速。例如可能這個請求并發的連接數太多超過了限制,或者 QPS 太高。
4、Perform Authentication:連接控制,驗證請求。例如可能根據 Referrer 頭部做一些防盜鏈的設置,或者驗證用戶的權限。
5、Generate Content:生成返回給用戶的響應。為了生成這個響應,做反向代理的時候可能會和上游服務(Upstream Services)進行通信,然后這個過程中還可能會有些子請求或者重定向,那么還會走一下這個過程(Internal redirects and subrequests)。
6、Response Filters:過濾返回給用戶的響應。比如壓縮響應,或者對圖片進行處理。
7、Log:記錄日志
Nginx限制IP訪問配置
屏蔽單個ip訪問 # 格式: deny ip; deny 123.68.23.5;允許單個ip訪問 # 格式: allow ip; allow 123.68.25.6;屏蔽所有ip訪問 deny all;允許所有ip訪問 allow all;屏蔽ip段訪問 # deny ip/mask # 屏蔽172.12.62.0到172.45.62.255訪問的命令 deny 172.12.62.0/24;允許ip段訪問 # allow ip/mask # 屏蔽172.102.0.0到172.102.255.255訪問的命令 allow 172.102.0.0/16;配置說明
可新建一個配置文件,如 blockip.conf。在其中編寫相關的 ip 限制語句,然后在 nginx.conf 中加入如下配置:
# 配置ip限制策略 include blockip.conf;nginx 會根據配置文件中的語句,從上至下依次判斷。因此,寫在前面的語句可能會屏蔽后續的語句。除部分 ip 白名單外,屏蔽所有 ip 的錯誤示例:
deny all; # 該語句已經禁止所有ip的訪問,后續的配置不會生效 allow 123.45.25.6; allow 123.68.52.125; allow 123.125.25.106;正確示例:
# 允許部分ip訪問 allow 123.45.25.6; allow 123.68.52.125; allow 123.125.25.106; # 禁止其余ip訪問 deny all;總結
- 上一篇: stm32例程_如何学习STM32?
- 下一篇: Nginx —— 检查配置文件ngi