笔者最近在做公司的去 nginx 的工作,工作的内容是将 nginx 配置翻译成公司的自研的类 nginx 服务的配置,但问题是笔者之前并未接触过 nginx 配置相关的内容,本着「不懂就要总结」的精神,笔者整理 nginx 常用的配置,如有遗漏欢迎指出。

1.Nginx 能做什么?

Nginx 可以提供反向代理、静态资源 WEB、负载均衡、动态缓存的服务。

1.1 反向代理

正向代理与反向代理的区别在于代理的对象不一样:

  • 正向代理:代理的对象时客户端
  • 反向代理:代理的对象时服务端

配置语法:

Syntax: proxy_pass URL
Default: -
Context: location,if in location,limit_except

注: url 可以直接写 IP 地址或者写成 upstream 定义的地址(后面介绍)

1.2 静态资源 WEB

静态资源的类型:

  • 非服务器动态运行生成的文件 —— 浏览器端渲染、图片、视频、文件
  • 静态资源服务场景—— CDN

静态资源 WEB 这项简单理解就是:

  • 将静态资源(xiyan.jpg) 存储到 nginx 服务的指定目录(/data/static)
  • nginx 配置访问文件指定静态资源的存储目录(root /data/static)
  • 客户端访问http://127.0.0.1:8080/xiyan.jpg nginx 会自动拼接路径返回 /data/static/xiyan.jpg 的文件给客户端

root 命令配置静态文件总结:

  • 对于匹配后的 URL 地址,将匹配的 location 中的 root 路径替换为访问 URL 的 host 即的到文件存储的真实路径
  • 如果不匹配 location,则寻找更外层的 root 做替换
  • 例子如下:
location /dir/ 
root root_path ->  http://host/dir/file.txt  -> root_path/dir/file.txt

注: 除 root 命令外, alias 指令也可用于配置静态文件

1.3 负载均衡

upstream 模块可配置后端服务器的负载均衡。

后端服务的状态设置:

配置

说明

down

当前的 server 暂时不参与负载均衡

backup

预留的备份服务器

max_fails

允许请求失败的次数

fail_timeout

经过 max_fails 失败以后,服务暂停的时间

max_conns

限制最大的接收的连接数

注 : backup 可用于配置冷备,原因是后端为有状态的服务 ,为了支持容灾可配置一台冷备的服务,当主服务挂掉以后能切换到备用的服务。

后端服务的配置策略:

配置

说明

场景

轮询

按照时间顺序逐一分配轮询配置服务地址

加权轮询

weight 值越大,分配到的访问概率越高

ip_hash

每个请求按照访问 IP 的 hash 结果分配,同一个 IP 固定访问同一个后端地址

解决 session 问题

url_hash

按照访问的 URL 的 hash 结果来分配请求,使每个 URL 定向到同一个后端服务器

后端缓存比较有效

least_conn

最少连接数,哪个机器的连接数少就

hash 关键数值

hash 自定义的 key

1.4 缓存

配置的栗子如下:

http{
    proxy_connect_timeout 10; //服务器连接的超时时间
    proxy_read_timeout 180;   //连接成功后,等待后端服务器响应的时间
    proxy_send_timeout 5;     //后端服务器数据回传的时间
    proxy_buffer_size 16k;    //缓存区的大小
    //每个连接设置缓冲区的数量为number,每块缓冲区的大小为size
    proxy_buffers 4 32k;   
    //开启缓冲响应的功能以后,在没有读到全部响应的情况下,写缓冲到达一定大小时,nginx一定会向客户端发送响应,直到缓冲小于此值
    proxy_busy_buffers_size 96k;
    //设置nginx每次写数据到临时文件的size(大小)限制
    proxy_temp_file_write_size 96k;
    //从后端服务器接收的临时文件的存放路径
    proxy_temp_path /tmp/temp_dir;
    //设置缓存的路径和其他参数。被缓存的数据如果在inactive参数(当前为1天)指定的时间内未被访问,就会被从缓存中移除
    proxy_cache_path /tmp/cache levels=1:2 keys_zone=cache_one:100m inactive=1d max_size=10g;


    server {
        listen       80 default_server;
        server_name  localhost;
        root /mnt/blog/;

        location / {

        }

        #要缓存文件的后缀,可以在以下设置。
        location ~ .*\.(gif|jpg|png|css|js)(.*) {
                //nginx缓存里拿不到资源,向该地址转发请求,拿到新的资源,并进行缓存
                proxy_pass http://address;
                //设置后端服务器“Location”响应头和“Refresh”响应头的替换文本
                proxy_redirect off;
                //允许重新定义或者添加发往后端服务器的请求头
                proxy_set_header Host $host;
                //指定用于页面缓存的共享内存,对应http层设置的keys_zone
                proxy_cache cache_one;
                //为不同的响应状态码设置不同的缓存时间
                proxy_cache_valid 200 302 24h;
                proxy_cache_valid 301 30d;
                proxy_cache_valid any 5m;
                //缓存时间
                expires 90d;
        }
    }
}

2. nginx 配置文件组成

nginx 配置存储在 nginx.conf 的文件中,主要分为通用配置、event 配置、 http 配置三部分。

2.1 通用配置

user admin;                               #定义Nginx运行的用户
error_log ar/loginx/error.log info;       #全局错误日志定义类型,[ debug | info | notice | warn | error | crit ]
access_log off;                           #定义本虚拟主机的访问日志
pid ar/runinx.pid;                        #进程文件
worker_processes auto;                    #nginx进程数
worker_rlimit_nofile 65535;               #一个nginx进程打开的最多文件描述符数目

