nginx 學習路程
作為一個前端,我覺得大部分人應該聽說過nginx因為它在最近兩年實在是很火,現在作為一個前端如果你不會ngxin那肯定不好意思說自己是一個大前端:我首先看一下nginx的官方介紹:
"Nginx是一款輕量級的HTTP伺服器,採用事件驅動的非同步非阻塞處理方式框架,這讓其具有極好的IO效能,時常用於服務端的反向代理和負載均衡。"
nginx特性
IO多路複用多個描述符的IO操作都能在一個執行緒裡交替書序完成,複用執行緒
1.select執行緒遍歷檔案描述符列表,1.效率底下2.最多隻能有1024(注:這種模式其實就是輪詢沒過一段時間去檢查一下任務是否完成,輪詢的期間沒辦法執行其他操作,有些IO操作很慢的話不可能每秒都去輪詢檢查這樣做無疑是效率低下的方式,當然因為系統限制只能有1024個執行緒)
2.epoll每當FD就緒,採用系統回撥函式將fd放入1.效率高2.沒有1024限制(注:這種方式有點類似於node的機制,不用去輪詢檢查任務是否完成而是任務完成後會自動通知將執行結果放入回撥函式中) CPU親和 一種把CPU核心和nginx工作程序繫結的方式,也就是沒一個core核心就有一個nginx程序,把每個worker程序固定在一個cpu上執行減少了切換cpu和提交快取命中率,獲得更好的效能
sendfile零拷貝傳輸模式,這個模式的好處在於靜態資源的代理,通常我們再linux伺服器上讀取靜態檔案需要經過使用者空間,伺服器上的記憶體空間然後返回到客戶端,nginx作為靜態資源伺服器繞過了使用者空間的快取少了資源的拷貝傳輸更高效
Nginx的優點
支援海量高併發:採用IO多路複用epoll。官方測試Nginx能夠支援5萬併發連結,實際生產環境中可以支撐2-4萬併發連線數。 記憶體消耗少:在主流的伺服器中Nginx目前是記憶體消耗最小的了,比如我們用Nginx+PHP,在3萬併發連結下,開啟10個Nginx程序消耗150M記憶體。 免費使用可以商業化:Nginx為開源軟體,採用的是2-clause BSD-like協議,可以免費使用,並且可以用於商業。 配置檔案簡單:網路和程式配置通俗易懂,即使非專業運維也能看懂。
安裝
準備工作:1關閉防火牆等配置(本人購買的是阿里雲ECS center OS)命令如下
systemctl stop firewalld.service
setenforce 0
2:安裝必要的依賴(安裝工具編譯環境等)命令如下
yum -y install gcc gcc-c++ autoconf pcre pcre-devel make automake
yum -y install weget httped-tools vim
3修改yum源 使用vim編譯器新建一個yum配置檔案我們使用的是vim編輯器上面已經安裝了 vim /etc/yum.repos.d/nginx.repo,這裡會新建一個yum源的配置檔案我們使用i鍵進入insert模式把下面的配置貼上進去
[nginx]
name=nginx repo
baseurl=http://nginx.org/packages/centos/7/$basearch/
gpgcheck=0
enabled=1
按下esc並且輸入:wq儲存並退出,這裡都是linux的編輯器命令不做過多解釋
如果都已經準備好了,那就可以開始安裝了,安裝的命令非常簡單:
yum install nginx
安裝完成後可以使用命令,來檢測Nginx的版本。
nginx -v

學會使用
我們首先可以使用一條命令查詢我們nginx安裝的目錄
/etc/nginx配置檔案都在該檔案下

