Nginx是一個 輕量級/高性能的反向代理Web服務器,用於 HTTP、HTTPS、SMTP、POP3 和 IMAP 協議。他實現非常高效的反向代理、負載平衡,他可以處理2-3萬並發連接數,官方監測能支持5萬並發,現在中國使用nginx網站用戶有很多,例如:新浪、網易、 騰訊等。
Nginx 有哪些優點?如果一個 server 採用一個進程(或者線程)負責一個request的方式,那麼進程數就是並發數。那麼顯而易見的,就是會有很多進程在等待中。等什麼?最多的應該是等待網絡傳輸。
而 Nginx 的異步非阻塞工作方式正是利用了這點等待的時間。在需要等待的時候,這些進程就空閒出來待命了。因此表現為少數幾個進程就解決了大量的並發問題。
Nginx是如何利用的呢,簡單來說:同樣的 4 個進程,如果採用一個進程負責一個 request 的方式,那麼,同時進來 4 個 request 之後,每個進程就負責其中一個,直至會話關閉。期間,如果有第 5 個request進來了。就無法及時反應了,因為 4 個進程都沒幹完活呢,因此,一般有個調度進程,每當新進來了一個 request ,就新開個進程來處理。
回想下,BIO 是不是存在醬紫的問題?
Nginx 不這樣,每進來一個 request ,會有一個 worker 進程去處理。但不是全程的處理,處理到什麼程度呢?處理到可能發生阻塞的地方,比如向上游(後端)服務器轉發 request ,並等待請求返回。那麼,這個處理的 worker 不會這麼傻等着,他會在發送完請求後,註冊一個事件:「如果 upstream 返回了,告訴我一聲,我再接着干」。於是他就休息去了。此時,如果再有 request 進來,他就可以很快再按這種方式處理。而一旦上游服務器返回了,就會觸發這個事件,worker 才會來接手,這個 request 才會接着往下走。
這就是為什麼說,Nginx 基於事件模型。
由於 web server 的工作性質決定了每個 request 的大部份生命都是在網絡傳輸中,實際上花費在 server 機器上的時間片不多。這是幾個進程就解決高並發的秘密所在。即:
webserver 剛好屬於網絡 IO 密集型應用,不算是計算密集型。
異步,非阻塞,使用 epoll ,和大量細節處的優化。也正是 Nginx 之所以然的技術基石。
什麼是正向代理?一個位於客戶端和原始服務器(origin server)之間的服務器,為了從原始服務器取得內容,客戶端向代理髮送一個請求並指定目標(原始服務器),然後代理向原始服務器轉交請求並將獲得的內容返回給客戶端。
客戶端才能使用正向代理。正向代理總結就一句話:代理端代理的是客戶端。例如說:我們使用的OpenVPN 等等。
什麼是反向代理?反向代理(Reverse Proxy)方式,是指以代理服務器來接受 Internet上的連接請求,然後將請求,發給內部網絡上的服務器並將從服務器上得到的結果返回給 Internet 上請求連接的客戶端,此時代理服務器對外就表現為一個反向代理服務器。
反向代理總結就一句話:代理端代理的是服務端。
反向代理服務器的優點是什麼?反向代理服務器可以隱藏源服務器的存在和特徵。它充當互聯網雲和web服務器之間的中間層。這對於安全方面來說是很好的,特別是當您使用web託管服務時。
Nginx目錄結構有哪些?[root@localhost~]#tree/usr/local/nginx/usr/local/nginx├──client_body_temp├──conf#Nginx所有配置文件的目錄│├──fastcgi.conf#fastcgi相關參數的配置文件│├──fastcgi.conf.default#fastcgi.conf的原始備份文件│├──fastcgi_params#fastcgi的參數文件│├──fastcgi_params.default│├──koi-utf│├──koi-win│├──mime.types#媒體類型│├──mime.types.default│├──nginx.conf#Nginx主配置文件│├──nginx.conf.default│├──scgi_params#scgi相關參數文件│├──scgi_params.default│├──uwsgi_params#uwsgi相關參數文件│├──uwsgi_params.default│└──win-utf├──fastcgi_temp#fastcgi臨時數據目錄├──html#Nginx默認站點目錄│├──50x.html#錯誤頁面優雅替代顯示文件,例如當出現502錯誤時會調用此頁面│└──index.html#默認的首頁文件├──logs#Nginx日誌目錄│├──access.log#訪問日誌文件│├──error.log#錯誤日誌文件│└──nginx.pid#pid文件,Nginx進程啟動後,會把所有進程的ID號寫到此文件├──proxy_temp#臨時目錄├──sbin#Nginx命令目錄│└──nginx#Nginx的啟動命令├──scgi_temp#臨時目錄└──uwsgi_temp#臨時目錄Nginx配置文件nginx.conf有哪些屬性模塊?worker_processes1;#worker進程的數量events{#事件區塊開始worker_connections1024;#每個worker進程支持的最大連接數}#事件區塊結束http{#HTTP區塊開始includemime.types;#Nginx支持的媒體類型庫文件default_typeapplication/octet-stream;#默認的媒體類型sendfileon;#開啟高效傳輸模式keepalive_timeout65;#連接超時server{#第一個Server區塊開始,表示一個獨立的虛擬主機站點listen80;#提供服務的端口,默認80server_namelocalhost;#提供服務的域名主機名location/{#第一個location區塊開始roothtml;#站點的根目錄,相當於Nginx的安裝目錄indexindex.htmlindex.htm;#默認的首頁文件,多個用空格分開}#第一個location區塊結果error_page500502503504/50x.html;#出現對應的http狀態碼時,使用50x.html回應客戶location=/50x.html{#location區塊開始,訪問50x.htmlroothtml;#指定對應的站點目錄為html}}......cookie和session區別?共同:存放用戶信息。存放的形式:key-value格式 變量和變量內容鍵值對。
區別:cookie
session:
Apache: 創建多個進程或線程,而每個進程或線程都會為其分配 cpu 和內存(線程要比進程小的多,所以 worker 支持比 perfork 高的並發),並發過大會榨乾服務器資源。
Nginx: 採用單線程來異步非阻塞處理請求(管理員可以配置 Nginx 主進程的工作進程的數量)(epoll),不會為每個請求分配 cpu 和內存資源,節省了大量資源,同時也減少了大量的 CPU 的上下文切換。所以才使得 Nginx 支持更高的並發。
nginx和apache的區別輕量級,同樣起web服務,比apache占用更少的內存和資源。
抗並發,nginx處理請求是異步非阻塞的,而apache則是阻塞性的,在高並發下nginx能保持低資源,低消耗高性能。
高度模塊化的設計,編寫模塊相對簡單。
最核心的區別在於apache是同步多進程模型,一個連接對應一個進程,nginx是異步的,多個連接可以對應一個進程。

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

