Nginx 配置學習

官方文檔php

1、概述

Nginx的配置放在配置文件nginx.conf/etc/nginx/nginx.conf中,大概的結構以下:css

main                                # 全局配置

events {                            # nginx工做模式配置

}

http {                                # http設置
    ....

    server {                        # 服務器主機配置
        ....
        location {                    # 路由配置
            ....
        }

        location path {
            ....
        }

        location otherpath {
            ....
        }
    }

    server {
        ....

        location {
            ....
        }
    }

    upstream name {                    # 負載均衡配置
        ....
    }
}

主要有html

  • main,全局配置
  • event nginx工做模式
  • http http服務器的配置
  • server 服務器訪問的配置
  • location 路由配置
  • upstream 負載均衡配置

2、main模塊

全局配置並不須要包含在大括號中。前端

user  nginx;
worker_processes  1;
error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;
worker_rlimit_nofile 1024;
  • nginx 用哪一個用戶來啓動
  • worker_processes 啓動的進程數,通常是CPU數量的兩倍
  • error_log 錯誤日誌,空格後面是日誌的等級,有warn error notice等
  • pid nginx pid的存放地址
  • worker_rlimit_nofile 每一個進程打開的文件描述符的數量

3、event 模塊

event {
    worker_connections 1024;
    multi_accept on;
    use epoll;
}
  • worker_connections 最大可接收的鏈接數
  • muti_accept 配置指定nginx在收到一個新鏈接通知後儘量多的接受更多的鏈接
  • use 配置線程輪詢方式

4、http模塊