2.2 event 配置

events{
use epoll;                   #设置用于复用客户端线程的轮询方法,[ kqueue | rtsig | epoll | /dev/poll | select | poll ]
worker_connections 65535;    #单个进程最大连接数(最大连接数=连接数*进程数)
multi_accept on;             #开启后告诉nginx收到一个新连接通知后接受尽可能多的连接
}

HTTP 模块是 nginx 配置核心模块,将单独抽出一小节详细说明。

HTTP 模块配置说明

3.1 http 模块通用配置

http{
server_tokens off;                        #开启或关闭在错误信息的“Server”响应头中输出nginx版本号
include mime.types;                       #文件扩展名与文件类型映射表
default_type application/octet-stream;    #默认文件类型
charset utf-8;                            #默认编码
server_names_hash_bucket_size 128;        #服务器名字的hash表大小
client_header_buffer_size 32k;            #设置读取客户端请求头部的缓冲容量
large_client_header_buffers 4 64k;        #设置读取客户端请求超大请求的缓冲最大number(数量)和每块缓冲的size(容量)
client_max_body_size 8m;                  #设定请求缓存
sendfile on;                              #开启高效文件传输模式
autoindex on;                             #开启目录列表访问,合适下载服务器,默认关闭。
tcp_nopush on;                            #开启或者关闭nginx在FreeBSD上使用TCP_NOPUSH套接字选项
tcp_nodelay on;                           #开启或关闭nginx使用TCP_NODELAY选项的功能
keepalive_timeout 120;                    #长连接超时时间,单位是秒
reset_timedout_connection on;             #开启或关闭重置超时连接的功能
}

3.2 location 配置说明

location 先精确匹配,再匹配正则,搜索到就停止:

  • = 开头,精确匹配
  • / 开头,通配匹配,如果没有其它匹配,任何请求都会匹配到
  • ^~ 开头,表示 uri 以某个常规字符开头,非正则匹配
  • ~ 开头,表示区分大小写的正则匹配
  • ~* 开头,表示不区分大小写的正则匹配

rewrite 使用

主要功能是实现 URL 的重写,nginx 的 rewite 功能是使用 nginx 提供的全局变量或自己设置的变量,结合正则表达式和标志位实现 URL 重写以及重定向

指令执行的顺序:

  1. 执行 server 块的 rewrite 指令
  2. 执行 location 匹配
  3. 执行选定的 loacation 的 rewrite 指令

语法: rewrite regex URL [flag]

  • regex : 正则表达式匹配规则
  • URL:重定向规则
  • flag:标记为, 302 表示临时重定向,301 表示永久重定向

3.3 全局变量

  • $remote_addr: 客户端 IP
  • $binary_remote_addr:客户端二进制 IP
  • $remote_port: 客户端 Port
  • $remote_user:已经过 Auth Basic Module 验证的用户名
  • $host:请求主机头字段,否则为服务器名称, 如:www.baidu.com
  • $request:用户请求信息,如:GET ?a=1&b=2 HTTP/1.1
  • $request_filename:当前请求文件的路径名
  • $status: 请求响应的状态码
  • $body_bytes_sent:响应时送出的 body 字节数量
  • $content_length:请求行的「content-length」的值
  • $content_type:请求行的「content-type」的值
  • $http_referer:引用地址
  • $http_user_agent:客户端的 agent,eg Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.76 Safari/537.361
  • $args:与 $query_string 相同,等于 URL 的参数(GET), 如 a=1&b=2
  • $document_uri:与 $uri 相同,当前请求的 URI,不包括任何参数
  • $document_root:针对当前请求的根路径设置的值
  • $hostname:主机名,如 centos53.localdomain
  • $http_cookie:客户端 cookie 信息
  • $limit_rate:限制连接速率, 0 表示不限速
  • $query_string:与 $arg 相同,等于 URL 的参数(GET), 如 a=1&b=2
  • $request_body:记录 POST 过来的数据信息
  • $request_body_file:客户端请求主题信息的临时文件
  • $request_method:客户端请求的方法信息,eg,GET
  • $request_uri:包含请求的原始 URI ,不包含主机名,如:/2013/81.html
  • $server_protocol:请求使用的协议,如:HTTP/1.1
  • $server_addr:服务器 IP 地址
  • $server_name:服务器名称,如 www.baidu.com
  • $server_port:请求到达服务器的端口号,如:80
  • $1:表示路径中正则表达式匹配的第一个参数,eg:
location ~/xiyan/(.*){
}
访问 locahost:8080/xiyan/xingguang 时, $1 = "xingguang"

4.特殊配置说明

4.1 特殊 Header 说明

HTTP头是可以包含英文字母([A-Za-z])、数字([0-9])、连接号(-), 也可义是下划线(_)。在使用 nginx 的时候应该避免使用包含下划线的 HTTP 头。主要的原因是:

  • 默认的情况下 nginx 引用 header 变量时不能使用带下划线的变量。要解决这样的问题只能单独配置underscores_in_headers on。
  • 默认的情况下会忽略掉带下划线的变量。要解决这个需要配置ignore_invalid_headers off。

以上总结了笔者最近遇到的所有配置项的说明,初次使用如有不准确的地方,欢迎支持,非常感谢。

5.参考资料

  • nginx documentation
  • Module ngx_http_core_module
  • 自定义 HTTP 头时的注意事项
  • ngx_http_upstream_check_module
  • nginx 详解 - 详细配置说明
  • niginx 静态资源配置
  • 使用 nginx 缓存服务器上的静态文件