Nginx - 配置

Nginx

標籤 : nginx


Nginx

    nginx [engine x] is an HTTP and reverse proxy server, a mail proxy server, and a generic TCP/UDP proxy server, originally written by Igor Sysoev. For a long time, it has been running on many heavily loaded Russian sites including Yandex, Mail.Ru, VK, and Rambler. According to Netcraft, nginx served or proxied 25.64% busiest sites in April 2016. Here are some of the success stories: Netflix, Wordpress.com, FastMail.FM.
    The sources and documentation are distributed under the 2-clause BSD-like license.
    Commercial support is available from Nginx, Inc.

Nginx是一款輕量級的Web服務器/反向代理服務器電子郵件(IMAP/POP3)代理服務器,由俄羅斯工程師Igor Sysoev開發,供俄國大型入口網站及搜索引擎Rambler使用.其源代碼以BSD-like協議發佈. 其特點是內存佔用少,併發能力強, 因此被國內很多大型網站(如京東/淘寶)採用.
(主頁/介紹/文檔).


編譯安裝

  • wget http://nginx.org/download/nginx-1.10.0.tar.gz
  • tar -zxvf nginx-1.10.0.tar.gz
  • ./configure --prefix=/usr/local/nginx

    configure階段可能會遇到缺少依賴庫的提示(如pcre/zlib),此時需要安裝這些依賴才能繼續:

    • yum install pcre pcre-devel
    • yum install zlib zlib-devel
  • make && make install
    安裝完成後可在/usr/local/nginx/目錄下生成如下文件夾:

目錄 描述
conf nginx配置文件
html 網頁文件
logs nginx日誌文件
sbin nginx可執行文件
  • /usr/local/nginx/sbin/nginx
    啓動, Nginx默認佔用80端口,可在nginx.conf中更改.

Nginx信號

關於Linux信號相關知識, 可參考系列博客Linux信號實踐, 在此, 我們僅介紹Nginx捕獲的幾個信號.

nginx can be controlled with signals.

  • Kill -信號名 PID
信號名 作用
TERM/INT fast shutdown
QUIT graceful shutdown
HUP changing configuration, keeping up with a changed time zone , starting new worker processes with a new configuration, graceful shutdown of old worker processes
USR1 re-opening log files
USR2 upgrading an executable file
WINCH graceful shutdown of worker processes

以上信號作用亦可通過編譯出的nginx二進制文件實現:

To start nginx, run the executable file. Once nginx is started, it can be controlled by invoking the executable with the -s parameter. Use the following syntax:
nginx -s signal


配置

  • nginx.config
#運行服務的用戶及用戶組 
#user  nobody;

#工作進程數(一般設置爲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 {

    # 採用epoll進行IO複用
    # use epoll;

    # 單進程所允許的最大連接數
    worker_connections  1024;
}


http {
    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"';

    #access_log  logs/access.log  main;

    #是否激活sendfile()函數
    sendfile        on;
    #將HTTP響應頭壓縮到一個包中發送,僅在sendfile開啓時才能使用
    #tcp_nopush     on;

    #keepalive_timeout  0;
    keepalive_timeout  65;

    #開啓gzip模塊
    #gzip  on;

    #設定虛擬主機,默認監聽80端口,可配置多個
    server {
        listen       80;
        server_name  localhost;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

        # 頁面存放位置
        location / {
            # 頁面存放根目錄
            root   html;
            # 默認頁面
            index  index.html index.htm;
        }

        #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;
        #}
    }


    # 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;
    #    }
    #}
}

Server

在Nginx內可配置虛擬主機, 只需在nginx.conf中添加一個server元素:

server {
    listen 801;
    server_name www.feiqing.me;
    location / {
        root   /www.feiqing.me/;
        index  index.html index.htm;
    }
}

Log

  • 自定義log_format
log_format  fq_log_format   '$remote_addr - $remote_user [$time_local] "$request" '
        '$status $body_bytes_sent "$http_referer" '
        '"$http_user_agent" "$http_x_forwarded_for"';
  • servlet內引用
