nginx配置之server_name

介绍nginx中server_name的用法。

服务器名称通过server_name指令定义,用于决定请求由哪个server块进行处理。可以用具体的名称、通配符名称或正则表达式定义。

server {
    listen       80;
    server_name  example.org  www.example.org;
    ...
}

server {
    listen       80;
    server_name  *.example.org;
    ...
}

server {
    listen       80;
    server_name  mail.*;
    ...
}

server {
    listen       80;
    server_name  ~^(?.+)\.example\.net$;
    ...
}

当通过名称查询一个虚拟主机时,如果名称匹配了超过一个的变量,例如通配符和正则都匹配,则先匹配上的变量会被选中,优先级顺序如下:

  1. 具体的名称
  2. 以*开头的最长的通配符
  3. 以*结尾的通配符
  4. 第一个匹配的正则表达式(按出现在配置文件中的先后顺序)

通配符
通配符的*只能出现在名称的开头或结尾,并且只能使用英文句号“.”作为边界。名称“www.*.example.org”或“w*.example.org”是无效的。但这些名称可以通过正则表达式定义,例如“~^www\..+\.example\.org$”及“~^w.*\.example\.org$”。一个*可以匹配多个名字部分。名字“*.example.org”不仅匹配www.example.org还匹配www.sub.example.org
正则表达式
nginx使用的Perl正则表达式语法(PCRE),要用正则表达式,必须以~开头:
server_name ~^www\d+\.example\.net$;
否则会被认为是一个确切的名称,如果存在*,还被认为是统配符(这往往是不对的)。不要忘记添加“^”和“$”,语法上不要求加,但加上更符合逻辑。另外,注意域名的点应该用“\”进行转义。含有“{”和“}”的正则表达式需要用引号包裹:
server_name "~^(?\w\d{1,3}+)\.example\.net$";
否则,nginx启动会报错:
directive "server_name" is not terminated by ";" in ...
名称的正则表达式的捕获信息可以用作变量:

server {
    server_name   ~^(www\.)?(?.+)$;

    location / {
        root   /sites/$domain;
    }
}

PCRE库支持的用法如下:

? Perl 5.10 compatible syntax, supported since PCRE-7.0
?’name’ Perl 5.10 compatible syntax, supported since PCRE-7.0
?P Python compatible syntax, supported since PCRE-4.0

