Nginx是一款輕量級的 Web服務器 / 反向代理服務器 / 電子郵件(IMAP/POP3)代理服務器,主要的優勢是:javascript
支持高併發鏈接,尤爲是靜態界面,官方測試Nginx可以支撐5萬併發鏈接php
內存佔用極低css
配置簡單,使用靈活,能夠基於自身須要加強其功能,同時支持自定義模塊的開發html
使用靈活:能夠根據須要,配置不一樣的負載均衡模式,URL地址重寫等功能前端
穩定性高,在進行反向代理時,宕機的機率很低java
支持熱部署,應用啓動重載很是迅速node
安裝linux
文件下載地址:http://nginx.org/en/docs/windows.htmlnginx
若是下載很慢能夠用該連接:web
百度雲盤連接: https://pan.baidu.com/s/1r3mSEGhmz4HA46Cw9w6QTQ 提取碼: d8bi
解壓便可
基本命令
# 啓動 # 建議使用第一種,第二種會使窗口一直處於執行中,不能進行其餘命令操做 C:\server\nginx-1.19.2> start nginx C:\server\nginx-1.19.2> nginx.exe # 中止 # stop是快速中止nginx,可能並不保存相關信息;quit是完整有序的中止nginx,並保存相關信息 C:\server\nginx-1.19.2> nginx.exe -s stop C:\server\nginx-1.19.2> nginx.exe -s quit # 重載Nginx # 當配置信息修改,須要從新載入這些配置時使用此命令 C:\server\nginx-1.19.2> nginx.exe -s reload # 從新打開日誌文件 C:\server\nginx-1.19.2> nginx.exe -s reopen # 查看Nginx版本 C:\server\nginx-1.19.2> nginx -v # 查看配置文件是否正確 C:\server\nginx-1.19.2> nginx -t
簡單Demo
利用SwitchHost
軟件編輯域名和IP的映射關係,或到目錄C:\Windows\System32\drivers\etc
下,編輯hosts
文件,增長配置以下(Mac 同理)
127.0.0.1 kerwin.demo.com
PS:推薦使用軟件SwitchHost
,工做時幾乎是必用的
修改配置,如圖所示:
效果如圖所示:
網關:能夠簡單的理解爲用戶請求和服務器響應的關口,即面向用戶的總入口
網關能夠攔截客戶端全部請求,對該請求進行權限控制、負載均衡、日誌管理、接口調用監控等,所以不管使用什麼架構體系,均可以使用Nginx
做爲最外層的網關
虛擬主機的定義:虛擬主機是一種特殊的軟硬件技術,它能夠將網絡上的每一臺計算機分紅多個虛擬主機,每一個虛擬主機能夠獨立對外提供 www 服務,這樣就能夠實現一臺主機對外提供多個 web 服務,每一個虛擬主機之間是獨立的,互不影響的。
經過 Nginx 能夠實現虛擬主機的配置,Nginx 支持三種類型的虛擬主機配置
表現形式其實你們多見過,即:
# 每一個 server 就是一個虛擬主機 http { # ... server{ # ... } # ... server{ # ... } }
在Nginx
的配置文件中,咱們常常能夠看到這樣的配置:
location / { #.... }
location
在此處就起到了路由的做用,好比咱們在同一個虛擬主機內定義兩個不一樣的路由,以下:
location / { proxy_pass https://www.baidu.com/; } location /api { proxy_pass https://apinew.juejin.im/user_api/v1/user/get?aid=2608&user_id=1275089220013336¬_self=1; }
效果以下:
由於路由的存在,爲咱們後續解決跨域問題
提供了必定的思路,同時配置內容和API接口等更加方便
PS:路由的功能很是強大,支持正則匹配
此處額外解釋一下proxy_pass
的含義
在Nginx
中配置proxy_pass
代理轉發時,若是在proxy_pass
後面的url加 /
,表示絕對根路徑;
若是沒有/
,表示相對路徑
正向代理
反向代理
共同點
區別
靜態服務器是Nginx
的強項,使用很是容易,在默認配置下自己就是指向了靜態的HTML界面,如:
location / { root html; index index.html index.htm; }
因此前端同窗們,若是構建好了界面,能夠進行相應的配置,把界面指向目標文件夾中便可,root
指的是html
文件夾
負載均衡功能是Nginx
另外一大殺手鐗,一共有5種方式,着重介紹一下。
每一個請求按時間順序逐一分配到不一樣的後端服務器,若是後端服務器down掉,能自動剔除,配置以下:
upstream tomcatserver { server 192.168.0.1; server 192.168.0.2; }
輪詢策略是默認的負載均衡策略
即在輪詢的基礎之上,增長權重的概念,weight
和訪問比率成正比,用於後端服務器性能不均的狀況,配置以下:
upstream tomcatserver { server 192.168.0.1 weight=1; server 192.168.0.2 weight=10; }
每一個請求按訪問ip的hash結果分配,這樣每一個訪客固定訪問一個後端服務器,能夠解決session的問題,配置以下:
upstream tomcatserver { ip_hash; server 192.168.0.14:88; server 192.168.0.15:80; }
第三方提供的負載均衡策略,按後端服務器的響應時間來分配請求,響應時間短的優先分配,生產環境中有各類狀況可能致使響應時間波動,須要慎用
upstream tomcatserver { server server1; server server2; fair; }
第三方提供的負載均衡策略,按訪問url的hash結果來分配請求,使每一個url定向到同一個後端服務器
upstream tomcatserver { server squid1:3128; server squid2:3128; hash $request_uri; hash_method crc32; }
先來看看Nginx
模塊架構圖:
這5個模塊由上到下重要性一次遞減。
(1)核心模塊;
核心模塊是Nginx服務器正常運行必不可少的模塊,如同操做系統的內核。它提供了Nginx最基本的核心服務。像進程管理、權限控制、錯誤日誌記錄等;
(2)標準HTTP模塊;
標準HTTP模塊支持標準的HTTP的功能,如:端口配置,網頁編碼設置,HTTP響應頭設置等;
(3)可選HTTP模塊;
可選HTTP模塊主要用於擴展標準的HTTP功能,讓Nginx能處理一些特殊的服務,如:解析GeoIP請求,SSL支持等;
(4)郵件服務模塊;
郵件服務模塊主要用於支持Nginx的郵件服務;
(5)第三方模塊;
第三方模塊是爲了擴展Nginx服務器應用,完成開發者想要的功能,如:Lua支持,JSON支持等;
模塊化設計使得Nginx方便開發和擴展,功能很強大
基於上文中的Nginx
模塊化結構,咱們很容易想到,在請求的處理階段也會經歷諸多的過程,Nginx
將各功能模塊組織成一條鏈,當有請求到達的時候,請求依次通過這條鏈上的部分或者所有模塊,進行處理,每一個模塊實現特定的功能。
一個 HTTP Request 的處理過程:
Nginx 在啓動後,會有一個 master
進程和多個 worker
進程。
master
進程主要用來管理worker
進程,包括接收來自外界的信號,向各 worker 進程發送信號,監控 worker 進程的運行狀態以及啓動 worker 進程。
worker
進程是用來處理來自客戶端的請求事件。多個 worker 進程之間是對等的,它們同等競爭來自客戶端的請求,各進程互相獨立,一個請求只能在一個 worker 進程中處理。worker 進程的個數是能夠設置的,通常會設置與機器 CPU 核數一致,這裏面的緣由與事件處理模型有關
Nginx 的進程模型,可由下圖來表示:
這種設計帶來如下優勢:
1) 利用多核系統的併發處理能力
現代操做系統已經支持多核 CPU 架構,這使得多個進程能夠分別佔用不一樣的 CPU 核心來工做。Nginx 中全部的 worker 工做進程都是徹底平等的。這提升了網絡性能、下降了請求的時延。
2) 負載均衡
多個 worker 工做進程經過進程間通訊來實現負載均衡,即一個請求到來時更容易被分配到負載較輕的 worker 工做進程中處理。這也在必定程度上提升了網絡性能、下降了請求的時延。
3) 管理進程會負責監控工做進程的狀態,並負責管理其行爲
管理進程不會佔用多少系統資源,它只是用來啓動、中止、監控或使用其餘行爲來控制工做進程。首先,這提升了系統的可靠性,當 worker 進程出現問題時,管理進程能夠啓動新的工做進程來避免系統性能的降低。其次,管理進程支持 Nginx 服務運行中的程序升級、配置項修改等操做,這種設計使得動態可擴展性、動態定製性較容易實現。
什麼是驚羣現象?
驚羣效應(thundering herd)是指多進程(多線程)在同時阻塞等待同一個事件的時候(休眠狀態),若是等待的這個事件發生,那麼他就會喚醒等待的全部進程(或者線程),可是最終卻只能有一個進程(線程)得到這個時間的「控制權」,對該事件進行處理,而其餘進程(線程)獲取「控制權」失敗,只能從新進入休眠狀態,這種現象和性能浪費就叫作驚羣效應。
上文中介紹了Nginx的多進程模型,而典型的多進程模型正如文中所說,多個worker進程之間是對等的,所以當一個請求到來的時候,全部進程會同時開始競爭,最終執行的又只有一個,這樣勢必會形成資源的浪費。
Nginx解決該問題的思路是:不讓多個進程在同一時間監聽接受鏈接的socket,而是讓每一個進程輪流監聽,這樣當有鏈接過來的時候,就只有一個進程在監聽那確定就沒有驚羣的問題。
具體作法是:利用一把進程間鎖,每一個進程中都嘗試得到這把鎖,若是獲取成功將監聽socket加入wait集合中,並設置超時等待鏈接到來,沒有得到鎖的進程則將監聽socket從wait集合去除。
承接上文,咱們知道了Nginx的多進程模型後瞭解到,其工做進程實際上只有幾個,但爲何依然能得到如此高的併發性能,固然與其採用的事件驅動模型和異步非阻塞IO的方式來處理請求有關。
Nginx服務器響應和處理Web請求的過程,是基於事件驅動模型的,它包含事件收集器、事件發送器和事件處理器等三部分基本單元,着重關注事件處理器
,而通常狀況下事件處理器有這麼幾種辦法:
第三種方式,在編寫程序代碼時,邏輯比前面兩種都複雜。大多數網絡服務器採用了第三種方式,逐漸造成了所謂的事件驅動處理庫
。
事件驅動處理庫
又被稱爲多路IO複用方法
,最多見的包括如下三種:select模型,poll模型和epoll模型。
其中Nginx就默認使用的是epoll
模型,同時也支持其餘事件模型。
epoll
的幫助就在於其提供了一種機制,可讓進程同時處理多個併發請求,不用關心IO調用的具體狀態。IO調用徹底由事件驅動模型來管理,這樣一來,當某個工做進程接收到客戶端的請求之後,調用IO進行處理,若是不能當即獲得結果,就去處理其餘的請求;而工做進程在此期間也無需等待響應,能夠去處理其餘事情;當IO返回時,epoll
就會通知此工做進程;該進程獲得通知後,會來繼續處理未完的請求
在生產環境或者開發環境中Nginx通常會代理多個虛擬主機,若是把全部的配置文件寫在默認的nginx.conf
中,看起來會很是臃腫,所以建議將每個虛擬文件單獨放置一個文件夾,Nginx支持這樣的配置,以下:
http { # 省略中間配置 # 引用該目錄下以 .conf 文件結尾的配置 include /etc/nginx/conf.d/*.conf; }
具體文件配置如:
# Demo upstream web_pro_testin { server 10.42.46.70:6003 max_fails=3 fail_timeout=20s; ip_hash; } server { listen 80; server_name web.pro.testin.cn; location / { proxy_pass http://web_pro_testin; proxy_redirect off; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } location ~ ^/(WEB-INF)/ { deny all; } }
# 運行用戶 user www-data; # 啓動進程,一般設置成和cpu的數量相等 worker_processes 6; # 全局錯誤日誌定義類型,[debug | info | notice | warn | error | crit] error_log logs/error.log; error_log logs/error.log notice; error_log logs/error.log info; # 進程pid文件 pid /var/run/nginx.pid; # 工做模式及鏈接數上限 events { # 僅用於linux2.6以上內核,能夠大大提升nginx的性能 use epoll; # 單個後臺worker process進程的最大併發連接數 worker_connections 1024; # 客戶端請求頭部的緩衝區大小 client_header_buffer_size 4k; # keepalive 超時時間 keepalive_timeout 60; # 告訴nginx收到一個新鏈接通知後接受盡量多的鏈接 # multi_accept on; } #設定http服務器,利用它的反向代理功能提供負載均衡支持 http { # 文件擴展名與文件類型映射表義 include /etc/nginx/mime.types; # 默認文件類型 default_type application/octet-stream; # 默認編碼 charset utf-8; # 服務器名字的hash表大小 server_names_hash_bucket_size 128; # 客戶端請求頭部的緩衝區大小 client_header_buffer_size 32k; # 客戶請求頭緩衝大小 large_client_header_buffers 4 64k; # 設定經過nginx上傳文件的大小 client_max_body_size 8m; # 開啓目錄列表訪問,合適下載服務器,默認關閉。 autoindex on; # sendfile 指令指定 nginx 是否調用 sendfile 函數(zero copy 方式)來輸出文件,對於普通應用, # 必須設爲 on,若是用來進行下載等應用磁盤IO重負載應用,可設置爲 off,以平衡磁盤與網絡I/O處理速度 sendfile on; # 此選項容許或禁止使用socke的TCP_CORK的選項,此選項僅在使用sendfile的時候使用 #tcp_nopush on; # 鏈接超時時間(單秒爲秒) keepalive_timeout 65; # gzip模塊設置 gzip on; #開啓gzip壓縮輸出 gzip_min_length 1k; #最小壓縮文件大小 gzip_buffers 4 16k; #壓縮緩衝區 gzip_http_version 1.0; #壓縮版本(默認1.1,前端若是是squid2.5請使用1.0) gzip_comp_level 2; #壓縮等級 gzip_types text/plain application/x-javascript text/css application/xml; gzip_vary on; # 開啓限制IP鏈接數的時候須要使用 #limit_zone crawler $binary_remote_addr 10m; # 指定虛擬主機的配置文件,方便管理 include /etc/nginx/conf.d/*.conf; # 負載均衡配置 upstream mysvr { # 請見上文中的五種配置 } # 虛擬主機的配置 server { # 監聽端口 listen 80; # 域名能夠有多個,用空格隔開 server_name www.jd.com jd.com; # 默認入口文件名稱 index index.html index.htm index.php; root /data/www/jd; # 圖片緩存時間設置 location ~ .*.(gif|jpg|jpeg|png|bmp|swf)${ expires 10d; } #JS和CSS緩存時間設置 location ~ .*.(js|css)?${ expires 1h; } # 日誌格式設定 #$remote_addr與$http_x_forwarded_for用以記錄客戶端的ip地址; #$remote_user:用來記錄客戶端用戶名稱; #$time_local: 用來記錄訪問時間與時區; #$request: 用來記錄請求的url與http協議; #$status: 用來記錄請求狀態;成功是200, #$body_bytes_sent :記錄發送給客戶端文件主體內容大小; #$http_referer:用來記錄從那個頁面連接訪問過來的; log_format access '$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" $http_x_forwarded_for'; # 定義本虛擬主機的訪問日誌 access_log /usr/local/nginx/logs/host.access.log main; access_log /usr/local/nginx/logs/host.access.404.log log404; # 對具體路由進行反向代理 location /connect-controller { proxy_pass http://127.0.0.1:88; proxy_redirect off; proxy_set_header X-Real-IP $remote_addr; # 後端的Web服務器能夠經過X-Forwarded-For獲取用戶真實IP proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $host; # 容許客戶端請求的最大單文件字節數 client_max_body_size 10m; # 緩衝區代理緩衝用戶端請求的最大字節數, client_body_buffer_size 128k; # 表示使nginx阻止HTTP應答代碼爲400或者更高的應答。 proxy_intercept_errors on; # nginx跟後端服務器鏈接超時時間(代理鏈接超時) proxy_connect_timeout 90; # 後端服務器數據回傳時間_就是在規定時間以內後端服務器必須傳完全部的數據 proxy_send_timeout 90; # 鏈接成功後,後端服務器響應的超時時間 proxy_read_timeout 90; # 設置代理服務器(nginx)保存用戶頭信息的緩衝區大小 proxy_buffer_size 4k; # 設置用於讀取應答的緩衝區數目和大小,默認狀況也爲分頁大小,根據操做系統的不一樣多是4k或者8k proxy_buffers 4 32k; # 高負荷下緩衝大小(proxy_buffers*2) proxy_busy_buffers_size 64k; # 設置在寫入proxy_temp_path時數據的大小,預防一個工做進程在傳遞文件時阻塞太長 # 設定緩存文件夾大小,大於這個值,將從upstream服務器傳 proxy_temp_file_write_size 64k; } # 動靜分離反向代理配置(多路由指向不一樣的服務端或界面) location ~ .(jsp|jspx|do)?$ { proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_pass http://127.0.0.1:8080; } } }
思路有兩個:
根據用戶設備不一樣返回不一樣樣式的站點,之前常用的是純前端的自適應佈局,但不管是複雜性和易用性上面仍是不如分開編寫的好,好比咱們常見的淘寶、京東......這些大型網站就都沒有采用自適應,而是用分開製做的方式,根據用戶請求的 user-agent
來判斷是返回 PC 仍是 H5 站點
Nginx按請求速率限速模塊使用的是漏桶算法,即可以強行保證請求的實時處理速度不會超過設置的閾值,如:
http { limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s; server { location /search/ { limit_req zone=one burst=5 nodelay; } } }
如:圖片防盜鏈,請求過濾,泛域名轉發,配置HTTPS等等
可參考文章:《Nginx 從入門到實踐,萬字詳解!》
見上文中Nginx在架構體系中的做用,配合Nginx還能作什麼做答便可
理解網關的必要性,以及Nginx保證高可用,負載均衡的能力
若是一個server採用一個進程負責一個request的方式,那麼進程數就是併發數。那麼顯而易見的,就是會有不少進程在等待中。等什麼?最多的應該是等待網絡傳輸。
而nginx 的異步非阻塞工做方式正是利用了這點等待的時間。在須要等待的時候,這些進程就空閒出來待命了。所以表現爲少數幾個進程就解決了大量的併發問題。
nginx是如何利用的呢,簡單來講:一樣的4個進程,若是採用一個進程負責一個request的方式,那麼,同時進來4個request以後,每一個進程就負責其中一個,直至會話關閉。期間,若是有第5個request進來了。就沒法及時反應了,由於4個進程都沒幹完活呢,所以,通常有個調度進程,每當新進來了一個request,就新開個進程來處理。
nginx不這樣,每進來一個request,會有一個worker進程去處理。但不是全程的處理,處理到什麼程度呢?處理到可能發生阻塞的地方,好比向上遊(後端)服務器轉發request,並等待請求返回。那麼,這個處理的worker不會這麼傻等着,他會在發送完請求後,註冊一個事件:「若是upstream返回了,告訴我一聲,我再接着幹」。因而他就休息去了。此時,若是再有request 進來,他就能夠很快再按這種方式處理。而一旦上游服務器返回了,就會觸發這個事件,worker纔會來接手,這個request纔會接着往下走。
因爲web server的工做性質決定了每一個request的大部份生命都是在網絡傳輸中,實際上花費在server機器上的時間片很少。這是幾個進程就解決高併發的祕密所在。
總結:事件模型,異步非阻塞,多進程模型加上細節優化的共同做用
見上文
見上文
見上文
深刻理解多進程模型加上異步非阻塞IO的好處以及多線程模型中上下文切換的劣勢
很是耗費服務器的CPU
實際上有兩種,多進程和單進程,可是實際工做中都是多進程的
若是你以爲這篇內容對你挺有幫助的話: