配置

在Centos 默认配置文件在 /usr/local/nginx-1.5.1/conf/nginx.conf 我们要在这里配置一些文件。nginx.conf是主配置文件,由若干个部分组成,每个大括号{}表示一个部分。每一行指令都由分号结束;,标志着一行的结束。

常用正则

正则 说明 正则 说明
. 匹配除换行符以外的任意字符 $ 匹配字符串的结束
? 重复0次或1次 {n} 重复n次
+ 重复1次或更多次 {n,} 重复n次或更多次
* 重复0次或更多次 [c] 匹配单个字符c
\d 匹配数字 [a-z] 匹配a-z小写字母的任意一个
^ 匹配字符串的开始 - -

全局变量

变量 说明 变量 说明
$args 这个变量等于请求行中的参数,同$query_string $remote_port 客户端的端口。
$content_length 请求头中的Content-length字段。 $remote_user 已经经过Auth Basic Module验证的用户名。
$content_type 请求头中的Content-Type字段。 $request_filename 当前请求的文件路径,由root或alias指令与URI请求生成。
$document_root 当前请求在root指令中指定的值。 $scheme HTTP方法(如http,https)。
$host 请求主机头字段,否则为服务器名称。 $server_protocol 请求使用的协议,通常是HTTP/1.0或HTTP/1.1。
$http_user_agent 客户端agent信息 $server_addr 服务器地址,在完成一次系统调用后可以确定这个值。
$http_cookie 客户端cookie信息 $server_name 服务器名称。
$limit_rate 这个变量可以限制连接速率。 $server_port 请求到达服务器的端口号。
$request_method 客户端请求的动作,通常为GET或POST。 $request_uri 包含请求参数的原始URI,不包含主机名,如:/foo/bar.php?arg=baz。
$remote_addr 客户端的IP地址。 $uri 不带请求参数的当前URI,$uri不包含主机名,如/foo/bar.html。
$document_uri 与$uri相同。 - -

例如请求:http://localhost:3000/test1/test2/test.php

$host:localhost
$server_port:3000
$request_uri:/test1/test2/test.php
$document_uri:/test1/test2/test.php
$document_root:/var/www/html
$request_filename:/var/www/html/test1/test2/test.php

符号参考

符号 说明 符号 说明 符号 说明
k,K 千字节 m,M 兆字节 ms 毫秒
s m 分钟 h 小时
d w M 一个月, 30天

例如,”8k”,”1m” 代表字节数计量。
例如,”1h 30m”,”1y 6M”。代表 “1小时 30分”,”1年零6个月”。

配置文件

nginx 的配置系统由一个主配置文件和其他一些辅助的配置文件构成。这些配置文件均是纯文本文件,全部位于 nginx 安装目录下的 conf 目录下。

指令由 nginx 的各个模块提供,不同的模块会提供不同的指令来实现配置。
指令除了 Key-Value 的形式,还有作用域指令。

nginx.conf 中的配置信息,根据其逻辑上的意义,对它们进行了分类,也就是分成了多个作用域,或者称之为配置指令上下文。不同的作用域含有一个或者多个配置项。

下面的这些上下文指令是用的比较多:

Directive Description Contains Directive
main nginx 在运行时与具体业务功能(比如 http 服务或者 email 服务代理)无关的一些参数,比如工作进程数,运行的身份等。 user, worker_processes, error_log, events, http, mail
http 与提供 http 服务相关的一些配置参数。例如:是否使用 keepalive 啊,是否使用 gzip 进行压缩等。 server
server http 服务上支持若干虚拟主机。每个虚拟主机一个对应的 server 配置项,配置项里面包含该虚拟主机相关的配置。在提供 mail 服务的代理时,也可以建立若干 server. 每个 server 通过监听的地址来区分。 listen, server_name, access_log, location, protocol, proxy, smtp_auth, xclient
location http 服务中,某些特定的 URL 对应的一系列配置项。 index, root
mail 实现 email 相关的 SMTP/IMAP/POP3 代理时,共享的一些配置项(因为可能实现多个代理,工作在多个监听地址上)。 server, http, imap_capabilities
include 以便增强配置文件的可读性,使得部分配置文件可以重新使用。 -
valid_referers 用来校验Http请求头Referer是否有效。 -
try_files 用在server部分,不过最常见的还是用在location部分,它会按照给定的参数顺序进行尝试,第一个被匹配到的将会被使用。 -
if 当在location块中使用if指令,在某些情况下它并不按照预期运行,一般来说避免使用if指令。 -