http {
   
    access_log /var/log/nginx/access.log;
    error_log /var/log/nginx/error.log;
    log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';
  
    include /etc/nginx/conf.d/*.conf;

經常使用配置nginx

  • access_log access日誌
  • error_log 錯誤日誌
  • log_format 日誌格式
  • include 引入其餘文件做爲配置

其餘配置web

5、server模塊

server模塊放在http模塊裏面,一個server至關於一個虛擬的服務器。正則表達式

server {
    listen        80;
    server_name localhost    192.168.1.100;
    root        /nginx/www;
    index        index.php index.html index.html;
    charset        utf-8;
    access_log    logs/access.log;
    error_log    logs/error.log;
    ......
}
  • listen 監聽的端口
  • server_name 域名或者IP 空格分隔
  • root 表示虛擬主機的根目錄
  • index 表示全局首頁
  • charset 網頁中默認的編碼方式
  • access_log 訪問記錄日誌
  • error_log 錯誤日誌

6、location模塊

location模塊放在server模塊裏面,表示一個路由規則。tomcat

location的語法規則安全

location [ 空格 | = | ~ | ~* |^~|!~ | !~* ]  /uri/  {}

第一部分是location關鍵字
第二部分是修飾語(modifier)
第三部分是匹配的內容
第四部分是匹配成功後處理的方法服務器

1.修飾語

請求目錄是指客戶端發過了的請求的uri,例如客戶端訪問http://www.aa.com/dir1/dir2,其中/dir1/dir2就是請求目錄

  • = 精確匹配,也就是請求目錄和匹配的內容徹底一致,纔會匹配上,不支持正則
  • ^~開頭字符串匹配,若是請求目錄的開頭和匹配內容同樣,就會匹配上,不支持正則
  • ~ 開頭區分大小寫正則匹配,若是請求目錄的開頭符合匹配內容(正則表達式),就會匹配上
  • ~* 和~相似,區別是這個不區分大小寫
  • !~ 和~相似,區別是不符合正則,就會匹配上
  • !~* 和~*相似,區別是不符合正則,就會匹配上
  • 空格,跟^~相似,區別是優先級最低

上面的修飾符,除了精確匹配=和正則的匹配以外,其餘都是前綴匹配,也就是請求目錄的前面匹配上,就算匹配上了,無論後面的。
爲了安全起見,建議正在匹配儘可能加上^$

2. 匹配優先級

當多個location均可以匹配請求目錄,那麼nginx會使用哪一個location呢?

  1. 若是修飾語不一樣,那麼修飾語的優先級是
    = 大於 ^~ 大於~大於~*大於空格

    location = /dir1 {
    return 601;
    }
    location ^~ /dir1 {
    return 602;
    }
    location ~ /dir\d {
    return 603;
    }
    location ~* /dir\d {
    return 604;
    }
    location /dir1 {
    return 605;
    }

使用上面的配置,訪問http://test.kevinlu.com:10000/dir1,第一個location優先級最高,而後逐漸降低(能夠經過註釋location來測試)。

  1. 若是修飾語同樣,會找最長匹配字符串

    location / {
    return 601;
    }

    location /d {
    return 602;
    }

若是訪問http://test.kevinlu.com:10000/d,兩個location都會匹配上,可是第二個location會匹配到請求目錄的/d,長度是2,而第一個只會匹配到/,長度是1,前面的長度更長,因此使用第二個location。
注意這裏的長度是請求目錄的長度,不是匹配內容的長度。因此~ /\d~ /3,長度是同樣的,都是長度爲1。

  1. 若是匹配字符串的長度同樣,使用第一個location

    location ~ /\d {
        return 601;
    }
    location ~ /3 {
        return 602;
    }

例如上面的配置,訪問http://test.kevinlu.com:10000/3,會返回601。

因此總結一下Nginx尋找location的邏輯

  1. 根據修飾符的優先級,從高到低,尋找匹配的location數量N
    1. 若是N==0,尋找下一個優先級的修飾符
    2. 若是N==1,使用該location
    3. 若是N>1,計算每一個location匹配uri的最長的匹配字符串長度L,能達到L的location的數量N1,
      1. 若是N1==1,返回該location
      2. 若是N1>1,返回第一個location
  2. 若是全部location都不知足,返回404

僞代碼:

MODIFIER_LIST = ['=', '^~', '.......']  #修飾符的優先級排序


def get_location(uri):
    """尋找最優的location"""
    for modifier in MODIFIER_LIST:
        locations = get_match_location(uri, modifier) #獲取修飾符是modifier,匹配上uri的全部locations
        num = len(locations)
        if num == 0:
            continue
        elif num == 1:
            return locations[0]
        else:
            max_length = 0
            use_location = None
            for location in locations:
                length = get_match_uri_length(location, uri) #計算該location匹配上uri的最長匹配字符串的長度
                if length > max_length: #這裏是大於,不是大於等於,因此若是有多個location的length相同,會採用第一個
                    use_location = location
            return use_location
    return 404

#alias /data/demo/demo2018/nginx_test/1;
#root html;
#index test.html;

3.經常使用的匹配配置

#精確匹配首頁
location = / {
    proxy_pass http://tomcat:8080/index
}
#靜態資源
location ~* \.(gif|jpg|jpeg|png|css|js|ico|html)$ {
    root /webroot/res/;
}
#返回某個目錄下面的全部文件
location ^~ /static/ {
    root /webroot/static/;
}

4. 處理請求的指令

當Nginx找到最優的location來處理當前請求後,就會根據location的第四部分(大括號裏面)的指令來處理請求,並返回response。

4.1 返回靜態文件

root和alias指令都是用來返回系統本地的問題。兩個指令的值都是本地文件目錄,注意目錄後面要加/,例如/data/www/

  • root,會吧root的值和請求uri拼合在一塊兒來尋找本地文件
  • alias,會把alias的值和未匹配上的uri子串拼合在一塊兒來尋找本地文件

例如配置:

location /static1/{
    root /data/nginx_test/;
}
location /static2/{
    alias /data/nginx_test/;
}
location ~ ^/static3/(.+\.html)${
    alias /data/nginx_test/$1;
    #return 601;
}

當訪問http://test.kevinlu.com/static1/test.html,會返回文件/data/nginx_test/static1/test.html
當訪問http://test.kevinlu.com/static2/test.html,會返回文件/data/nginx_test/test.html
當訪問http://test.kevinlu.com/static3/test.html,會返回文件/data/nginx_test/test.html
注意第二個是沒有static2的。
使用alias的話,若是是正則的匹配方法,就須要使用正則的捕獲功能,把括號裏面的字符串賦值到變量$1中。
若是配置後,找不到文件,能夠看看error_log,會報錯105415 open() "/data/demo/demo2018/nginx_test/static1/2/test.html" failed (2: No such file or directory),就能夠看nginx

4.2反向代理

  1. 普通代理
    Nignx會把HTTP請求經過socket鏈接,轉發給其餘進程來處理

    location /static1/{
    proxy_pass http://localhost:8080/;
    proxy_set_header Host $host;
    }

使用proxy_pass指令。

  • proxy_pass 指定轉發到的socket地址
  • proxy_set_header 在http請求的基礎上,增長header 第一個參數是頭的key,第二個是頭的value
  • 其餘proxy相關指令

.

  1. FastCGI代理

    location / {
    fastcgi_pass localhost:9000;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_param QUERY_STRING $query_string;
    }

4.3返回狀態碼

return指令用戶之間返回response
第一個參數是http狀態碼,
第二個參數是body
能夠直接重定向,也能夠返回內容給前端。

location /test/{
        #return 301 http://www.baidu.com;
        return 200 <h1>aaa</h1>;
    }

4.4 重定向rewrite

語法:

rewrite regex replacement [flag];

該指令會把看是否uri匹配regex,若是匹配,把replacement替換regex
flag能夠:

  • last 向下匹配其餘location
  • break 終止匹配,不會再匹配下面的location
  • redirect 返回302重定向,這個是臨時重定向
  • permanent 返回301重定向,這個是永久重定向,

官網介紹
301和302的區別
博客

7、upstream

nginx配置

upstream gunicorn_pool
{
    #server 地址:端口號 weight表示權值,權值越大,被分配的概率越大;max_fails表示在fail_timeout中失敗的最大次數,若是達到該次數,就再也不導流量到該server
    server 192.168.137.130:9098 weight=4 max_fails=2 fail_timeout=30s;
    server 192.168.137.133:9098 weight=4 max_fails=2 fail_timeout=30s;
}

server {
    listen 80;
    server_name 127.0.0.1 www.test.com;
    access_log /data/logs/nginx_access.log;
    error_log /data/logs/nginx_error.log;
    location @gunicorn_proxy {
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;
        proxy_redirect off;
        proxy_pass http://gunicorn_pool;
    }
}

配置一個upstream,gunicorn_pool。裏面有兩個服務層(130和137)
若是兩個服務層都正常,Nginx會把流量根據weight值,導流到兩個服務器。
同一個請求中,若是nginx導流到server1,發現返回的是錯誤響應(例如502),nginx會把請求再發送server2,至關於重試。這時會記錄server1的fail次數+1
若是再fail_timeout時間內,server1的fail次數超過max_fails,在fail_timeout時間內,nginx就不會再把其餘請求導流到server1了。

未經容許,請不要轉載

相關文章
相關標籤/搜索