Nginx

 

安装 Nginx

RHEL/CentOS

Install prerequisites

sudo yum install yum-utils

Set up the yum repository

vim /etc/yum.repos.d/nginx.repo
[nginx-stable]
name=nginx stable repo
baseurl=http://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true
proxy=http://127.0.0.1:7890

[nginx-mainline]
name=nginx mainline repo
baseurl=http://nginx.org/packages/mainline/centos/$releasever/$basearch/
gpgcheck=1
enabled=0
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true

Check the nginx repo is enabled

yum repoinfo nginx-stable

Install nginx

yum install nginx

配置 Nginx

配置文件 nginx.conf 通常放在以下目录:

  • /usr/local/nginx/conf
  • /usr/local/etc/nginx
  • /etc/nginx

检查配置文件的语法是否正确

# 使用默认的 /etc/nginx/nginx.conf 文件
nginx -t

# 指定要检查的配置文件
nginx -t -c /etc/nginx/my.conf

修改配置后需要使用下面的命令重新加载配置

nginx -s reload

Nginx 由 模块 (modules) 组成,模块由配置文件中的 指令 (directives) 控制,指令分为:

  • 简单指令 (simple directives)

  • 块指令 (block directives).

    • 块指令的大括号范围称为 上下文 (context).

    • 任何上下文之外的范围称为 主上下文 (main context).

Uniform Resource Locator (URL)

URL

HTTP Load Balancing

一个最简单的负载均衡配置

http {
    upstream backend {
        ip_hash;
        server backend1.example.com;
        server backend2.example.com;
        server 192.0.0.1 backup;
    }

    server {
        location / {
            proxy_pass http://backend;
        }
    }
}
  • http 上下文

    • upstream 指令定义一个 服务器组

      • server 指令用来配置服务器,注意不要和 http 中用来配置虚拟服务器的 server block 搞混。

      • 负载均衡策略

        • round_robin: 默认策略,没有指令,HTTP 请求平均分配到各服务器。
        • least_conn: HTTP 请求会被分配到激活连接最小的服务器上。
        • ip_hash: HTTP 请求分配到哪个服务器由客户端 IP 来决定,IPv4 地址的前三组八位数或 IPv6 的整个地址被用来计算哈希值,这种策略保证相同来源的请求会被发送到相同的服务器上。
        • hash: HTTP 请求分配到哪个服务器由用户定义的 key 来决定,可以是字符串,变量或它们的组合。例如 key 可以是客户端 IP 和端口的组合,或者是一个 URI。
    • server 块指令定义一个 虚拟服务器 (Virutal Server)

      • server_name 用来设置 Virtual Server 的名称,nginx 通过请求头中的 Host 字段来决定将请求路由到哪个虚拟服务器。查看 How nginx processes a request 来了解 nginx 如何决定用哪个 server_name 来处理请求。
      • location 块指令用来匹配 HTTP 请求中的 URI。

        • proxy_pass 指令设置后端服务器的协议和地址,以及可选的 URI,然后将请求转发出去。请求中的 URI 被转发的规则如下:

          • proxy_pass 指定了 URI,则客户端请求的 URI 中 location 匹配的部分会被指令中指定的 URI 替换。
          • proxy_pass 没有指定 URI,转发给后端服务器的 URI 与客户端请求的 URI 一致。

location 指令说明

location 指令使用 前辍字符串 (prefix stringprefix location) 和 正则表达式 来进行匹配。

location [ = | ~ | ~* | ^~ ] uri { ... }
location @name { ... }

location 的匹配顺序

优先级 修饰符 作用
最高 = 使用前辍字符串对 URI 进行精确匹配,一旦匹配,立即处理,停止其它匹配
^~ 使用前辍字符串对 URI 进行最长匹配,一旦匹配,立即处理,不再检查正则表达式
~ 使用正则表达式对 URI 进行匹配,区分大小写,一旦匹配,立即处理
~* 使用正则表达式对 URI 进行匹配,不区分大小写,一旦匹配,立即处理
最低 使用前辍字符串对 URI 进行最长匹配
# 精确匹配,只匹配 URI='/',不会匹配 '/foo',一旦匹配,停止其它匹配
location = / {}

# 最长匹配,可以匹配 '/images/1.png',不再检查正则表达式匹配
location ^~ /images/ {}

# 正则表达式匹配,不区分大小写,可以匹配 'documents/1.jpg'
location ~* \.(jpg|jpeg|gif|png)$ {}

# 无修饰符最长匹配,可以匹配 '/documents/topic.html'
location /documents/ {}

# 无修饰符最长匹配,可以匹配 '/documents/topic.html',优先级低于上一条
location /doc/ {}

# 无修饰符最长匹配,可以匹配 '/documents/topic.html',优先级最低
location / {}

proxy_pass 指令说明

proxy_pass URL;

proxy_pass 指令设置要转发的后端服务器 (Proxied Server) 的协议和地址,以及可选的 URI。协议可以是 httphttps,地址可以是域名或 IP 地址,以及端口:

proxy_pass http://proxied_server:8000/uri/;

proxy_pass 对匹配的 URI 有以下替换规则,假如有一个请求是 https://www.yourserver.net/v1/api/login

location /v1/ {
    # 转发请求的 URI 是 '/v2/',替换 '/v1/'
    # 转发结果是 http://backend/v2/api/login
    proxy_pass http://backend/v2/;
}

location /v1/ {
    # 转发请求的 URI 是 '/',替换 '/v1/'
    # 转发结果是 http://backend/api/login
    proxy_pass http://backend/;
}

location /v1/ {
    # 转发请求的 URI 是 '/new',替换 '/v1/'
    # 转发结果是 http://backend/newapi/login
    proxy_pass http://backend/new;
}

location /v1/api/ {
    # 转发请求没有指定 URI,不进行替换
    # 转发结果是 http://backend/v1/api/login
    proxy_pass http://backend;
}

HTTP Request Header

Host

这个请求头指明客户端要将请求发送到的服务器主机名端口号。如果通过反向代理,这里就是反向代理的主机名和端口号。如果没有提供端口号,会自动使用请求协议对应的默认端口,例如 HTTP 使用 80 端口,HTTPS 使用 443 端口。

Host: host:port

Nginx 使用内嵌变量 $host$server_port 来提供对应的值。

proxy_set_header   Host   $host:$server_port;

X-Forwarded-For

这个请求头指明客户端的实际 IP 地址,如果经过多个反向代理,每个反向代理的 IP 地址也会被记录在内,其语法为:

X-Forwarded-For: client_ip, proxy1_ip, proxy2_ip

Nginx 使用内嵌变量 $proxy_add_x_forwarded_for 来设置它的值,

proxy_set_header   X-Forwarded-For   $proxy_add_x_forwarded_for;

如果 X-Forwarded-For 没有出现在请求头,$proxy_add_x_forwarded_for 将与 $remote_addr 一样。

X-Real-IP

这不是一个标准的请求头,但被普遍使用,用来指明客户端的实际 IP 地址,其作用与 X-Forwarded-For 相似,但 X-Forwarded-For 属于 RFC 7239 标准。Nginx 一般使用 $remote_addr 来设置它的值,

proxy_set_header   X-Real-IP   $remote_addr;

X-Forwarded-Proto

这个请求头指明客户端实际使用的传输协议 (HTTP 或 HTTPS),这样在服务器访问日志中可以准确记录客户端使用的传输协议,而非反向代理使用的协议。Nginx 使用内嵌变量 $scheme 来设置它的值。

proxy_set_header   X-Forwarded-Proto   $scheme;