例如我们再 nginx.conf 里面引用两个配置 vhost/example.com.conf 和 vhost/gitlab.com.conf 它们都被放在一个我自己新建的目录 vhost 下面。nginx.conf 配置如下:

  1. worker_processes 1;
  2. events {
  3. worker_connections 1024;
  4. }
  5. http {
  6. include mime.types;
  7. default_type application/octet-stream;
  8. #log_format main '$remote_addr - $remote_user [$time_local] "$request" '
  9. # '$status $body_bytes_sent "$http_referer" '
  10. # '"$http_user_agent" "$http_x_forwarded_for"';
  11. #access_log logs/access.log main;
  12. sendfile on;
  13. #tcp_nopush on;
  14. #keepalive_timeout 0;
  15. keepalive_timeout 65;
  16. #gzip on;
  17. server {
  18. listen 80;
  19. server_name localhost;
  20. location / {
  21. root html;
  22. index index.html index.htm;
  23. }
  24. error_page 500 502 503 504 /50x.html;
  25. location = /50x.html {
  26. root html;
  27. }
  28. }
  29. include vhost/example.com.conf;
  30. include vhost/gitlab.com.conf;
  31. }

简单的配置: example.com.conf

  1. server {
  2. #侦听的80端口
  3. listen 80;
  4. server_name baidu.com app.baidu.com; # 这里指定域名
  5. index index.html index.htm; # 这里指定默认入口页面
  6. root /home/www/app.baidu.com; # 这里指定目录
  7. }

内置预定义变量

Nginx提供了许多预定义的变量,也可以通过使用set来设置变量。你可以在if中使用预定义变量,也可以将它们传递给代理服务器。以下是一些常见的预定义变量,更多详见

变量名称
$args_name 在请求中的name参数
$args 所有请求参数
$query_string $args的别名
$content_length 请求头Content-Length的值
$content_type 请求头Content-Type的值
$host 如果当前有Host,则为请求头Host的值;如果没有这个头,那么该值等于匹配该请求的server_name的值
$remote_addr 客户端的IP地址
$request 完整的请求,从客户端收到,包括Http请求方法、URI、Http协议、头、请求体
$request_uri 完整请求的URI,从客户端来的请求,包括参数
$scheme 当前请求的协议
$uri 当前请求的标准化URI

反向代理

反向代理是一个Web服务器,它接受客户端的连接请求,然后将请求转发给上游服务器,并将从服务器得到的结果返回给连接的客户端。下面简单的反向代理的例子:

  1. server {
  2. listen 80;
  3. server_name localhost;
  4. client_max_body_size 1024M; # 允许客户端请求的最大单文件字节数
  5. location / {
  6. proxy_pass http://localhost:8080;
  7. proxy_set_header Host $host:$server_port;
  8. proxy_set_header X-Forwarded-For $remote_addr; # HTTP的请求端真实的IP
  9. proxy_set_header X-Forwarded-Proto $scheme; # 为了正确地识别实际用户发出的协议是 http 还是 https
  10. }
  11. }

复杂的配置: gitlab.com.conf。

  1. server {
  2. #侦听的80端口
  3. listen 80;
  4. server_name git.example.cn;
  5. location / {
  6. proxy_pass http://localhost:3000;
  7. #以下是一些反向代理的配置可删除
  8. proxy_redirect off;
  9. #后端的Web服务器可以通过X-Forwarded-For获取用户真实IP
  10. proxy_set_header Host $host;
  11. client_max_body_size 10m; #允许客户端请求的最大单文件字节数
  12. client_body_buffer_size 128k; #缓冲区代理缓冲用户端请求的最大字节数
  13. proxy_connect_timeout 300; #nginx跟后端服务器连接超时时间(代理连接超时)
  14. proxy_send_timeout 300; #后端服务器数据回传时间(代理发送超时)
  15. proxy_read_timeout 300; #连接成功后,后端服务器响应时间(代理接收超时)
  16. proxy_buffer_size 4k; #设置代理服务器(nginx)保存用户头信息的缓冲区大小
  17. proxy_buffers 4 32k; #proxy_buffers缓冲区,网页平均在32k以下的话,这样设置
  18. proxy_busy_buffers_size 64k; #高负荷下缓冲大小(proxy_buffers*2)
  19. }
  20. }