access_log logs/www.feiqing.me.access.log fq_log_format;
   啓用log       log位置                     log格式
  • 示例
    www.feiqing.me server單獨配置一個log:
server {
    listen 801;
    access_log logs/www.feiqing.me.access.log main;
    server_name www.feiqing.me;
    location / {
        root   /www.feiqing.me/;
        index  index.html index.htm;
    }
}

Location

Syntax:     location [ = | ~ | ~* | ^~ ] uri { ... }
location @name { ... }
Default:    —
Context:    server, location

Sets configuration depending on a request URI.
Nginx允許自定義location塊,通過指定的模式客戶端請求的URI相匹配,Nginx可將網站根據URI進行劃分,將網站的不同部分定位到不同的處理方式上:

server {
    server_name     www.feiqing.me;
    location /admin/ {
        # The configuration you place here only applies to http://www.feiqing.me/admin/
    }
}
  • location修飾符
    location第一個可選參數是一個符號,用來定義Nginx的匹配模式:
修飾符 描述
@ 指定一個命名的location,一般只用於內部重定向請求
= 精確匹配模式: URI的定位必須與指定的模式精確匹配
(無) 一般匹配模式: URI的定位必須以指定模式開始, 不可以使用正則表達式
~ 區分大小寫的正則匹配模式: 客戶端請求URI與指定正則表達式匹配必須區分大小寫
~* 不區分大小寫的正則匹配模式
^~ 類似於(無)模式的行爲, URI的定位必須以指定模式開始, 不同的是, 如果模式匹配, 那麼Nginx就停止搜索其他模式
!~/!~* 分別爲區分大小寫不匹配和不區分大小寫不匹配的正則
/ 通用匹配, 任何請求都會匹配到
  • 有多個location配置情況下的匹配順序:

    1. 帶有=修飾符的location: 如果指定pattern與URI 精確匹配, 則Nginx使用該location設置.
    2. 沒有修飾符的location: 如果指定pattern與URI 精確匹配,則使用之.
    3. 帶有^~修飾符的location: 如果指定pattern與URI 開始匹配, 則使用之.
    4. 帶有~/~*修飾符的location: 如果指定pattern與URI 匹配, 則使用之.
    5. 沒有修飾符的location: 如果指定pattern與URI 開始匹配, 則使用之.
    6. 通用匹配/.
  • 示例:

location ~* ^/\w*admin\w*/ {
    root   /var/www/regexp/;
    index  index.html;
}

關於location詳細內容可參考Nginx-ngx_http_core_module模塊文檔.


Rewrite

Rewrite用於實現URI重寫, URI重寫可以讓我們在改變網站結構時,無需修改原先暴露出去的URL, 並且在一定程度上提高網站安全性;

The ngx_http_rewrite_module module is used to change request URI using regular expressions, return redirects, and conditionally select configurations.

Nginx的Rewrite的實現依賴於PCRE(Perl Compatible Regular Expressions:Perl兼容正則表達式)庫, 因此在編譯Nginx前, 需要確保系統中已經包含該依賴.

注意: 正則表達式的元字符{}會與nginx.conf中block定界符{ ... }有衝突, 如果需要在nginx.conf內寫一個包含花括號的正則表達式,需要將表達式放在單引號/雙引號之間.

  • Rewrite指令執行順序:
    • 執行serverrewrite指令;
    • 執行location匹配;
    • 執行選定location中的rewrite指令;

如果其中某步URI被重寫,則重新循環執行1-3步,直到找到真實存在的文件. 但循環次數不能超過10次, 否則Nginx返回500-Internal Server Error.


指令

if 指令

Syntax:     if (condition) { ... }
Default:    —
Context:    server, location
  • The specified condition is evaluated. If true, this module directives specified inside the braces are executed, and the request is assigned the configuration inside the if directive. Configurations inside the if directives are inherited from the previous configuration level.

if條件可以是如下內容:

condition 描述
一個變量名 只有該變量是空字符串或者以0開始的字符串, 才爲false
使用=/!= 比較一個變量和字符串
使用~/~* 變量與正則表達式進行匹配的變量
使用-f/!-f 檢查一個文件是否存在
使用-d/!-d 檢查一個目錄是否存在
使用-e/!-e 檢查一個文件、目錄、符號鏈接是否存在
使用-x/!-x 檢查一個文件是否可執行
  • 示例
location ~* ^/\w*admin\w*/ {
    if ($request_method = GET) {
        return 405;
    }

    root   /var/www/regexp/;
    index  index.html;
}
  • 其他
if ($http_user_agent ~ MSIE) {
    rewrite ^(.*)$ /msie/$1 break;
}

if ($http_cookie ~* "id=([^;]+)(?:;|$)") {
    set $id $1;
}

if ($request_method = POST) {
    return 405;
}

if ($slow) {
    limit_rate 10k;
}

if ($invalid_referer) {
    return 403;
}

break 指令

Syntax:     break;
Default: 
Context:    server, location, if
  • Stops processing the current set of ngx_http_rewrite_module directives(停止執行當前虛擬主機的後續rewrite指令).

return 指令

Syntax: return code [text];
        return code URL;
        return URL;
Default:    —
Context:    server, location, if
  • Stops processing and returns the specified code to a client. The non-standard code 444 closes a connection without sending a response header(停止處理並返回指定狀態碼給客戶端,非標準狀態碼444表示關閉連接且不給客戶端發送響應頭).

該指令用於直接向客戶端返回響應狀態碼,從0.8.42版本起,return支持響應URL重定向(對於301/302/303/307),或者文本響應(對於其他狀態碼).

注意: 對於302/307, 返回的URL中應包含"http://"/"https://".對於文本或者URL重定向可以包含變量.

if ($http_user_agent ~ Chrome) {
    return 302 http://www.baidu.com;
}

set 指令

Syntax:     set $variable value;
Default: 
Context:    server, location, if
  • Sets a value for the specified variable. The value can contain text, variables, and their combination.

rewrite 指令

Syntax:     rewrite regex replacement [flag];
Default: 
Context:    server, location, if
  • If the specified regular expression matches a request URI, URI is changed as specified in the replacement string(如果一個URI匹配指定的正則表達式, URI就按照replacement形式重寫). The rewrite directives are executed sequentially in order of their appearance in the configuration file. It is possible to terminate further processing of the directives using flags(rewrite按配置文件中出現的順序執行, 但flags標誌可以停止繼續處理). If a replacement string starts with “http://” or “https://”, the processing stops and the redirect is returned to a client.

注意: 接收到的URI不包含host地址(如example.com), 也不包含URL中的請求參數(如?arg1=value1&arg2=value).


實例-僞靜態化

使用Rewrite功能將JavaWeb中的動態URL(xx.do?arg1=xx&arg2=xx)以靜態URL替換(xx-xx-xx.html).

server {
        listen       800;
        server_name  localhost;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

        location / {
            root   html;
            index  index.html index.htm;
        }

        location ~* (/javis/teacher/).*(.html)$ {
        rewrite /javis/teacher/(\w+)-(\w+)-(\w+)\.html /javis/teacher/$1.do?name=$2&password=$3;
        }

        location ~* \.(do|jsp|jspx)?$ {
            proxy_set_header X-Forwarded-For $remote_addr;
            proxy_pass http://10.45.156.170:80;
        }

    }

location ~* (/javis/teacher/).*(.html)$ { ... }會攔截所有/javis/teacher/ 目錄下以.html結尾的靜態URL,將其重寫爲.do結尾的動態URL(/javis/teacher/login-new_name-password.html -> /javis/teacher/login.do?name=new_name&password=password ), 然後location ~* \.(do|jsp|jspx)?$ { ... }提供反向代理功能,將所有以.do結尾的URL轉發到http://10.45.156.170:80地址, 由Java的後端Server提供真正的服務(反向代理相關知識可參考我的下一篇Nginx博客).


Gzip

Gzip(GNU-ZIP)是一種壓縮技術,經壓縮後的頁面可能只有原大小的30%,大大減小了網絡傳輸開銷,瀏覽器加載網頁的速度也會提升不少,但這項技術需要瀏覽器的配合(在服務端對網頁進行壓縮, 在瀏覽器對其解壓並解析),由於現代瀏覽都支持很多種解壓縮的方式(如Chrome: Accept-Encoding:gzip, deflate, sdch), 因此瀏覽器方面不需要我們擔心.
Nginx的gzip模塊是內置的, 由ngx_http_gzip_module 模塊實現, 可在nginx.conf中配置使用:

