這篇文章主要講解了“Nginx的概念和用法”,文中的講解內(nèi)容簡單清晰,易于學(xué)習(xí)與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“Nginx的概念和用法”吧!
成都創(chuàng)新互聯(lián)主要從事成都網(wǎng)站設(shè)計、網(wǎng)站建設(shè)、網(wǎng)頁設(shè)計、企業(yè)做網(wǎng)站、公司建網(wǎng)站等業(yè)務(wù)。立足成都服務(wù)九臺,十余年網(wǎng)站建設(shè)經(jīng)驗,價格優(yōu)惠、服務(wù)專業(yè),歡迎來電咨詢建站服務(wù):13518219792
基礎(chǔ)篇
一、環(huán)境
服務(wù)器版本:CentOS 7.2
為了保證學(xué)習(xí)階段不遇到奇怪的事情,請保證以下四點(大神選擇性無視)
1. 確認系統(tǒng)網(wǎng)絡(luò)
2. 確認yum可用
3. 確認關(guān)閉iptables
4. 確認停用selinux
#查看iptables狀態(tài) systemctl status firewalld.service #關(guān)閉防火墻(臨時關(guān)閉) systemctl stop firewalld.service #查看SELinux狀態(tài) getenforce #臨時關(guān)閉SELinux setenforce 0
安裝一些系統(tǒng)基本工具,正常情況系統(tǒng)都會自帶(沒有在裝哦)
yum -y install gcc gcc-c++ autoconf pcre pcre-devel make automake yum -y install wget httpd-tools vim
Nginx是一個開源且高性能、可靠的HTTP中間件、代理服務(wù)
其他的HTTP服務(wù):
1. HTTPD-Apache基金會
2. IIS-微軟
3. GWS-Google(不對外開放)
近幾年,Nginx的市場占有率越來越高,一度飆升,為什么呢?接下來我們就知道了!
1. IO多路復(fù)用epoll(IO復(fù)用)
如何理解呢?舉個例子吧!
有A、B、C三個老師,他們都遇到一個難題,要幫助一個班級的學(xué)生解決課堂作業(yè)。
老師A采用從第一排開始一個學(xué)生一個學(xué)生輪流解答的方式去回答問題,老師A浪費了很多時間,并且有的學(xué)生作業(yè)還沒有完成呢,老師就來了,反反復(fù)復(fù)效率極慢。
老師B是一個忍者,他發(fā)現(xiàn)老師A的方法行不通,于是他使用了影分身術(shù),分身出好幾個自己同一時間去幫好幾個同學(xué)回答問題,最后還沒回答完,老師B消耗光了能量累倒了。
老師C比較精明,他告訴學(xué)生,誰完成了作業(yè)舉手,有舉手的同學(xué)他才去指導(dǎo)問題,他讓學(xué)生主動發(fā)聲,分開了“并發(fā)”。
這個老師C就是Nginx。
2. 輕量級
功能模塊少 - Nginx僅保留了HTTP需要的模塊,其他都用插件的方式,后天添加
代碼模塊化 - 更適合二次開發(fā),如阿里巴巴Tengine
3. CPU親和
把CPU核心和Nginx工作進程綁定,把每個worker進程固定在一個CPU上執(zhí)行,減少切換CPU的cache miss,從而提高性能。
本人使用了鳥哥的lnmp集成包 https://lnmp.org,簡單方便-推薦!
#執(zhí)行這句語句,根據(jù)指引,將安裝 nginx php MySQL 可進入lnmp官網(wǎng)查看更詳細的過程 #默認安裝目錄/usr/local wget -c http://soft.vpser.net/lnmp/lnmp1.4.tar.gz && tar zxf lnmp1.4.tar.gz && cd lnmp1.4 && ./install.sh lnmp #默認安裝目錄 /usr/local
#打開主配置文件,若你是用lnmp環(huán)境安裝 vim /usr/local/nginx/conf/nginx.conf ---------------------------------------- user #設(shè)置nginx服務(wù)的系統(tǒng)使用用戶 worker_processes #工作進程數(shù) 一般情況與CPU核數(shù)保持一致 error_log #nginx的錯誤日志 pid #nginx啟動時的pid events { worker_connections #每個進程允許最大連接數(shù) use #nginx使用的內(nèi)核模型 }
我們使用 nginx 的 http 服務(wù),在配置文件 nginx.conf 中的 http 區(qū)域內(nèi),配置無數(shù)個 server ,每一個 server 對應(yīng)這一個虛擬主機或者域名
http { ... ... #后面再詳細介紹 http 配置項目 server { listen 80 #監(jiān)聽端口; server_name localhost #地址 location / { #訪問首頁路徑 root /xxx/xxx/index.html #默認目錄 index index.html index.htm #默認文件 } error_page 500 504 /50x.html #當(dāng)出現(xiàn)以上狀態(tài)碼時從新定義到50x.html location = /50x.html { #當(dāng)訪問50x.html時 root /xxx/xxx/html #50x.html 頁面所在位置 } } server { ... ... } }
一個 server 可以出現(xiàn)多個 location ,我們對不同的訪問路徑進行不同情況的配置
我們再來看看 http 的配置詳情
http { sendfile on #高效傳輸文件的模式 一定要開啟 keepalive_timeout 65 #客戶端服務(wù)端請求超時時間 log_format main XXX #定義日志格式 代號為main access_log /usr/local/access.log main #日志保存地址 格式代碼 main }
查看 nginx 已開啟和編聯(lián)進去的模塊,模塊太多了,就不在這長篇大論,有需要自行百度吧~
#大寫V查看所有模塊,小寫v查看版本 nginx -V # 查看此配置文件 是否存在語法錯誤 nginx -tc /usr/local/nginx/conf/nginx.conf
1.靜態(tài)資源類型
非服務(wù)器動態(tài)運行生成的文件,換句話說,就是可以直接在服務(wù)器上找到對應(yīng)文件的請求
瀏覽器端渲染:HTML,CSS,JS
圖片:JPEG,GIF,PNG
視頻:FLV,MPEG
文件:TXT,任意下載文件
2.靜態(tài)資源服務(wù)場景-cdn
什么是CDN?例如一個北京用戶要請求一個文件,而文件放在的新疆的資源存儲中心,如果直接請求新疆距離太遠,延遲久。使用nginx靜態(tài)資源回源,分發(fā)給北京的資源存儲中心,讓用戶請求的動態(tài)定位到北京的資源存儲中心請求,實現(xiàn)傳輸延遲的最小化
2.nginx靜態(tài)資源配置
配置域:http、server、location #文件高速讀取 http { sendfile on; } #在 sendfile 開啟的情況下,開啟 tcp_nopush 提高網(wǎng)絡(luò)包傳輸效率 #tcp_nopush 將文件一次性一起傳輸給客戶端,就好像你有十個包裹,快遞員一次送一個,來回十趟,開啟后,快遞員講等待你十個包裹都派件,一趟一起送給你 http { sendfile on; tcp_nopush on; } #tcp_nodelay 開啟實時傳輸,傳輸方式與 tcp_nopush 相反,追求實時性,但是它只有在長連接下才生效 http { sendfile on; tcp_nopush on; tcp_nodelay on; } #將訪問的文件壓縮傳輸 (減少文件資源大小,提高傳輸速度) #當(dāng)訪問內(nèi)容以gif或jpg結(jié)尾的資源時 location ~ .*\.(gif|jpg)$ { gzip on; #開啟 gzip_http_version 1.1; #服務(wù)器傳輸版本 gzip_comp_level 2; #壓縮比,越高壓縮越多,壓縮越高可能會消耗服務(wù)器性能 gzip_types text/plain application/javascript application/x-javascript text/javascript text/css application/xml application/xml+rss image/jpeg image/gif image/png; #壓縮文件類型 root /opt/app/code; #對應(yīng)目錄(去該目錄下尋找對應(yīng)文件) } #直接訪問已壓縮文件 #當(dāng)訪問路徑以download開頭時,如www.baidu.com/download/test.img #去/opt/app/code目錄下尋找test.img.gz文件,返回到前端時已是可以瀏覽的img文件 location ~ load^/download { gzip_static on #開啟; tcp_nopush on; root /opt/app/code; }
HTTP協(xié)議定義的緩存機制(如:Expires; Cache-control等 )
減少服務(wù)端的消耗,降低延遲
1.瀏覽器無緩存
瀏覽器請求 -> 無緩存 -> 請求WEB服務(wù)器 -> 請求相應(yīng) -> 呈現(xiàn)
在呈現(xiàn)階段會根據(jù)緩存的設(shè)置在瀏覽器中生成緩存
2.瀏覽器有緩存
瀏覽器請求 -> 有緩存 -> 校驗本地緩存時間是否過期 -> 沒有過期 -> 呈現(xiàn)
若過期從新請求WEB服務(wù)器
3.語法配置
location ~ .*\.(html|htm)$ { expires 12h; #緩存12小時 }
服務(wù)器響應(yīng)靜態(tài)文件時,請求頭信息會帶上 etag 和 last_modified_since 2個標簽值,瀏覽器下次去請求時,頭信息發(fā)送這兩個標簽,服務(wù)器檢測文件有沒有發(fā)生變化,如無,直接頭信息返 etag 和last_modified_since,狀態(tài)碼為 304 ,瀏覽器知道內(nèi)容無改變,于是直接調(diào)用本地緩存,這個過程也請求了服務(wù),但是傳著的內(nèi)容極少
開發(fā)nginx跨站訪問設(shè)置
location ~ .*\.(html|htm)$ { add_header Access-Control-Allow-Origin *; add_header Access-Control-Allow-Methods GET,POST,PUT,DELETE,OPTIONS; #Access-Control-Allow-Credentials true #允許cookie跨域 }
在響應(yīng)中指定 Access-Control-Allow-Credentials 為 true 時,Access-Control-Allow-Origin 不能指定為 *,需要指定到具體域名
相關(guān)跨域內(nèi)容可參考 Laravel 跨域功能中間件 使用代碼實現(xiàn)跨域,原理與nginx跨域配置相同
防止服務(wù)器內(nèi)的靜態(tài)資源被其他網(wǎng)站所套用
此處介紹的 nginx 防盜鏈為基礎(chǔ)方式,其它更加深入的方式將在之后的文章介紹
首先,需要理解一個nginx變量
$http_referer #表示當(dāng)前請求上一次頁面訪問的地址,換句話說,訪問 www.baidu.com 主頁,這是第一次訪問,所以 $http_referer 為空,但是 訪問此頁面的時候還需要獲取一張首頁圖片,再請求這張圖片的時候 $http_referer 就為 www.baidu.com
然后配置
location ~ .*\.(jpg|gif)$ { #valid_referers 表示我們允許哪些 $http_referer 來訪問 #none 表示沒有帶 $http_referer,如第一次訪問時 $http_referer 為空 #blocked 表示 $http_referer 不是標準的地址,非正常域名等 #只允許此ip valid_referers none blocked 127.xxx.xxx.xx if ($invalid_referer) { #不滿足情況下變量值為1 return 403; } }
Nginx可以實現(xiàn)多種代理方式
HTTP
ICMPPOPIMAP
HTTPS
RTMP
1. 代理區(qū)別
區(qū)別在于代理的對象不一樣
正向代理代理的對象是客戶端
反向代理代理的對象是服務(wù)端
2. 反向代理
語法:proxy_pass URL 默認:—— 位置:loaction #代理端口 #場景:服務(wù)器80端口開放,8080端口對外關(guān)閉,客戶端需要訪問到8080 #在nginx中配置proxy_pass代理轉(zhuǎn)發(fā)時,如果在proxy_pass后面的url加/,表示絕對根路徑;如果沒有/,表示相對路徑,把匹配的路徑部分也給代理走 server { listen 80; location / { proxy_pass http://127.0.0.1:8080/; proxy_redirect default; proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; #獲取客戶端真實IP proxy_connect_timeout 30; #超時時間 proxy_send_timeout 60; proxy_read_timeout 60; proxy_buffer_size 32k; proxy_buffering on; #開啟緩沖區(qū),減少磁盤io proxy_buffers 4 128k; proxy_busy_buffers_size 256k; proxy_max_temp_file_size 256k; #當(dāng)超過內(nèi)存允許儲蓄大小,存到文件 } }
負載均衡的實現(xiàn)方法就是我們上章介紹的反向代理 。將客戶的請求通過 nginx 分發(fā)(反向代理)到一組多臺不同的服務(wù)器上
這一組服務(wù)器我們稱為 服務(wù)池(upstream server),池內(nèi)的每一個服務(wù)器稱為一個 單元,服務(wù)池內(nèi)將對每一個單元進行請求輪訓(xùn),實現(xiàn)負載均衡
#配置 語法:upstream name ... 默認:—— 位置:http upstream #自定義組名 { server x1.baidu.com; #可以是域名 server x2.baidu.com; #server x3.baidu.com #down 不參與負載均衡 #weight=5; 權(quán)重,越高分配越多 #backup; 預(yù)留的備份服務(wù)器 #max_fails 允許失敗的次數(shù) #fail_timeout 超過失敗次數(shù)后,服務(wù)暫停時間 #max_coons 限制最大的接受的連接數(shù) #根據(jù)服務(wù)器性能不同,配置適合的參數(shù) #server 106.xx.xx.xxx; 可以是ip #server 106.xx.xx.xxx:8080; 可以帶端口號 #server unix:/tmp/xxx; 支出socket方式 }
假設(shè)我們有三臺服務(wù)器,并且假設(shè)它們的IP地址,前端負載均衡服務(wù)器A(127.0.0.1),后臺服務(wù)器B(127.0.0.2),后臺服務(wù)器C(127.0.0.3)
新建文件 proxy.conf
,內(nèi)容如下,上一章介紹的反向代理配置
proxy_redirect default; proxy_set_header Host $http_host; proxy_set_header X-Real-IP $remote_addr; proxy_connect_timeout 30; proxy_send_timeout 60; proxy_read_timeout 60; proxy_buffer_size 32k; proxy_buffering on; proxy_buffers 4 128k; proxy_busy_buffers_size 256k; proxy_max_temp_file_size 256k; #服務(wù)器A的配置 http { ... upstream xxx { server 127.0.0.2; server 127.0.0.3; } server { liseten 80; server_name localhost; location / { proxy_pass http://xxx #upstream 對應(yīng)自定義名稱 include proxy.conf; } } } #服務(wù)器B、服務(wù)器C的配置 server { liseten 80; server_name localhost; location / { index index.html } }
調(diào)度算法
輪訓(xùn):按時間順序逐一分配到不同的后端服務(wù)器
加權(quán)輪訓(xùn):weight值越大,分配到的幾率越高
ip_hash:每個請求按訪問IP的hash結(jié)果分配,這樣來自同一個IP固定訪問一個后端服務(wù)器
least_conn:最少鏈接數(shù),哪個機器連接數(shù)少就分發(fā)給誰
url_hash:按照訪問的URL的hash結(jié)果來分配請求,每一個URL定向到同一個后端服務(wù)器
hash關(guān)鍵數(shù)值:hash自定義key
ip_hash
配置
upstream xxx { ip_hash; server 127.0.0.2; server 127.0.0.3; }
ip_hash存在缺陷,當(dāng)前端服務(wù)器再多一層時,將獲取不到用戶的正確IP,獲取的將是前一個前端服務(wù)器的IP,因此 nginx1.7.2版本推出了 url_hash
url_hash
配置
upstream xxx { hash $request_uri; server 127.0.0.2; server 127.0.0.3; }
1. 緩存類型
服務(wù)端緩存:緩存存儲在后端服務(wù)器,如redis,memcache
代理緩存:緩存存儲在代理服務(wù)器或者中間件上,它的內(nèi)容是從后端服務(wù)器獲取的,但是保存在自己本地
客戶端緩存:緩存在瀏覽器內(nèi)的
2. nginx 代理緩存
客戶端請求nginx,nginx查看本地是否有緩存數(shù)據(jù),若有直接返回給客戶端,若沒有再去后端服務(wù)器請求
http { proxy_cache_path /var/www/cache #緩存地址 levels=1:2 #目錄分級 keys_zone=test_cache:10m #開啟的keys空間名字:空間大小(1m可以存放8000個key) max_size=10g #目錄最大大小(超過時,不常用的將被刪除) inactive=60m #60分鐘內(nèi)沒有被訪問的緩存將清理 use_temp_path=pff; #是否開啟存放臨時文件目錄,關(guān)閉默認存儲在緩存地址 server { ... location / { proxy_cache test_cache; #開啟緩存對應(yīng)的名稱,在keys_zone命名好 proxy_cache_valid 200 304 12h; #狀態(tài)碼為200 304的緩存12小時 proxy_cache_valid any 10m; #其他狀態(tài)緩存10小時 proxy_cache_key $host$uri$is_args$args; #設(shè)置key值 add_header Nginx-Cache "$upstream_cache_status"; } } }
當(dāng)有個特定請求我們不需要緩存的時候,在上面配置的內(nèi)容中加入以下配置
server { ... if ($request_uri ~ ^/(login|register) ) { #當(dāng)請求地址有l(wèi)ogin或register時 set $nocache = 1; #設(shè)置一個自定義變量為true } location / { proxy_no_cache $nocache $arg_nocache $arg_comment; proxy_no_cache $http_pragma $http_authoriztion; } }
3. 分片請求
早期版本 nginx 對大文件的分片請求不支持緩存,1.9版本后slice模塊實現(xiàn)了這個功能
前端發(fā)起請求,nginx去獲取這個請求文件的大小,若超過我們的定義slice的大小,會進行切片,分割成多個小的請求去請求后端,到前端就成為一個一個獨立的緩存文件
tips:歡迎關(guān)注微信公眾號:Java后端,獲取每日技術(shù)博文推送。
優(yōu)勢:每個子請求收到的數(shù)據(jù)都會形成獨立文件,一個請求中斷了,其他請求不受影響,原本情況請求中斷,再次請求文件將從頭開始,而開啟分片請求,就接下去獲取未請求的小文件
劣勢:當(dāng)文件很大或者slice很小時,可能會導(dǎo)致文件描述符耗盡等情況
語法:slice size; #當(dāng)大文件請求時,設(shè)置size為每個小文件的大小 默認:slice 0; 位置:http/server/location
#當(dāng)出現(xiàn)虛擬主機域名相同的情況,重啟nginx時,會出現(xiàn)警告??處理,但是并不不會阻止nginx繼續(xù)使用 server { listen 80; server_name www.baidu.com ... } server { listen 80; server_name www.baidu.com ... } ... 優(yōu)先選擇最新讀取到的配置文件,當(dāng)多個文件是通過include時,文件排序越靠前,越早被讀取
= #進行普通字符精確匹配,完全匹配 ^~ #進行普通字符匹配,當(dāng)前表示前綴匹配 ~\~* #表示執(zhí)行一個正則匹配() #當(dāng)程序使用精確匹配時,一但匹配成功,將停止其他匹配 #當(dāng)正則匹配成功時,會繼續(xù)接下來的匹配,尋找是否還有更精準的匹配
按順序檢查文件是否存在
location / { try_files $uri $uri/ /index.php; } #先查找$uri下是否有文件存在,若存在直接返回給用戶 #若$url下沒有文件存在,再次訪問$uri/的路徑是否有文件存在 #還是沒有文件存在,交給index.php處理 例: location / { root /test/index.html try_files $uri @test } location @test { proxy_pass http://127.0.0.1:9090; } #訪問 / 時,查看 /test/index.html 文件是否存在 #若不存在,讓9090端口的程序去處理這個請求
location /request_path/image/ { root /local_path/image/; } #當(dāng)我們訪問 /upload/otherpic60/786645.png時 #將訪問 /upload/otherpic60/786646.png 下的文件 location /request_path/image/ { alias /local_path/image/; } #當(dāng)我們訪問 /upload/otherpic60/786645.png時 #將訪問 /upload/otherpic60/786647.png 下的文件
當(dāng)一個請求通過多個代理服務(wù)器時,用戶的IP將會被代理服務(wù)器IP覆蓋
#在第一個代理服務(wù)器中設(shè)置 set x_real_ip=$remote_addr #最后一個代理服務(wù)器中獲取 $x_real_ip=IP1
413 Request Entity Too Large #上傳文件過大,設(shè)置 client_max_body_size 503 bad gateway #后端服務(wù)無響應(yīng) 504 Gateway Time-out #后端服務(wù)執(zhí)行超時
感謝各位的閱讀,以上就是“Nginx的概念和用法”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對Nginx的概念和用法這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是創(chuàng)新互聯(lián),小編將為大家推送更多相關(guān)知識點的文章,歡迎關(guān)注!