代理到上游服务器的配置中,最重要的是proxy_pass指令。以下是代理模块中的一些常用指令:

指令 说明
proxy_connect_timeout Nginx从接受请求至连接到上游服务器的最长等待时间
proxy_send_timeout 后端服务器数据回传时间(代理发送超时)
proxy_read_timeout 连接成功后,后端服务器响应时间(代理接收超时)
proxy_cookie_domain 替代从上游服务器来的Set-Cookie头的domain属性
proxy_cookie_path 替代从上游服务器来的Set-Cookie头的path属性
proxy_buffer_size 设置代理服务器(nginx)保存用户头信息的缓冲区大小
proxy_buffers proxy_buffers缓冲区,网页平均在多少k以下
proxy_set_header 重写发送到上游服务器头的内容,也可以通过将某个头部的值设置为空字符串,而不发送某个头部的方法实现
proxy_ignore_headers 这个指令禁止处理来自代理服务器的应答。
proxy_intercept_errors 使nginx阻止HTTP应答代码为400或者更高的应答。

负载均衡

upstream指令启用一个新的配置区段,在该区段定义一组上游服务器。这些服务器可能被设置不同的权重,也可能出于对服务器进行维护,标记为down。

  1. upstream gitlab {
  2. ip_hash;
  3. # upstream的负载均衡,weight是权重,可以根据机器配置定义权重。weigth参数表示权值,权值越高被分配到的几率越大。
  4. server 192.168.122.11:8081 ;
  5. server 127.0.0.1:82 weight=3;
  6. server 127.0.0.1:83 weight=3 down;
  7. server 127.0.0.1:84 weight=3; max_fails=3 fail_timeout=20s;
  8. server 127.0.0.1:85 weight=4;;
  9. keepalive 32;
  10. }
  11. server {
  12. #侦听的80端口
  13. listen 80;
  14. server_name git.example.cn;
  15. location / {
  16. proxy_pass http://gitlab; #在这里设置一个代理,和upstream的名字一样
  17. #以下是一些反向代理的配置可删除
  18. proxy_redirect off;
  19. #后端的Web服务器可以通过X-Forwarded-For获取用户真实IP
  20. proxy_set_header Host $host;
  21. proxy_set_header X-Real-IP $remote_addr;
  22. proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  23. client_max_body_size 10m; #允许客户端请求的最大单文件字节数
  24. client_body_buffer_size 128k; #缓冲区代理缓冲用户端请求的最大字节数
  25. proxy_connect_timeout 300; #nginx跟后端服务器连接超时时间(代理连接超时)
  26. proxy_send_timeout 300; #后端服务器数据回传时间(代理发送超时)
  27. proxy_read_timeout 300; #连接成功后,后端服务器响应时间(代理接收超时)
  28. proxy_buffer_size 4k; #设置代理服务器(nginx)保存用户头信息的缓冲区大小
  29. proxy_buffers 4 32k;# 缓冲区,网页平均在32k以下的话,这样设置
  30. proxy_busy_buffers_size 64k; #高负荷下缓冲大小(proxy_buffers*2)
  31. proxy_temp_file_write_size 64k; #设定缓存文件夹大小,大于这个值,将从upstream服务器传
  32. }
  33. }

每个请求按时间顺序逐一分配到不同的后端服务器,如果后端服务器down掉,能自动剔除。

负载均衡:

upstream模块能够使用3种负载均衡算法:轮询、IP哈希、最少连接数。

轮询: 默认情况下使用轮询算法,不需要配置指令来激活它,它是基于在队列中谁是下一个的原理确保访问均匀地分布到每个上游服务器;
IP哈希: 通过ip_hash指令来激活,Nginx通过IPv4地址的前3个字节或者整个IPv6地址作为哈希键来实现,同一个IP地址总是能被映射到同一个上游服务器;
最少连接数: 通过least_conn指令来激活,该算法通过选择一个活跃数最少的上游服务器进行连接。如果上游服务器处理能力不同,可以通过给server配置weight权重来说明,该算法将考虑到不同服务器的加权最少连接数。

RR