The ngx_http_gzip_module module is a filter that compresses responses using the “gzip” method. This often helps to reduce the size of transmitted data by half or even more.


指令

Context: http, server, location, Gzip一共有9個指令可以設置:

指令 描述
gzip on | off; Enables or disables gzipping of responses.
gzip_buffers number size; Sets the number and size of buffers used to compress a response. By default, the buffer size is equal to one memory page. This is either 4K or 8K, depending on a platform.
gzip_comp_level level; Sets a gzip compression level of a response. Acceptable values are in the range from 1 to 9(推薦壓縮級別爲6).
gzip_disable regex ...; Disables gzipping of responses for requests with “User-Agent” header fields matching any of the specified regular expressions.
gzip_min_length length; Sets the minimum length of a response that will be gzipped. The length is determined only from the “Content-Length” response header field.
gzip_http_version 1.0 | 1.1; Sets the minimum HTTP version of a request required to compress a response(default 1.1).
gzip_types mime-type ...; Enables gzipping of responses for the specified MIME types in addition to “text/html”. The special value “*” matches any MIME type (0.8.29). Responses with the “text/html” type are always compressed.
gzip_vary on | off; Enables or disables inserting the “Vary: Accept-Encoding” response header field if the directives gzip, gzip_static, or gunzip are active.
gzip_proxied [flag]; Enables or disables gzipping of responses for proxied requests depending on the request and response. The fact that the request is proxied is determined by the presence of the “Via” request header field. The directive accepts multiple parameters -> details

實例-常用Gzip配置

http {
    ## ...

    gzip  on;
    gzip_min_length 1024;
    gzip_buffers 4 16k;
    gzip_comp_level 6;
    gzip_types text/plain application/x-javascript application/javascript application/xml text/css ;
    gzip_vary on;

    ## ...
}

爲了使Nginx能夠在全局範圍內使用gzip,故將其放在http全局模塊中.如果需要對各個虛擬主機區別對待,可在對應的server塊中添加自己的gzip指令.

通過以上Nginx服務器訪問一個網頁(前提: Content-Length > 1024), 會看到靜態資源文件的Response中新增瞭如下三個響應頭:

Content-Encoding:gzip
Transfer-Encoding:chunked
Vary:Accept-Encoding

注意:
1. 由於圖片/視頻/音頻之類文件壓縮比率很小, 且壓縮過程非常耗費CPU資源, 因此這類資源推薦不對其壓縮.
2. 較小的文件壓縮後很有可能會比原文件還大, 因此這類資源也推薦不對其壓縮.


Expires

對於網站圖片,尤其是新聞網站,圖片一旦發佈,改動的可能非常小.因此我們希望用戶在第一訪問之後,圖片直接緩存在瀏覽器,而不再向服務端發送請求(不同於HTTP-304-Not Modified), 且能夠自定義緩存配置.這就用到了Nginx的expires功能.

Syntax: expires [modified] time;
expires epoch | max | off;
Default:    
expires off;
Context:    http, server, location, if in location
  • Enables or disables adding or modifying the “Expires” and “Cache-Control” response header fields provided that the response code equals 200, 201, 204, 206, 301, 302, 303, 304, or 307. A parameter can be a positive or negative time.
    注意: 要確保服務器時間準確,如果服務器時間落後於實際時間,可導致緩存失效.

實例-圖片緩存

  • 配置圖片緩存時間爲一天:
location ~* (jpg|png|jpeg|gif)$ {
    expires 1d;
}

通過以上Nginx服務器訪問一個圖片(如nginx.png),會看到圖片的Response中添加了如下兩個響應頭:

Cache-Control:max-age=86400 
Expires:Fri, 20 May 2016 12:26:11 GMT

再次刷新該URL, 在瀏覽器(如Chrome)中會看到這張圖片來自本地緩存:


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章