nginx 配置常用指令(HTTP 服務)

直接查閱 nginx doc 是一個最簡單的途徑(Alphabetical index of directivesAlphabetical index of variables);你可以查看每個 Module 的詳盡解釋,很好。

location 命令
  • Understanding Nginx Server and Location Block Selection Algorithms
  • regex101,一個很好的在線正則表達式調試網站;
  • add_header
  • ~:Regular expressions ( for case-sensitive matching);
  • ~*:Regular expressions (for case-insensitive matching);
  • The @ prefix defines a named location. Such a location is not used for a regular request processing, but instead used for request redirection(內部重定向).
location priority 一般優先級
  1. Directives with the "=" prefix that match the query exactly. If found, searching stops.
  2. All remaining directives with conventional strings. If this match used the "^~" prefix, searching stops.
  3. Regular expressions, in the order they are defined in the configuration file.
  4. If #3 yielded a match, that result is used. Otherwise, the match from #2 is used.
rewrite
  • 一般形式:rewrite regex replacement [flag];
  • rewrite 針對的是處理 path,不處理 query string;
    要獲得 query string,請使用 $query_string 變量;
  • 關于 URI
    nginx 內部通常使用 $uri(沒有 query string,且歸一化了),區別于 $request_uri(full original request URI (with arguments),即有 query string);
  • 通常:rewrite /grab-new/index.html$ /demand.html;
    這里只需指定新的 path;其他部分,包括原有的 query_string 會自動添加上,從而形成新的 url;
  • rewrite /grab-new/index.html$ /demand.html permanent;
    permanent 返回 301,永久重定向;redirect 返回 302,臨時重定向;不指定 permanent 或者 redirect,就是 nginx 內部重定向(internal redirect,對用戶是透明的,即用戶并不知曉改變);permanent 或 redirect 會改變瀏覽器地址欄;
  • rewrite /grab-new/index.html$ /demand.html?a=2? permanent;
    使用新的 query_string: a=2,如果沒有最后的 ?,則原有的 query_string 會自動添加上;
    replacement: /demand.html?$query_string? 等同于 /demand.html
  • 如果要跳轉到新域名,replacement 請使用 http:// 或 https:// 開頭的完整 url,這時不指定 flag 的話,默認 302 redirect;

方法1

下面代碼中,listen 指令表明 server 塊同時用于 HTTP流量。
server_name 指令匹配包含域名 www.old-name.com 的請求。
return 指令告訴 Nginx 停止處理請求,直接返回 301 (Moved Permanently) 代碼和指定的重寫過的URL到客戶端。
$scheme 是協議(HTTP 或 HTTPS),$request_uri是包含參數的完整的 URI。

server{
    listen         80;
    server_name www.old-name.com;    
    # return 指令的第一個參數是響應碼。第二個參數可選,可以是重定向的 URL
    # location 和 server 上下文中都可以使用 return 指令。
    return 301 $scheme://www.new-name.com$request_uri;
}

方法2

server {
    listen 80;
    server_name old.example.cn;
    rewrite ^(.*)$ http://$newhost$1 permanent;
}

常用指令

  • server_namemore about server names
  • index
  • listen
  • root
  • expires timeExcellent Caching Tutorial
    該設置用于生成 HTTP Response Header:ExpiresCache-Control
  • try_files
  • access_log
    log_format,有時日志暫時不需要,可以關閉:access_log off;
  • error_log
    有時日志暫時不需要,可以關閉:error_log off;
  • return
  • 簡單認證 auth_basic
    auth_basic "Git authentication required";
    auth_basic_user_file htpasswd/pages.example.com;
    使用 openssl passwd 來將明文轉為密碼;printf "USER:$(openssl passwd -crypt PASSWORD)\n" >> <passwdfilename>,printf 類似 echo;
  • error_page
  • rewriteif 是 rewrite 模塊的一個指令;
  • client_body_in_file_only
    可用來查看調試 request body 內容,在 log_format 中使用 $request_body_file 記錄文件名,文件路徑為 $nginx/client_body_temp
  • 記錄請求頭和響應頭;
    記錄請求頭(request headers),則需要在 log_format 中使用 $http_name 分別指定,記錄響應頭(response headers)則形如:$sent_http_name自定義的 header 也沒問題;比如:$sent_http_content_type(Content-Type);(Header lines sent to a client have the prefix “sent_http_”, for example, $sent_http_content_range.)
  • add_header
    其中偶遇的 map 功能挺有意思:根據返回的 Content-Type 來決定 expires;
map $sent_http_content_type $expires {
    default         off;
    application/pdf 42d;
    ~image/         max;
}
expires $expires;

