nginx是一個高性能的http和反向代理的web服務器。php
直接說概念好像有點枯燥,先學會使用吧。css
進入官網,找到window版本,下一步下一步就完成了。html
注意: nginx默認使用的是80端口,若是本地有80端口被佔用,可修改nginx配置文件(後面會講到)前端
本文主要講的是linux下nginx的安裝,畢竟生產環境下,linux服務器佔了大多數。node
linux下nginx的安裝步驟:linux
詳細見安裝步驟:nginx
如何讓nginx成爲全局命令呢?git
經過上面安裝,還沒法全局使用nginx,和window同樣的思路,須要在全局環境變量配置。
github
PATH:$PATH:/usr/local/nginx/sbin/
也就是nginx安裝目錄下的sbin目錄(爲命令行目錄)source profile
通過上面的配置,已經能夠全局使用nginx這個命令了。web
下面說一下nginx常見的命令:
配置文件是在conf目錄下的nginx.conf文件。(本文的目錄爲/usr/local/nginx/conf
),注意是在nginx下的安裝目錄下尋找。window也相同。
這是默認的nginx配置文件(一一進行講解)
# 運行用戶,本文是nobody,能夠不設置。nginx中#表明註釋
#user nobody;
# nginx進程,默認和cpu核心數相同
worker_processes 1;
# 錯誤日誌存放目錄
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#進程pid存放位置
#pid logs/nginx.pid;
events {
# 單個後臺進程的最大併發數
worker_connections 1024;
}
http {
# include:導入某個文件,這兒表示導入當前目錄的mime.types(這個文件是後綴名與類型的映射表)
include mime.types;
# 默認文件類型
default_type application/octet-stream;
# 設置日誌模式
#log_format main '$remote_addr - $remote_user [$time_local] "$request" '
# '$status $body_bytes_sent "$http_referer" '
# '"$http_user_agent" "$http_x_forwarded_for"';
#nginx訪問日誌默認存放位置
#access_log logs/access.log main;
# 是否開啓高效傳輸模式 on:開啓 off:關閉
sendfile on;
# 減小網絡報文段的內容
#tcp_nopush on;
# 保持鏈接的時間,也叫超時時間
#keepalive_timeout 0;
keepalive_timeout 65;
# 是否開啓gzip
#gzip on;
# 配置服務(這兒纔是重中之重)
server {
# 端口
listen 80;
# 域名
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
# 默認使用的目錄(這兒使用的當前安裝目錄下的html目錄)
root html;
# 默認指向這個目錄下的哪一個文件
index index.html index.htm;
}
# 配置404頁面
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
# 配置錯誤頁面
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
# proxy_pass http://127.0.0.1;
#}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#location ~ \.php$ {
# root html;
# fastcgi_pass 127.0.0.1:9000;
# fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
# include fastcgi_params;
#}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}
include /usr/local/nginx/conf/config_nginx_lijiayi/*.conf;
# another virtual host using mix of IP-, name-, and port-based configuration
#
#server {
# listen 8000;
# listen somename:8080;
# server_name somename alias another.alias;
# location / {
# root html;
# index index.html index.htm;
# }
#}
# HTTPS server
#
#server {
# listen 443 ssl;
# server_name localhost;
# ssl_certificate cert.pem;
# ssl_certificate_key cert.key;
# ssl_session_cache shared:SSL:1m;
# ssl_session_timeout 5m;
# ssl_ciphers HIGH:!aNULL:!MD5;
# ssl_prefer_server_ciphers on;
# location / {
# root html;
# index index.html index.htm;
# }
#}
}
複製代碼
上面主要講解了一些nginx的基礎配置,其實不少咱們瞭解便可。咱們通常的配置都是在server上配置。
好比咱們的後臺管理系統,只容許內網的訪問,不對外公開,就須要配置權限
location /{
allow xx.xx.xx.xx;
deny all;
}
複製代碼
可是須要注意指令的優先級
好比上面的配置,若是講deny放在allow前面會怎麼樣?
會禁止全部ip訪問。先起做用的配置會覆蓋後面的配置。
首先說一下,什麼是靜態資源文件服務器?
說白了就是隻有前端的資源文件,若是js css img等。只須要服務器向本機某個目錄讀取並返回給客戶端。(其實相似於express框架中,express實例.use(express.static(path.join(__dirname, '目錄名稱'))),筆者也實現了一個相似的功能,見node構建靜態文件服務器)
實際操做:(注: 如下操做均在linux下操做)
建立一個靜態資源文件目錄test,好比test目錄下有兩個子目錄blob data(這兩個各有一個html文件),而且有static目錄(放img等資源)。
上面的文件目錄爲:
- test
- blob
- index.html
- data
- data.html
- static
- 2.jpg
複製代碼
咱們想經過域名+'/frontEnd/'的方式讀取到test這個靜態服務目錄。
nginx的配置規則以下:
location /frontEnd/ {
alias /test/;
index index.html;
autoindex on;
}
複製代碼
並重啓nginx,nginx -s reload, 訪問域名+/frontEnd/便可成功訪問。此時咱們就用nginx配置了一個靜態資源文件服務。
其實上面用到了alias autoindex等基本配置沒講到的地方。甚至咱們衍生出nginx的location路徑匹配規則。這些咱們會在後面的nginx常見語法中講到。這裏只須要了解便可。
跨域在前端很是常見,就是非同源之間的訪問。
如何解決跨域呢?
這裏主要使用nginx來進行跨域處理。
好比本地有個node服務(localhost:8080),請求/data會返回一個json數據。
curl http://localhost:8080/data
返回
{
a: 1,
b: 2,
c: 3
}
複製代碼
在本地的其餘端口上面有個靜態頁面,使用ajax請求http://localhost:8080/data,瀏覽器會報跨域的錯誤。
使用nginx進行配置
location ^~ /api/ {
rewrite ^/api/(.*)$ /$1 break;
proxy_pass http://localhost:8080/;
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_connect_timeout 5;
}
複製代碼
前端代碼以下:
$.ajax({
type: 'get',
url: '/api/data',
success: function(res){
console.log(res)
}
})
複製代碼
上面代碼慢慢來解釋一下:
前端代碼:
ajax訪問的地址爲: http://localhost/api/data
nginx配置:
這裏就有個匹配規則(^~ /api/),^~ 又表明什麼? 後面都會解釋到
這裏能夠先大概的認爲: 當訪問開頭path爲api的時候,對應下面的具體匹配規則:
rewrite ^/api/(.*)$ /$1 break; // 意思是將前面的正則表達式進行替換,重寫了url。這裏的$1和js正則裏的概念是相同的,匹配到第一個()的表達式。
因此這裏最終將: http://localhost/api/data
重寫爲http://localhost/data
roxy_pass http://localhost:8080/
;// 代理的意思,將上面的url代理到http://localhost:8080/
,也就是將http://localhost
替換爲http://localhost:8080/
,因此總體的地址爲: http://localhost:8080/data
。從而完成了跨域的處理。
有個問題:配製成proxy_pass http://localhost:8080
; 會有影響嗎?(少了/)
後面的那幾個配置屬性:
解決代理引發的ip host問題。
由於: 若是默認不配置這幾項屬性,咱們真正的後端服務器(localhost:8080)獲取到的ip host都是咱們中間服務器的(這裏指的是nginx服務器)。若是咱們須要對違規用戶進行ip封號,由於沒法獲取客戶端的ip。爲了解決此類問題,使用了上面的配置。
若是不瞭解上面的小知識點,可搜索http X-Forwarded-For相關頭。
這塊功尚未經過代碼測試。因此主要講一下相關概念和簡單的配置。
什麼是反向代理負載均衡呢?舉例
反向代理: 咱們訪問百度(www.baidu.com), 咱們知道百度可能會有上百臺服務器在運行支持百度的服務。由於一臺服務器沒法支撐龐大的訪問量。 那麼咱們訪問www.baidu.com其實就是訪問到了中間服務器,中間服務器再通過一系列轉發等操做,轉發到真正爲咱們提供服務的後端服務器(也就是集羣)。
這裏說的中間服務器就是nginx服務器。
僞nginx配置文件:
http {
upstream baiduNginx {
server www.xxx.com;
server www.yyy.com;
...
}
server {
listen 80;
server_name www.baidu.com;
location / {
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Scheme $scheme;
proxy_pass baiduNginx;
}
}
}
複製代碼
上面的僞代理就是反向代理負載均衡的核心配置。
在具體的負載均衡配置中,還可配置多種策略。這裏就不展開講了。
nginx其實有不少的語法配置 公共常量等等。
這裏主要講解一下一些常見的語法。
上面咱們其實已經積累了不少問題:
其中咱們會將第4個問題集中到第一個問題裏講解。
location的匹配方式有兩種:
location的匹配規則: 首先前綴匹配,而後再進行正則匹配
有兩種特殊的前綴匹配:
正則匹配:
舉例:
location = / {
[ configuration A ]
}
location / {
[ configuration B ]
}
location /documents/ {
[ configuration C ]
}
location ^~ /images/ {
[ configuration D ]
}
location ~* \.(gif|jpg|jpeg)$ {
[ configuration E ]
}
複製代碼
1.訪問地址爲: /
先進行前綴匹配(按照書寫規則),根據規則,會進行A B C D前綴匹配規則,而後再進行正則匹配。可是匹配到A時,是精確匹配,則中止後續匹配。
2.訪問地址爲: /index.html
先進行前綴匹配,發現只有B符合,且B爲最長前綴匹配。
而後進行正則匹配,都沒匹配上,選擇以前的最長前綴匹配B
3.訪問地址爲: /documents/document.html
先進行前綴匹配, B C都符合,且 C爲最長前綴匹配
而後進行正則匹配,都沒匹配上,選擇以前的最長前綴匹配C
4.訪問地址爲: /images/1.gif
先進行前綴匹配, B D都符合,且 D爲特殊前綴匹配,則中止後續正則匹配。當前的規則使用 D
5.訪問地址爲: /documents/1.jpg
先進行前綴匹配,B C都符合,最長前綴匹配爲C。
再進行正則匹配,匹配到E , 並丟棄之間的最長前綴匹配。 當前的規則使用E
location /a/ {
root /test/;
index index.html;
}
複製代碼
訪問http://xxx.com/a/index.html
真正尋找的資源是在 /test/a/index.html
root處理: root 路徑 + location 路徑
location /a/ {
alias /test/;
index index.html;
}
複製代碼
訪問http://xxx.com/a/index.html
真正尋找的資源是在 /test/index.html
alias 的處理:使用 alias 路徑替換 location 路徑, alias後面必須以/結束
這裏多注意一下,多寫兩邊試試效果