简单配置 ,这里我配置了2台服务器,当然实际上是一台,只是端口不一样而已,而8081的服务器是不存在的,也就是说访问不到,但是我们访问 http://localhost 的时候,也不会有问题,会默认跳转到http://localhost:8080具体是因为Nginx会自动判断服务器的状态,如果服务器处于不能访问(服务器挂了),就不会跳转到这台服务器,所以也避免了一台服务器挂了影响使用的情况,由于Nginx默认是RR策略,所以我们不需要其他更多的设置

  1. upstream test {
  2. server localhost:8080;
  3. server localhost:8081;
  4. }
  5. server {
  6. listen 81;
  7. server_name localhost;
  8. client_max_body_size 1024M;
  9. location / {
  10. proxy_pass http://test;
  11. proxy_set_header Host $host:$server_port;
  12. }
  13. }

负载均衡的核心代码为

  1. upstream test {
  2. server localhost:8080;
  3. server localhost:8081;
  4. }

权重

指定轮询几率,weight和访问比率成正比,用于后端服务器性能不均的情况。 例如

  1. upstream test {
  2. server localhost:8080 weight=9;
  3. server localhost:8081 weight=1;
  4. }

那么10次一般只会有1次会访问到8081,而有9次会访问到8080

ip_hash

上面的2种方式都有一个问题,那就是下一个请求来的时候请求可能分发到另外一个服务器,当我们的程序不是无状态的时候(采用了session保存数据),这时候就有一个很大的很问题了,比如把登录信息保存到了session中,那么跳转到另外一台服务器的时候就需要重新登录了,所以很多时候我们需要一个客户只访问一个服务器,那么就需要用iphash了,iphash的每个请求按访问ip的hash结果分配,这样每个访客固定访问一个后端服务器,可以解决session的问题。

  1. upstream test {
  2. ip_hash;
  3. server localhost:8080;
  4. server localhost:8081;
  5. }

fair

这是个第三方模块,按后端服务器的响应时间来分配请求,响应时间短的优先分配。

  1. upstream backend {
  2. fair;
  3. server localhost:8080;
  4. server localhost:8081;
  5. }

url_hash

这是个第三方模块,按访问url的hash结果来分配请求,使每个url定向到同一个后端服务器,后端服务器为缓存时比较有效。 在upstream中加入hash语句,server语句中不能写入weight等其他的参数,hash_method是使用的hash算法

  1. upstream backend {
  2. hash $request_uri;
  3. hash_method crc32;
  4. server localhost:8080;
  5. server localhost:8081;
  6. }

以上5种负载均衡各自适用不同情况下使用,所以可以根据实际情况选择使用哪种策略模式,不过fair和url_hash需要安装第三方模块才能使用

server指令可选参数:

  1. weight:设置一个服务器的访问权重,数值越高,收到的请求也越多;
  2. fail_timeout:在这个指定的时间内服务器必须提供响应,如果在这个时间内没有收到响应,那么服务器将会被标记为down状态;
  3. max_fails:设置在fail_timeout时间之内尝试对一个服务器连接的最大次数,如果超过这个次数,那么服务器将会被标记为down;
  4. down:标记一个服务器不再接受任何请求;
  5. backup:一旦其他服务器宕机,那么有该标记的机器将会接收请求。

keepalive指令:

Nginx服务器将会为每一个worker进行保持同上游服务器的连接。

屏蔽ip

在nginx的配置文件nginx.conf中加入如下配置,可以放到http, server, location, limit_except语句块,需要注意相对路径,本例当中nginx.confblocksip.conf在同一个目录中。

  1. include blockip.conf;

在blockip.conf里面输入内容,如:

  1. deny 165.91.122.67;
  2. deny IP; # 屏蔽单个ip访问
  3. allow IP; # 允许单个ip访问
  4. deny all; # 屏蔽所有ip访问
  5. allow all; # 允许所有ip访问
  6. deny 123.0.0.0/8 # 屏蔽整个段即从123.0.0.1到123.255.255.254访问的命令
  7. deny 124.45.0.0/16 # 屏蔽IP段即从123.45.0.1到123.45.255.254访问的命令
  8. deny 123.45.6.0/24 # 屏蔽IP段即从123.45.6.1到123.45.6.254访问的命令
  9. # 如果你想实现这样的应用,除了几个IP外,其他全部拒绝
  10. allow 1.1.1.1;
  11. allow 1.1.1.2;
  12. deny all;