Embedded Variables

  • Alphabetical index of variables
  • $http_name

    arbitrary request header field; the last part of a variable name is the field name converted to lower case with dashes replaced by underscores.
    請求頭中字段名轉為小寫,連字符改為下劃線;比如:User-Agent => $http_user_agent;X-Abc-Xyz => $http_x_abc_xyz;

  • $server_name

示例解析 nginx.conf 片段

example.com 301 便利 SEO 收錄和統計
server {
    listen 80;
    server_name example.com;
    return 301 $scheme://www.example.com$request_uri;
}
subdomain 和 path-component 共存
default_server
    server {
        listen 80 default_server;
        location / {
            root html;
            index index.html;
        }
        # return 200;
    }
  • root html 指的是 $NGINX_HOME/html,和 conf/ 目錄同級;
    html/index.html 這個文件可以很好的作為測試使用;
  • 通過 include zwph/*.conf; 引入的配置片段,root html 中的 html 路徑是一樣的;
  • 運行時,請打開 return 200;
log_not_found

假如 favicon.ico 和 robots.txt 兩個文件都沒有定義,可以如下設置:

    location = /favicon.ico {
        log_not_found off;
        access_log off;
    }   

    location = /robots.txt {
        allow all;
        log_not_found off;
        access_log off;
    }
    location = /favicon.ico {
        log_not_found off;
        access_log off;
        return 204;
    }   

Requests are logged in context of a location where request execution ends up. As you have error_page 404 defined, and no favicon.ico file - error 404 is generated and redirected to /errors/404.html. As a result request is logged in context of "location /errors/" where you have access log enabled.

    if ($time_iso8601 ~ "^(\d{4})-(\d{2})-(\d{2})T(\d{2})") {
        set $year $1;
        set $month $2;
        set $day $3;
        set $hour $4;
    }
    access_log /logs/wph/www/access-$year$month$day$hour.log;
  • 注意 if 后面的空格;
    location /hour24/screen-detail/ {
        if (!-f $request_filename) {
            rewrite ^/hour24/screen-detail/(.*)\.html$ /hour24/screen-detail.html?id=$1 last;
        }
    }
按版本部署 api
  root /home/app/8ni/api.m/;
  location ~ "^(/v[0-9]{1,2}\.[0-9]{1,2}/)(.*)\.php$" {
    fastcgi_pass 127.0.0.1:9000;
    fastcgi_index index.php;
    fastcgi_param SCRIPT_FILENAME /home/app/8ni/api.m/$1/web/$2.php;
    include fastcgi_params;
  }
  • 注意正則表達式的雙引號,否則會報告錯誤:pcre_compile() failed: missing ) in "^(/v[0-9]",因為把緊跟其后面的那個 { 認為是 location {} 的那個 {。
fonts 設置 cors
  location ~* ^.*?\.(eot|ttf|woff)$ {
    expires 1M; 
    access_log off;
    add_header Access-Control-Allow-Origin *;
  }
  • svg? woff2?
按版本部署 www
    root /home/app/example/wph.pages/;
    index index.html;

    location ~ "^(?!(\/s[0-9]{1,2}\.[0-9]{1,2}[a-z]))(.*)" {
        root /home/app/example/wph.pages/s0.6e/;
    }
php 代碼
  location ~ ".*\.php$" {
    include fastcgi_params;
    fastcgi_pass 127.0.0.1:9000;
    fastcgi_param SCRIPT_FILENAME /home/app/example/api/web/$fastcgi_script_name;
  }
  • 原來有一句 fastcgi_index index.php; 其實并不需要,因為 location 已經做了限定;
  • fastcgi_params 文件內容
fastcgi_param  QUERY_STRING       $query_string;
fastcgi_param  REQUEST_METHOD     $request_method;
fastcgi_param  CONTENT_TYPE       $content_type;
fastcgi_param  CONTENT_LENGTH     $content_length;

fastcgi_param  SCRIPT_NAME        $fastcgi_script_name;
fastcgi_param  REQUEST_URI        $request_uri;
fastcgi_param  DOCUMENT_URI       $document_uri;
fastcgi_param  DOCUMENT_ROOT      $document_root;
fastcgi_param  SERVER_PROTOCOL    $server_protocol;
fastcgi_param  HTTPS              $https if_not_empty;

fastcgi_param  GATEWAY_INTERFACE  CGI/1.1;
fastcgi_param  SERVER_SOFTWARE    nginx/$nginx_version;

fastcgi_param  REMOTE_ADDR        $remote_addr;
fastcgi_param  REMOTE_PORT        $remote_port;
fastcgi_param  SERVER_ADDR        $server_addr;
fastcgi_param  SERVER_PORT        $server_port;
fastcgi_param  SERVER_NAME        $server_name;

# PHP only, required if PHP was built with --enable-force-cgi-redirect
fastcgi_param  REDIRECT_STATUS    200;
  • 每一行指定了一個 fastcgi_param,在 PHP 代碼里面可以通過 $_SERVER 變量來引用,比如:$_SERVER['REMOTE_ADDR'];
  • fastcgi.conf 和 fastcgi_params 文件幾乎一樣
    fastcgi.conf 在最開頭多了一行:fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;,而這個 SCRIPT_FILENAME 我們是要自定義的。
  • 這篇文章 有深度;
  • 設置自定義的 fastcgi_param;
    fastcgi_param SITE_TPL_DIR /home/app/example/www.satellite/share/tpl/;
    這里設置了 SITE_TPL_DIR 這個自定義的 fastcgi_param,在 php 代碼中可以使用,便于每個站點使用自己的 TPL 目錄。

安全

隱藏版本號
http {
    server_tokens off;
}
  • 在 Response Headers 中只會返回:Server:nginx
  • 默認 nginx 錯誤頁也遵從這個指令;
  • 如果要 刪除 Server 這個 Header,則需要重新編譯 Nginx,然后 more_clear_headers Server;
PHP 版本隱藏問題(和 nginx 無關)
  • 在 php.ini 中配置:expose_php = Off 即可;
  • HTTP 回應頭 X-Powered-By:PHP/5.6.11 就不會再顯示了;
  • 使用 php --ini 查看 php.ini 在哪兒
  • 重啟 php-fpm:/usr/local/php/sbin/restart.sh

性能調整

Caching for IMAGES, CSS & JS
  # Media: images, icons, HTC 
  location ~* \.(?:jpg|gif|png|svg|ico|htc)$ {
    expires 1M;
    access_log off;
  }
  
  # CSS and Javascript
  location ~* \.(?:css|js)$ {
    expires 1y; 
    access_log off;
  }
gzip

有關 gzip 的設置,統一放在 nginx.conf 的 http 指令下即可;

gzip on; 
gzip_disable "msie6";
gzip_vary on;
gzip_min_length 1k; 
gzip_buffers 4 16k;
gzip_http_version 1.1;
gzip_comp_level 5;
gzip_types text/css application/javascript application/json text/plain;
ETag
  • Nginx 默認是開啟的,其 算法 為:<last modified time(hex)>-<content length(hex)>.
  • 示例:ETag:"57af2761-fe2b",對應時間:2016-08-13 21:57:53.033453025 +0800,文件大小=65067字節;
  • ETag @ RFC7232:Conditional Requests

Even if your components have a far future Expires header, a conditional GET request is still made whenever the user hits Reload or Refresh.

Miscs

  • 方便使用 nginx
cd /usr/local/bin
ln -s /usr/local/nginx/sbin/nginx nginx

nginx 代理 websocket

注釋 Does nginx support comment blocks in configuration?

# 做注釋

通過本地 proxy server 上網

假如你通過本地的一個 proxy server 上網,則需要如下設置 git:
* stackoverflow: Getting git to work with a proxy server

備注

  • 通常網站文件都要設置為 nginx:nginx。
  • $NGINX_HOME/html/ 默認作為 listen 的 default_server 的 root
    青云的負載均衡器的轉發策略比較靈活,比如 按域名轉發
    ^example.com$(將 http://example.com/ 訪問轉發到后端主機),api.example.com^.*example.com,等規則,并且可以調整匹配順序,類似 nginx 的正則解釋。
    在多個后端主機情況下,就體現出其匹配順序。
    排查問題可就近使用 $NGINX_HOME/html/index.html 文件。

關于 nginx for windows

nginx for Windows


最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • Nginx簡介 解決基于進程模型產生的C10K問題,請求時即使無狀態連接如web服務都無法達到并發響應量級一萬的現...
    魏鎮坪閱讀 2,081評論 0 9
  • 1.ngnix介紹 ngnix www服務軟件 俄羅斯人開發 開源 性能很高 本身是一款靜態WWW軟件 靜態小文件...
    逗比punk閱讀 2,131評論 1 6
  • nginx重寫規則 nginx rewrite 正則表達式匹配 大小寫匹配 ~ 為區分大小寫匹配 ~* 為不區分大...
    桖辶殤閱讀 5,602評論 0 2
  • 一、~/.vimrc 文件內容: set nocompatible " required filety...
    Aaron_Ren閱讀 828評論 0 0
  • 喜歡 在這樣一個安靜的下午 坐在角落 享受著陽光溫柔的親吻 像你的笑容一樣 一絲甘甜 滲透心房 喜歡 在這樣一個溫...
    a897184095eb閱讀 310評論 3 1