Nginx限流就是限制用戶請求速度,防止服務器受不了
限流有3種
Nginx的限流都是基於漏桶流算法
實現三種限流算法
1、正常限制訪問頻率(正常流量):限制一個用戶發送的請求,我Nginx多久接收一個請求。
Nginx中使用ngx_http_limit_req_module模塊來限制的訪問頻率,限制的原理實質是基於漏桶算法原理來實現的。在nginx.conf配置文件中可以使用limit_req_zone命令及limit_req命令限制單個IP的請求處理頻率。
#定義限流維度,一個用戶一分鐘一個請求進來,多餘的全部漏掉limit_req_zone$binary_remote_addrzone=one:10mrate=1r/m;#綁定限流維度server{location/seckill.html{limit_reqzone=zone;proxy_passhttp://lj_seckill;}}1r/s代表1秒一個請求,1r/m一分鐘接收一個請求, 如果Nginx這時還有別人的請求沒有處理完,Nginx就會拒絕處理該用戶請求。
2、突發限制訪問頻率(突發流量):限制一個用戶發送的請求,我Nginx多久接收一個。
上面的配置一定程度可以限制訪問頻率,但是也存在着一個問題:如果突發流量超出請求被拒絕處理,無法處理活動時候的突發流量,這時候應該如何進一步處理呢?
Nginx提供burst參數結合nodelay參數可以解決流量突發的問題,可以設置能處理的超過設置的請求數外能額外處理的請求數。我們可以將之前的例子添加burst參數以及nodelay參數:
#定義限流維度,一個用戶一分鐘一個請求進來,多餘的全部漏掉limit_req_zone$binary_remote_addrzone=one:10mrate=1r/m;#綁定限流維度server{location/seckill.html{limit_reqzone=zoneburst=5nodelay;proxy_passhttp://lj_seckill;}}為什麼就多了一個 burst=5 nodelay; 呢,多了這個可以代表Nginx對於一個用戶的請求會立即處理前五個,多餘的就慢慢來落,沒有其他用戶的請求我就處理你的,有其他的請求的話我Nginx就漏掉不接受你的請求
3、 限制並發連接數Nginx中的ngx_http_limit_conn_module模塊提供了限制並發連接數的功能,可以使用limit_conn_zone指令以及limit_conn執行進行配置。接下來我們可以通過一個簡單的例子來看下:
http{limit_conn_zone$binary_remote_addrzone=myip:10m;limit_conn_zone$server_namezone=myServerName:10m;}server{location/{limit_connmyip10;limit_connmyServerName100;rewrite/http://www.lijie.netpermanent;}}上面配置了單個IP同時並發連接數最多只能10個連接,並且設置了整個虛擬服務器同時最大並發數最多只能100個鏈接。當然,只有當請求的header被服務器處理後,虛擬服務器的連接數才會計數。剛才有提到過Nginx是基於漏桶算法原理實現的,實際上限流一般都是基於漏桶算法和令牌桶算法實現的。
漏桶流算法和令牌桶算法知道?漏桶算法漏桶算法思路很簡單,我們把水比作是請求,漏桶比作是系統處理能力極限,水先進入到漏桶里,漏桶里的水按一定速率流出,當流出的速率小於流入的速率時,由於漏桶容量有限,後續進入的水直接溢出(拒絕請求),以此實現限流。

令牌桶算法的原理也比較簡單,我們可以理解成醫院的掛號看病,只有拿到號以後才可以進行診病。
系統會維護一個令牌(token)桶,以一個恆定的速度往桶里放入令牌(token),這時如果有請求進來想要被處理,則需要先從桶里獲取一個令牌(token),當桶里沒有令牌(token)可取時,則該請求將被拒絕服務。令牌桶算法通過控制桶的容量、發放令牌的速率,來達到對請求的限制。

當上游服務器(真實訪問服務器),一旦出現故障或者是沒有及時相應的話,應該直接輪訓到下一台服務器,保證服務器的高可用
Nginx配置代碼:
server{listen80;server_namewww.lijie.com;location/{###指定上游服務器負載均衡服務器proxy_passhttp://backServer;###nginx與上游服務器(真實訪問的服務器)超時時間後端服務器連接的超時時間_發起握手等候響應超時時間proxy_connect_timeout1s;###nginx發送給上游服務器(真實訪問的服務器)超時時間proxy_send_timeout1s;###nginx接受上游服務器(真實訪問的服務器)超時時間proxy_read_timeout1s;indexindex.htmlindex.htm;}}Nginx怎麼判斷別IP不可訪問?#如果訪問的ip地址為192.168.9.115,則返回403if($remote_addr=192.168.9.115){return403;}在nginx中,如何使用未定義的服務器名稱來阻止處理請求?只需將請求刪除的服務器就可以定義為:
服務器名被保留一個空字符串,他在沒有主機頭字段的情況下匹配請求,而一個特殊的nginx的非標準代碼被返回,從而終止連接。
怎麼限制瀏覽器訪問?##不允許谷歌瀏覽器訪問如果是谷歌瀏覽器返回500if($http_user_agent~Chrome){return500;}Rewrite全局變量是什麼?$remote_addr//獲取客戶端ip$binary_remote_addr//客戶端ip(二進制)$remote_port//客戶端port,如:50472$remote_user//已經經過AuthBasicModule驗證的用戶名$host//請求主機頭字段,否則為服務器名稱,如:blog.sakmon.com$request//用戶請求信息,如:GET?a=1&b=2HTTP/1.1$request_filename//當前請求的文件的路徑名,由root或alias和URIrequest組合而成,如:/2013/81.html$status//請求的響應狀態碼,如:200$body_bytes_sent//響應時送出的body字節數數量。即使連接中斷,這個數據也是精確的,如:40$content_length//等於請求行的「Content_Length」的值$content_type//等於請求行的「Content_Type」的值$http_referer//引用地址$http_user_agent//客戶端agent信息,如:Mozilla/5.0(WindowsNT5.1)AppleWebKit/537.36(KHTML,likeGecko)Chrome/29.0.1547.76Safari/537.36$args//與$query_string相同等於當中URL的參數(GET),如a=1&b=2$document_uri//與$uri相同這個變量指當前的請求URI,不包括任何參數(見$args)如:/2013/81.html$document_root//針對當前請求的根路徑設置值$hostname//如:centos53.localdomain$http_cookie//客戶端cookie信息$cookie_COOKIE//cookieCOOKIE變量的值$is_args//如果有$args參數,這個變量等於」?」,否則等於」",空值,如?$limit_rate//這個變量可以限制連接速率,0表示不限速$query_string//與$args相同等於當中URL的參數(GET),如a=1&b=2$request_body//記錄POST過來的數據信息$request_body_file//客戶端請求主體信息的臨時文件名$request_method//客戶端請求的動作,通常為GET或POST,如:GET$request_uri//包含請求參數的原始URI,不包含主機名,如:/2013/81.html?a=1&b=2$scheme//HTTP方法(如http,https),如:http$uri//這個變量指當前的請求URI,不包括任何參數(見$args)如:/2013/81.html$request_completion//如果請求結束,設置為OK.當請求未結束或如果該請求不是請求鏈串的最後一個時,為空(Empty),如:OK$server_protocol//請求使用的協議,通常是HTTP/1.0或HTTP/1.1,如:HTTP/1.1$server_addr//服務器IP地址,在完成一次系統調用後可以確定這個值$server_name//服務器名稱,如:blog.sakmon.com$server_port//請求到達服務器的端口號,如:80Nginx 如何實現後端服務的健康檢查?方式一,利用 nginx 自帶模塊 ngx_http_proxy_module 和 ngx_http_upstream_module 對後端節點做健康檢查。
方式二(推薦),利用 nginx_upstream_check_module 模塊對後端節點做健康檢查。
Nginx 如何開啟壓縮?開啟nginx gzip壓縮後,網頁、css、js等靜態資源的大小會大大的減少,從而可以節約大量的帶寬,提高傳輸效率,給用戶快的體驗。雖然會消耗cpu資源,但是為了給用戶更好的體驗是值得的。
開啟的配置如下:
將以上配置放到nginx.conf的http{ … }節點中。
http{#開啟gzipgzipon;#啟用gzip壓縮的最小文件;小於設置值的文件將不會被壓縮gzip_min_length1k;#gzip壓縮級別1-10gzip_comp_level2;#進行壓縮的文件類型。gzip_typestext/plainapplication/javascriptapplication/x-javascripttext/cssapplication/xmltext/javascriptapplication/x-httpd-phpimage/jpegimage/gifimage/png;#是否在httpheader中添加Vary:Accept-Encoding,建議開啟gzip_varyon;}保存並重啟nginx,刷新頁面(為了避免緩存,請強制刷新)就能看到效果了。以谷歌瀏覽器為例,通過F12看請求的響應頭部:
我們可以先來對比下,如果我們沒有開啟zip壓縮之前,我們的對應的文件大小,如下所示:

現在我們開啟了gzip進行壓縮後的文件的大小,可以看到如下所示:

並且我們查看響應頭會看到gzip這樣的壓縮,如下所示

gzip壓縮前後效果對比:jquery原大小90kb,壓縮後只有30kb。
gzip雖然好用,但是以下類型的資源不建議啟用。
1、圖片類型原因:圖片如jpg、png本身就會有壓縮,所以就算開啟gzip後,壓縮前和壓縮後大小沒有多大區別,所以開啟了反而會白白的浪費資源。(Tips:可以試試將一張jpg圖片壓縮為zip,觀察大小並沒有多大的變化。雖然zip和gzip算法不一樣,但是可以看出壓縮圖片的價值並不大)
2、大文件原因:會消耗大量的cpu資源,且不一定有明顯的效果。
ngx_http_upstream_module的作用是什麼?ngx_http_upstream_module用於定義可通過fastcgi傳遞、proxy傳遞、uwsgi傳遞、memcached傳遞和scgi傳遞指令來引用的服務器組。
什麼是C10K問題?C10K問題是指無法同時處理大量客戶端(10,000)的網絡套接字。
Nginx是否支持將請求壓縮到上游?您可以使用Nginx模塊gunzip將請求壓縮到上游。gunzip模塊是一個過濾器,它可以對不支持「gzip」編碼方法的客戶機或服務器使用「內容編碼:gzip」來解壓縮響應。
如何在Nginx中獲得當前的時間?要獲得Nginx的當前時間,必須使用SSI模塊、和date_local的變量。
Proxy_set_headerTHE-TIME$date_gmt;用Nginx服務器解釋-s的目的是什麼?用於運行Nginx -s參數的可執行文件。
如何在Nginx服務器上添加模塊?在編譯過程中,必須選擇Nginx模塊,因為Nginx不支持模塊的運行時間選擇。
生產中如何設置worker進程的數量呢?在有多個cpu的情況下,可以設置多個worker,worker進程的數量可以設置到和cpu的核心數一樣多,如果在單個cpu上起多個worker進程,那麼操作系統會在多個worker之間進行調度,這種情況會降低系統性能,如果只有一個cpu,那麼只啟動一個worker進程就可以了。
nginx狀態碼499:
服務端處理時間過長,客戶端主動關閉了連接。
502:
(1).FastCGI進程是否已經啟動
(2).FastCGI worker進程數是否不夠
(3).FastCGI執行時間過長
(4).FastCGI Buffer不夠,nginx和apache一樣,有前端緩衝限制,可以調整緩衝參數
(5). Proxy Buffer不夠,如果你用了Proxying,調整
(6).php腳本執行時間過長
來源:blog.csdn.net/wuzhiwei549/article/details/122758937 推薦 Java面試題寶典 技術內卷群,一起來學習!! PS:因為公眾號平台更改了推送規則,如果不想錯過內容,記得讀完點一下「在看」,加個「星標」,這樣每次新文章推送才會第一時間出現在你的訂閱列表里。點「在看」支持我們吧!