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


最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,835评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,598评论 1 295
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,569评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,159评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,533评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,710评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,923评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,674评论 0 203
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,421评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,622评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,115评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,428评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,114评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,097评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,875评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,753评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,649评论 2 271

推荐阅读更多精彩内容

  • Nginx简介 解决基于进程模型产生的C10K问题,请求时即使无状态连接如web服务都无法达到并发响应量级一万的现...
    魏镇坪阅读 1,959评论 0 9
  • 1.ngnix介绍 ngnix www服务软件 俄罗斯人开发 开源 性能很高 本身是一款静态WWW软件 静态小文件...
    逗比punk阅读 2,034评论 1 6
  • 1. Nginx的模块与工作原理 Nginx由内核和模块组成,其中,内核的设计非常微小和简洁,完成的工作也非常简单...
    rosekissyou阅读 10,126评论 5 124
  • nginx重写规则 nginx rewrite 正则表达式匹配 大小写匹配 ~ 为区分大小写匹配 ~* 为不区分大...
    桖辶殇阅读 5,376评论 0 2
  • 一、~/.vimrc 文件内容: set nocompatible " required filety...
    Aaron_Ren阅读 782评论 0 0