#執行使用者,預設即是nginx,可以不進行設定 usernginx; #Nginx程序,一般設定為和CPU核數一樣 worker_processes1; #錯誤日誌存放目錄 error_log/var/log/nginx/error.log warn; #程序pid存放位置 pid/var/run/nginx.pid; events { worker_connections1024; # 單個後臺程序的最大併發數 } http { include/etc/nginx/mime.types;#副檔名與型別對映表 default_typeapplication/octet-stream;#預設檔案型別 #設定日誌模式 log_formatmain'$remote_addr - $remote_user [$time_local] "$request" ' '$status $body_bytes_sent "$http_referer" ' '"$http_user_agent" "$http_x_forwarded_for"'; access_log/var/log/nginx/access.logmain;#nginx訪問日誌存放位置 sendfileon;#開啟高效傳輸模式 #tcp_nopushon;#減少網路報文段的數量 keepalive_timeout65;#保持連線的時間,也叫超時時間 #gzipon;#開啟gzip壓縮 include /etc/nginx/conf.d/*.conf; #包含的子配置項位置和檔案 複製程式碼
自配置檔案在 conf.d的檔案下
server { listen80;#配置監聽埠 server_namelocalhost;//配置域名 #charset koi8-r; #access_log/var/log/nginx/host.access.logmain; location / { root/usr/share/nginx/html;#服務預設啟動目錄 indexindex.html index.htm;#預設訪問檔案 } #error_page404/404.html;# 配置404頁面 # redirect server error pages to the static page /50x.html # error_page500 502 503 504/50x.html;#錯誤狀態碼的顯示頁面,配置後需要重啟 location = /50x.html { root/usr/share/nginx/html; } # proxy the PHP scripts to Apache listening on 127.0.0.1:80 # #location ~ \.php$ { #proxy_passhttp://127.0.0.1; #} # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000 # #location ~ \.php$ { #roothtml; #fastcgi_pass127.0.0.1:9000; #fastcgi_indexindex.php; #fastcgi_paramSCRIPT_FILENAME/scripts$fastcgi_script_name; #includefastcgi_params; #} # deny access to .htaccess files, if Apache's document root # concurs with nginx's one # #location ~ /\.ht { #denyall; #} } 複製程式碼
我們大部分的nginx的配置都是在上述的兩個檔案下進行 明白了這些配置項,我們知道我們的服務目錄放在了/usr/share/nginx/html下,可以使用命令進入看一下目錄下的檔案,可以看到目錄下面有兩個檔案,50x.html 和 index.html。我們可以使用vim進行編輯。學到這裡,其實可以預想到,我們的nginx伺服器已經可以為html提供伺服器了。我們可以開啟瀏覽器,訪問ip地址試一試。

啟動的和重啟的基本命令
nginx直接啟動 在CentOS7.4版本里(低版本是不行的),是可以直接直接使用nginx啟動服務的。
nginx 複製程式碼
使用systemctl命令啟動,還可以使用個Linux的命令進行啟動,我一般都是採用這種方法進行使用。因為這種方法無論啟動什麼服務,都是一樣的,只是換一下服務的名字(不用增加額外的記憶點)。
systemctl start nginx.service 複製程式碼
輸入命令後,沒有任何提示,那我們如何知道Nginx服務已經啟動了哪?可以使用Linux的組合命令,進行查詢服務的執行狀況。
ps aux | grep nginx 複製程式碼
停止Nginx服務的四種方法 停止Nginx 方法有很多種,可以根據需求採用不一樣的方法,我們一個一個說明。 立即停止服務
nginx-s stop 複製程式碼
這種方法比較強硬,無論程序是否在工作,都直接停止程序。 從容停止服務
nginx -s quit 複製程式碼
這種方法較stop相比就比較溫和一些了,需要程序完成當前工作後再停止。 killall 方法殺死程序 這種方法也是比較野蠻的,我們直接殺死程序,但是在上面使用沒有效果時,我們用這種方法還是比較好的。
killall nginx systemctl 停止 systemctl stop nginx.service 複製程式碼
重啟Nginx服務 有時候我們需要重啟Nginx服務,這時候可以使用下面的命令。
systemctl restart nginx.service 複製程式碼
重新載入配置檔案 在重新編寫或者修改Nginx的配置檔案後,都需要作一下重新載入,這時候可以用Nginx給的命令,一般過載就可以使用了無需再次重啟。
nginx -s reload 複製程式碼
檢視埠號
netstat -tlnp 複製程式碼
自定義錯誤頁和訪問設定
沒一個好的網站都會設定各種各樣的友好的錯誤提示,比如由於網路原因我們沒辦法找到頁面的時候,我們要提示頁面沒有找到。下面介紹一下錯誤頁面在nginx的配置方式:
1.多錯誤指向一個頁面
在/etc/nginx/conf.d/default.conf 是可以看到下面這句話的。
error_page500 502 503 504/50x.html; 複製程式碼
error_page指令用於自定義錯誤頁面,500、502、503、504這些都是常見的錯誤,當遇到這些錯誤的時候我們都會返回這個50x.html的頁面中. 2.單獨為錯誤置頂處理方式
有些時候是要把這些錯誤頁面單獨的表現出來,給使用者更好的體驗。所以就要為每個錯誤碼設定不同的頁面。設定方法如下:
error_page 404/404_error.html; 複製程式碼
上述頁面都在/usr/share/nginx/html檔案目錄下
訪問設定
location / { deny123.9.51.42; allow45.76.202.231; } 複製程式碼
在配置檔案中我們可以加上deny和allow這兩個配置項選擇可以訪問到該頁面的IP地址段,我們也可以使用all關鍵字阻止其他使用者比如下面的設定方式:
location / { allow45.76.202.231; denyall; } 複製程式碼
這種方式就是指允許其中一個IP地址進行訪問其他地址被禁止訪問會進入403的頁面,不能更換位置nginx的許可權是從上向下執行的如果上面阻止了deny all那麼
Nginx訪問許可權詳細介紹
複雜訪問控制權限匹配
在工作中我們可以使用表示式使許可權控制變得更細化(=號代表精確匹配,使用了=後是根據其後的模式進行精確匹配。),我們可以設定圖片為都可訪問,我們將admin管理目錄設定為外界不可訪問這樣是不是更安全了呢。
上面的需求,配置程式碼如下:
location =/img{ allow all; } location =/admin{ deny all; } 複製程式碼
使用正則表示式設定訪問許可權
僅僅使用精準匹配可能不滿足我們的要求,有時候我們需要php這些後臺的介面檔案不被外界訪問到,我們就可以使用正則進行匹配下面的程式碼中代表了所有以.php為結尾的檔案都不能被訪問到,這樣就可以防止我們的關鍵性檔案不會暴露出來。
程式碼如下:
location ~\.php$ { deny all; } 複製程式碼
Nginx設定虛擬主機和設定反向代理
nginx可以為伺服器劃分成幾個不同的虛擬主機,首先我們再阿里雲域名解析上配置兩個不同的二級域名一個是music.jackyfgh.top,另一個是blog.jackyfgh.top,我們在conf.d的資料夾下建立兩個子配置項,這樣做的目的是為了更好的管理

server { listen80; server_nameblog.jackyfgh.top; location / { proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $http_host; proxy_set_header X-NginX-Proxy true; proxy_pass http://127.0.0.1:8090; proxy_redirect off; } error_page500 502 503 504/50x.html; error_page404 /404_error.html; location = /50x.html { root/usr/share/nginx/html; } } } 複製程式碼
上述配置檔案我們配置了servername指定了對應的二級域名,然後我們配置了相應的反向代理,代理到真事的ip地址,這裡我使用koa做的後臺服務8090為koa服務所監聽的埠,我們把所有的請求都代理到這個地址下就可以通過這個二級域名去訪問對應的網站了,music.conf的配置檔案也同樣
server { listen81; server_namemusic.jackyfgh.top; location / { proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $http_host; proxy_set_header X-NginX-Proxy true; proxy_pass http://127.0.0.1:3000; proxy_redirect off; } error_page500 502 503 504/50x.html; error_page404 /404_error.html; location = /50x.html { root/usr/share/nginx/html; } } 複製程式碼
上面所說的反向代理這裡介紹一下。 首先我們說一下什麼是正向代理再介紹反向代理,作為一個程式設計師你肯定用過翻牆工具,它就是一個典型的正向代理,它會把一些不讓我們訪問的網頁請求代理到一個可以訪問的伺服器上進行訪問,也就是客戶端的代理。然而反向代理就是代理了真實的伺服器,當用戶訪問的時候我們訪問的其實不是真正的伺服器地址,這樣就可以更大程度的保護我們真正的業務不被攻擊,通常代理伺服器都是安全級別很高的。

這裡說一個注意事項那就是location配置的優先順序,當我們配置多個匹配規則的時候會根據優先順序進行匹配,這裡我踩了一個坑因為該配置不是像正常理解的按照順序去載入的,而是按照(location =) > (location 完整路徑 >) >(location ^~ 路徑) >(location ~* 正則) >(location 路徑)這樣的規則順序去載入的,當碰到優先順序高的匹配規則就不會向下匹配了。通常一個複雜的業務nginx可能高達2000行也說不準我們配置的時候一定要切記這種坑存在。
Nginx適配PC或移動裝置
下面我們說一下nginx如何做到像淘寶一樣實現的適配PC和移動裝置 Nginx通過內建變數$http_user_agent,可以獲取到請求客戶端的userAgent,就可以使用者目前處於移動端還是PC端,進而展示不同的頁面給使用者。 操作步驟如下:
server{ listen 80; server_name nginx2.jspang.com; location / { root /usr/share/nginx/pc; if ($http_user_agent ~* '(Android|webOS|iPhone|iPod|BlackBerry)') { root /usr/share/nginx/mobile; } index index.html; } } 複製程式碼
這裡~*符號代表了不區分大小寫去匹配裝置我們將資源路徑指向了不同的地址預設指向PC的路徑,當然這裡的裝置識別符號可能不全面。
開啟gzip壓縮
首先我們說一下我們為什麼要要開啟gzip壓縮呢?如果我們在瀏覽器輸入一個地址的時候我們肯定會請求一堆檔案,瀏覽器會載入這些網頁如果這個資源很大我們怎麼辦,我們可不可以使用壓縮檔案來代替呢?這就是gzip技術。變化的部分在於瀏覽器和伺服器,它成功的傳送過去一個壓縮檔案。對於gzip壓縮的要點有兩點: 瀏覽器傳送一個請求頭,告訴伺服器接受壓縮版本的檔案(gzip和deflate是兩種壓縮演算法)Accept-Encoding:gzip,deflate 如果檔案壓縮了,伺服器返回一個頭資訊:Content-Encoding:gzip 如果伺服器沒有返回Content-Encoding的頭資訊,意味著這檔案是沒壓縮的(瀏覽器可以直接解析的)。請求頭Accept-Encoding只是瀏覽器的一個請求,而不是命令。如果伺服器不返回壓縮檔案,瀏覽器就不得不處理那龐大的原始檔。 下面的就是我使用配置nuxt專案的nginx Gzip配置檔案
server { listen80;# 監聽埠 server_nameyour-domain;# wx.10086.cn gzipon; gzip_typestext/plain application/xml text/css application/javascript;# 那些資源需要壓縮 gzip_min_length 1000; # 設定允許壓縮的頁面最小位元組數 location / { expires $expires; proxy_redirectoff; 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_set_header X-Forwarded-Proto$scheme; proxy_read_timeout1m; proxy_connect_timeout1m; proxy_passhttp://127.0.0.1:3000; # 代理的node地址 } } 複製程式碼
然後說一下Gzip配置項的說明:
gzip : 該指令用於開啟或 關閉gzip模組。 gzip_buffers : 設定系統獲取幾個單位的快取用於儲存gzip的壓縮結果資料流。 gzip_comp_level : gzip壓縮比,壓縮級別是1-9,1的壓縮級別最低,9的壓縮級別最高。壓縮級別越高壓縮率越大,壓縮時間越長。 gzip_disable : 可以通過該指令對一些特定的User-Agent不使用壓縮功能。 gzip_min_length:設定允許壓縮的頁面最小位元組數,頁面位元組數從相應訊息頭的Content-length中進行獲取。 gzip_http_version:識別HTTP協議版本,其值可以是1.1.或1.0. gzip_proxied : 用於設定啟用或禁用從代理伺服器上收到相應內容gzip壓縮。 gzip_vary : 用於在響應訊息頭中新增Vary:Accept-Encoding,使代理伺服器根據請求頭中的Accept-Encoding識別是否啟用gzip壓縮 ```。 nginx作為一個http伺服器被大家廣為推崇,當然僅僅學習是不夠的我們需要配合實際配置的經驗才能更好地應用。複製程式碼