如果nginx启动的时候报如下错误:
pcre_compile() failed: unrecognized character after (?< in ...
说明PCRE库比较老,试试改成?P语法。捕获信息也可以用数字代替:

server {
    server_name   ~^(www\.)?(.+)$;

    location / {
        root   /sites/$2;
    }
}

但是,这种用法仅限使用在比较简单的案例中,因为用数字代替很容易被覆盖重写。
混合名称
有一些特殊处理的服务器名称。
如果需要处理http请求没有Host域,并且没有设置默认服务器,需要定义一个空的名称:

server {
    listen       80;
    server_name  example.org  www.example.org  "";
    ...
}

如果server块中没有定义服务器名称,nginx默认使用空字符串作为名称。

nginx直到0.8.48版本,使用的是机器的主机名作为服务器名称

如果服务器名称定义为“$hostname”(0.9.4),会使用机器的主机名。
如果请求直接用IP地址而不是主机名,请求头中的Host域就是IP地址,可以使用IP地址所谓服务器名称。

server {
    listen       80;
    server_name  example.org
                 www.example.org
                 ""
                 192.168.1.1
                 ;
    ...
}

名称设为“_”可以捕获所有的主机名:

server {
    listen       80  default_server;
    server_name  _;
    return       444;
}

这个并不是什么特殊的用法,只是使用了域名中永远不会出现的几个无效的字符。其他的无效名称如“-”、“!@#”都可以。
直到0.6.25版本,nginx支持特殊名字“*”被错误解析为全捕获名称。现在这个已经过时,使用server_name_in_redirect指令。注意,没有办法通过server_name指令定义全捕获的名称或默认名称。这是listen指令的属性而不是server_name的指令。可以定义不同的服务器分别监听*:80和*:8080,其中一个是80端口的默认服务器,另一个是8080端口的默认服务器:

server {
    listen       80;
    listen       8080  default_server;
    server_name  example.net;
    ...
}

server {
    listen       80  default_server;
    listen       8080;
    server_name  example.org;
    ...
}

优化
具体名称、*开头的通配符名称、*结尾的通配符名称分配存储在三张哈希表中并绑定不同的端口。在配置阶段会对哈希表的大小进行优化,一般提高名称在CPU缓存中的命中率。
具体名称的哈希表是最先被搜索的,如果名称没有找到,会搜索*开头的通配符哈希表,最后再搜索*结尾的通配符哈希表。
搜索通配符哈希表要比搜索具体名称的哈希表更慢,因为要搜索域名的一部分。注意,特殊形式的通配符名称“.example.org”是存储在统配符哈希表中而不是固定名称的哈希表中(虽然名称中没有*)。
正则表达式最慢,并且不可扩展。
因此,最好用固定的名称。例如,如果最常访问的名字是example.org 和www.example.org,下面的写法更高效:

server {
    listen       80;
    server_name  example.org  www.example.org  *.example.org;
    ...
}

下面的写法性能要低一些:

server {
    listen       80;
    server_name  .example.org;
    ...
}

如果定义了大量的名称,或一个名称很长,需要用到server_names_hash_max_size和server_names_hash_bucket_size指令,它们应该写在http块内。server_names_hash_bucket_size指令的值可以是32或64,也可以是其他值,取决于CPU缓存的大小。如果默认值是32,服务器名称定义为“too.long.server.name.example.org”,nginx会启动失败,并有如下报错信息:

could not build the server_names_hash,
you should increase server_names_hash_bucket_size: 32

这时,需要通过指令将这个值调整到原值的2倍:

http {
    server_names_hash_bucket_size  64;
    ...

如果定义了很多个服务器名称,会出现另一个错误:

could not build the server_names_hash,
you should increase either server_names_hash_max_size: 512
or server_names_hash_bucket_size: 32

这种情况下,首先尝试将server_names_hash_max_size的值调整到接近名称数量。当这种方法不奏效或nginx不可接受过长的数值时,尝试增加server_names_hash_bucket_size的值。
如果只配置了一个server块监听端口,nginx根本不会检测服务器名称(也不会建立哈希表)。但有一个例外,如果名称是一个有捕获的正则表达式,nginx会执行正则表达式以便获取捕获信息。
兼容性

  • 特殊的服务器名称“$hostname”从0.9.4开始支持。
  • 从0.8.48开始默认的服务器名称是空的。
  • Named regular expression server name captures have been supported since 0.8.25.
  • Regular expression server name captures have been supported since 0.7.40.
  • 空的服务器名称从0.7.12开始被支持
  • 通配符和正则表达式从0.6.25版本开始被支持
  • 正则表达式服务器名称从0.6.7版本被支持
  • 通配符example.*形式从0.6.0版本开始被支持
  • 特殊形式.example.org从0.3.18版本开始被支持
  • 统配符*.example.org形式从0.1.13版本开始被支持

nginx命令行参数

介绍nginx命令行参数。

nginx支持以下命令行参数:

  • -? | -h:打印命令行帮助信息
  • -c file:使用备用配置文件file,代替默认配置文件
  • -g directives:设置全局配置指令,例如:
    nginx -g "pid /var/run/nginx.pid; worker_processes `sysctl -n hw.ncpu`;"
  • -p prefix:设置nginx路径前缀,即一个保存服务器文件的目录(默认为/usr/local/nginx)
  • -q:禁止非错误类的信息
  • -s signal:向主进程发送信号,可以是以下的值:stop(立即关闭)、quit(优雅关闭)、reload(重载配置)、reopen(重新打开日志文件)
  • -t:测试配置文件是否正确
  • -T:与-t相同,但会将配置文件显示在标准输出中(1.9.2)
  • -v:打印nginx版本
  • -V:打印nginx版本、编译器版本、配置参数

nginx中的计量单位

介绍nginx中可以使用的单位。

大小可以被定义为字节、千字节(k和K结尾)或兆字节(m和M结尾),例如:“1024”、“8k”、“1m”。
时间间隔可以定义为毫秒、秒、分钟、小时、天等,用下面的后缀:

  • ms:毫秒
  • s:秒
  • m:分
  • h:小时
  • d:天
  • w:星期
  • M:月(30天)
  • y:年(365天)

多个单位可以按顺序合并为一个值,多个单位之间可以用空白分开,但不强制。例如,“1h 30m”与“90m”或“5400s”表示相同的时间。如果一个值没有后缀,则代表秒。建议总是声明后缀。
有些时间间隔单位只能定义成秒。

nginx初学者向导

本向导介绍了以下内容:1.nginx的基本设置,并提供了一些简单的任务与完成方法。2.如何启动、停止nginx,如何重新加载nginx配置文件。3.解释了配置文件的结构。4.如何设置nginx作为静态文件服务器。5.如何设置nginx作为代理服务器。6.如何通过FastCGI协议连接应用。

nginx有一个主进程和一些工作进程。主进程的作用是读取并解析配置文件并维持其他工作进程,工作进程会去处理请求。nginx采用事件驱动模式与系统依赖机制来高效的将请求分配到工作进程上。工作进程数可以在配置文件中定义,可以是固定的某个值或根据CPU核心数自动适配。
nginx和相关模块的工作方式由配置文件决定。默认情况下,配置文件叫做nginx.conf,该文件位于/usr/local/nginx/conf,/etc/nginx,或/usr/local/etc/nginx.
启动停止服务与重新加载配置文件
执行可执行文件即可启动nginx(window下,双击nginx.exe,linux下使用nginx命令)。一旦nginx启动,可以通过调用-s参数控制nginx,语法如下:

nginx -s signal

signal可以是下列一个值:

  • stop:快速关闭
  • quit:优雅关闭
  • reload:重新载入配置文件
  • reopen:重新打开日志文件

例如,停止nginx进程并等待所有工作进程处理完当前的请求可以使用

nginx -s quit

执行该命令的用户需要与启动nginx的用户相同
配置文件中的改动不会立即生效,直到重新加载配置文件或nginx重启。重新加载配置文件命令如下:

nginx -s reload

当nginx主进程接收到重新加载配置文件的信号时,它会检查新的配置文件的语法,并会尝试应用新的配置。如果成功了,nginx主进程会启动新的工作进程,并通知旧的工作进程,让他们关闭。旧的工作进程在收到关闭命令后会停止接受新的连接并会继续处理当前的请求直到所有请求处理完毕,然后旧的工作进程会退出。
可以借助Unix系统的工具如kill命令向nginx进程发送信号,此时信号将会直接通过进程ID发送给进程。nginx的主进程ID默认写在nginx.pid中,该文件位于/usr/local/nginx/logs或/var/run.例如,如果主进程ID为1628,发送QUIT信号让nginx优雅的关闭需要执行:

kill -s QUIT 1628

获取正在运行中的nginx进程的列表,可以用ps命令,例如:

ps -ax | grep nginx

配置文件结构
nginx由定义在配置文件中的指令控制的模块构成。指令分为简单指令和块级指令。简单指令由名称和参数构成,名称与参数之间用空格分开,结尾以英文分号结束。块级指令结构同简单指令,与简单指令不同的是,它是一些被花括号“{}”包裹指令的集合。如果一个块级指令中有其他的指令,则叫做一个上下文(events、http、server及location)。
配置文件中,不在任何上下文中的指令被看做是main上下文,events和https指令在main上下文中,server指令在http上下文中,location在server上下文中。

以“#”开头的行是注释信息
静态内容服务
服务器的一个重要的任务是提供文件(图片或静态html等)。你可以在此实现一个例子,根据请求,文件从不同的本地目录:/data/www(包含html文档)、/data/images(包含图片)获取并提供服务。这需要编辑配置文件,一个http块内包含了一个server块,server块中有两个location块。
首先,创建目录/data/www并放置一个内容任意index.html,创建目录/data/images并放置一些图片。
然后,打开配置文件,默认的配置文件已经包含了几个server块的例子,其中大部分都注释了,现在注释所有的块,并新建一个如下的块:

http {
    server {
    }
}

一般地,配置文件可以包含多个server块,分别定义了监听的端口和主机名称。当nginx决定了使用哪个server块处理请求,它会检测请求头中的URI及参数并匹配到location块上。
在server块中添加一个location块方法如下:

location / {
    root /data/www;
}

location块会将“/”前缀与请求的URI进行比较,对于匹配的请求,URI将会拼接到root指令定义的路径后面,本例中及/data/www,然后在本地文件中找到请求的文件。如果有很多location都能匹配url,则nginx会选择最长的前缀。上面的location定义了最短的前缀,只有一个字符,所以只有其他location都不匹配的时候,这个请求才会被location /匹配。
添加第二个location块:

location /images/ {
    root /data;
}

它将会匹配/images/开头(/也会匹配,但比/images/短)。
整体的配置如下:

server {
    location / {
        root /data/www;
    }

    location /images/ {
        root /data;
    }
}

以上配置好了一个监听在80端口,可以被本机通过http://localhost访问的服务。以/images/开头的请求,会响应一个从/data/images目录对应的文件。例如,响应http://localhost/images/example.png请求,nginx会发送/data/images/example.png文件,如果文件不存在,则返回404错误。不以/images/开头的URI将会定位到/data/www目录。例如,响应http://localhost/some/example.html请求,nginx会发送/data/www/some/example.html文件。
要应用新的配置文件,需要启动nginx或通过nginx的重新载入命令:

nginx -s reload

如果出现问题,可以尝试在access.log和error.log中找到原因,文件位于/usr/local/nginx/logs 或 /var/log/nginx.
设置一个简单的代理服务器
nginx的常用功能之一是用作代理服务器,接受请求并发送到被代理的服务器上然后把服务器的响应返回给客户端。
我们将要配置一个基础的代理服务器,该服务器对于图片文件会从本地读取,其他请求会发送到被代理的服务器上。本例中,两个服务器都在一个nginx实例中定义。
首先,配置被代理的服务器:

server {
    listen 8080;
    root /data/up1;

    location / {
    }
}

这个服务器监听8080端口(80端口已经占用了),将所有请求定位到本地/data/up1目录。建立此目录并放置index.html。注意,root指令放在server上下文中,location中就不再添加root指令。
然后,将上例中的server修改一下:

server {
    location / {
        proxy_pass http://localhost:8080;
    }

    location /images/ {
        root /data;
    }
}

现在修改第二个location块,当前是/images/定位到/data/images下,要将其改为通过文件扩展名进行定位。修改的location如下:

location ~ \.(gif|jpg|png)$ {
    root /data/images;
}

参数是一个正则表达式,匹配了所有以.gif、.jpg和.png结尾的URI。正则表达式应以~开头。匹配正则表达式的请求会被定位到/data/images目录。
当nginx选择location块时,首先会location块前缀的长度,并记住最长的前缀,然后检测正则表达式。如果有一个请求匹配了正则表达式,则选择该location,否则选择最长前缀的匹配。
最终配置文件如下:

server {
    location / {
        proxy_pass http://localhost:8080/;
    }

    location ~ \.(gif|jpg|png)$ {
        root /data/images;
    }

服务器会过滤所有以.gif、.jpg、及.png的请求,把他们定位到/data/images目录(并将路径后面追加上URI),其他的请求会转发到定义的被代理服务器上(localhost:8080)。
修改完配置文件需要重新载入配置文件才会生效。
设置FastCGI代理
nginx可以FastCGI协议的网关代理服务器,支持应用服务如PHP。
最基础的nginx FastCGI协议网关代理服务器配置使用fastcgi_pass指令。通过fastcgi_param指令设置传给FastCGI服务的参数。支持FastCGI的服务监听localhost:9000端口。在PHP中,SCRIPT_FILENAME参数用于定义script name,QUERY_STRING参数用于传递请求参数。完整配置如下:

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

    location ~ \.(gif|jpg|png)$ {
        root /data/images;
    }
}

以上将会把所有除静态文件之外的请求通过FastCGI协议转发到localhost:9000上。

linux下编译安装nginx

介绍在linux系统下编译安装nginx的方法,及编译参数

一、下载→编译→安装→启动
1.下载nginx最新版
官方网站上下载最新的tar.gz包
直接下载nginx的url为http://nginx.org/download/nginx-{version}.tar.gz,其中{version}为nginx的版本号
命令:[root@localhost ~]# wget http://nginx.org/download/nginx-1.9.14.tar.gz
2.解压文件
[root@localhost ~]# tar -zvxf nginx-1.9.14.tar.gz
3.进入nginx解压目录
[root@localhost ~]# cd nginx-1.9.14
4.使用参数进行编译,后面会给出编译参数的具体解释
[root@localhost nginx-1.9.14]# ./configure –prefix=/etc/nginx –sbin-path=/usr/sbin/nginx –conf-path=/etc/nginx/nginx.conf –error-log-path=/var/log/nginx/error.log –http-log-path=/var/log/nginx/access.log –pid-path=/var/run/nginx.pid –lock-path=/var/run/nginx.lock –http-client-body-temp-path=/var/cache/nginx/client_temp –http-proxy-temp-path=/var/cache/nginx/proxy_temp –http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp –http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp –http-scgi-temp-path=/var/cache/nginx/scgi_temp –user=nginx –group=nginx –with-http_ssl_module –with-http_realip_module –with-http_addition_module –with-http_sub_module –with-http_dav_module –with-http_flv_module –with-http_mp4_module –with-http_gunzip_module –with-http_gzip_static_module –with-http_random_index_module –with-http_secure_link_module –with-http_stub_status_module –with-http_auth_request_module –with-mail –with-mail_ssl_module –with-file-aio –with-ipv6 –with-http_v2_module
5.执行编译过程
[root@localhost nginx-1.9.14]# make && make install
6.配置nginx.conf,后续文章会有详细介绍
7.启动nginx
[root@localhost nginx-1.9.14]# nginx
二、编译参数
–prefix=path
定义保存服务器文件的目录。这个目录同时将作用于nginx.conf配置文件中配置的相对路径(但不包括源码库的路径)。默认值为/usr/local/nginx。
–sbin-path=path
设置nginx可执行文件的名称,该名称只在安装期间使用。默认值是prefix/sbin/nginx
–conf-path=path
设置nginx.conf配置文件的名称。如果需要,nginx可以使用不同的配置文件启动,你可以通过命令行参数 -c file启动。默认文件名为prefix/conf/nginx.conf
–pid-path=path
设置nginx.pid文件的名称,nginx.pid用于存储主进程的进程ID。安装后,该文件名称可以在nginx.conf的pid指令中修改。默认为prefix/logs/nginx.pid
–error-log-path=path
设置重要的错误、警告以及诊断文件的名字。安装后,可以通过nginx.conf的error_log指令修改。默认为prefix/logs/error.log
–http-log-path=path
记录主要请求日志的名称,安装后通过access_log指令修改。默认为prefix/logs/access.log
–user=name
设置工作进程的用户名,安装后可以通过user指令修改。默认值为nobody
–group=name
设置工作进程的用户组,安皇后可以通过user指令修改,默认与user相同。
–with-xxx_module
安装xxx模块,这些模块可以在nginx文档中找到。
–without-xxx_module
不安装xxx模块(有些模块是默认安装的,如果不想安装,可以通过这个参数屏蔽),这些模块可以在nginx文档中找到。