「Nginx」Nginx配置入门

转载请注明出处: blog.csdn.net/jinixin/article/details/89975303

 

本篇文章不会做深入讲解, 阅读本篇文章, 也只能使你对配置有简单了解. 配置这部分内容比较多, 像前篇所提到的静态资源服务器, 虚拟主机, 反向代理都是需要依靠合理配置来实现的.

 

 

配置文件

 

配置文件名为”nginx.conf”, 默认位于”/etc/nginx/nginx.conf”. 如不确定, 可以使用”nginx -t”或”locate nginx.conf”命令进行定位.

 

 

命令类型

 

配置文件是由各种命令构成的, 根据是否嵌套可分为简单命令与复杂命令两种.

1. 简单命令形如:

命令A 参数列表;

 

2. 复杂命令形如:

命令A 参数列表 {

    命令B 参数列表;

}

命令A也被称为命令B的上下文.

 

 

配置文件结构

 

配置文件是由命令构成的, 命令间互相嵌套形成块, 块可分为main, events, http, server, location, upstream这6种, 大致结构如下:

main {

    # 配置工作进程数量, 日志文件位置, 连接最长保持时间等

    events {

        # 配置处理连接的方式

    }

    http {

        # 配置服务器与虚拟主机

        server {

            location {

                # 配置URI的路由规则

            }

            upstream {

                # 配置应用服务器集群

            }

        }

    }

}

Nginx常用于在客户端与应用服务器间转发请求与响应, 下面就简单谈下路由算法, 即如何根据请求找到目标应用服务器.

 

 

路由算法

 

我理解的路由算法大致分为两步, 首先是根据请求的目标域名和端口来路由server, 接着是在选定的server中根据请求的URI来路由location.

 

路由server

http块下可以有多个server块, 用以表示不同的主机, 不同的主机监听不同的域名和端口.

server块中最重要的是listen与server_name命令. listen命令表示该server块所监听的端口, server上下文中支持多条listen命令. server_name命令表示该server块所监听的域名.

 

http {

    server {

        listen      80;

        listen      81;

        server_name example.org www.example.org;

        # ...

    }

    server {

        listen      80 default_server;

        server_name example.net;

        # ...

    }

    server {

        listen      80;

        server_name example.com;

        # ...

    }

}

上面3个server都在监听80端口, 但之间作用范围其实并不重叠. 所有发送给”[www.]example.org:80"或"[www.]example.org:81"端口的请求, 都会分给第1个server块处理; 所有发送给”example.net:80"端口的请求, 都会分给第2个server块处理; 所有发送给”example.com:80"端口的请求, 都会分给第3个server块处理. 此时相当于在1台机器上处理3个不同域名的请求, 这便是Nginx的虚拟主机服务.

 

那么你也许会有这样的疑惑, 如果当前Nginx收到发送给”monkey.com:80”端口的请求, 其会交给第几个server块处理呢?

这就涉及端口默认主机的情况了, 可以通过在listen命令后加上default_server参数, 将该server块指定为该端口的默认server. 若没有default_server参数显性指明, 其便会选取第一个监听该端口的server块. 所以发给”monkey.com:80”端口的请求会转给第2个server块处理, 第二个server块是80端口的默认主机.

这里顺带提下, default_server参数是关于端口的属性, 而不是关于域名的属性. 实际上常在配置中加入以下server块:

server {

    listen      80 default_server;

    return     404;

}

用于接收未知域名的请求, 该server块将返回404响应, 并关闭连接.

 

路由server的过程

首先匹配端口, 将请求头Host字段中携带的目标端口与server块中监听的端口依次比较, 过滤出所有匹配的server块. 接着匹配域名, 在先前过滤出的所有server块里, 将请求头Host字段中携带的目标域名与server_name比较, 如有匹配的server块, 即为目标server. 若没有server_name与目标域名相匹配, 则选择该端口的默认主机作为目标server.

上面的端口匹配, 仅有精确匹配, 即比较双方完全相等. 而域名匹配则不只有精确匹配, 还有通配符匹配与正则匹配, 下面详细介绍:

server {

    listen       80;

    server_name  example.com mail.example.com;

    # 精确匹配

}

server {

    listen       80;

    server_name  *.example.com;

    # 通配符匹配

}

server {

    listen       80;

    server_name  mail.*;

    # 通配符匹配

}

server {

    listen       80;

    server_name  ~^.+\.example\.com$;

    # 正则匹配

}

关于通配符匹配, 上面的“*”即为通配符, 要注意的是:

1) 通配符只能出现在开头或结尾, 不能出现在中间, 比如”mail.*.com”就是错误的;

2) 通配符可匹配一个或多个单词, 比如“*.example.org”可以匹配”www.example.org”和"www.sub.example.org";

3) ”.example.org”比较特殊, 不仅可以与"example.org"精确匹配, 也可进行通配符匹配"*.example.org"

 

关于正则匹配, 即正则表达式匹配, 必须以”~”开头:

1) 为便于识别, 记得配对”^”与”$”.

2) 域名分隔符”.”记得要用反斜杠转义.

3) 如果正则式中出现了{}, 记得给整个正则式加上双引号.

 

这里就要抛出一个问题了, Nginx收到发给”mail.example.com:80”端口的请求, 该发给哪个server块处理呢?

很明显”mail.example.com:80”符合上述所有的server块, 此时请参照以下规则:

当配置中多个server组拥有相同端口时, 目标域名将按以下顺序匹配server_name, 匹配成功即为目标server:

1) 精确匹配

2) 以*开头的最长通配符

3) 以*结尾的最长通配符

4) 在配置文件中从上至下第一个匹配的正则式

 

举例:

某个HTTP请求头:

GET / HTTP/1.1

Host: monkey.com:10002

Connection: keep-alive

Cache-Control: no-cache

User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36

Accept: text/html

Accept-Encoding: gzip, deflate

Accept-Language: zh-CN, zh

 

Nginx配置如下:

server {

    listen       10002 default_server;

    return       403;

}

server {

    listen       10002;

    server_name www.monkey.com monkey.com;

}

server {

    listen       10003 default_server;

    server_name www.monkey.net monkey.net;

}

首先进行端口匹配, 过滤出第1个server和第2个server符合要求; 接着对过滤出的server组进行域名匹配, 目标域名精确匹配第2个server的server_name符合, 故该请求将转给第2个server块处理.

 

路由location

一个server块下可以有多个location块, Nginx在确认是哪个server块来处理请求后, 其就会在该server块下根据请求的URI匹配location块.

location命令支持最长前缀匹配与正则匹配, 前缀匹配的location参数是字符串, 正则匹配的location参数则以”~”开头. Nginx会首先对URI进行最长前缀匹配, 记录下最合适的location块. 接着对URI进行正则匹配, 如果有匹配到正则式, 则使用该式所对应的location块. 如果没有匹配到, 则使用之前通过最长前缀匹配所捕获的location块.

location上下文中较常用的有root命令与proxy_pass命令.

root命令, 会把URI拼接到root命令所示路径后构成本地路径, 获取并向客户端返回该文件, 此时Nginx就起到了静态资源服务器的作用, 这部分请求直接由Nginx处理, 从而减小其背后应用服务器的访问压力.

proxy_pass命令, 此时Nginx便起到反向代理服务器的作用. 即接收客户端请求并转发给应用服务器, 接收响应后再转发给客户端.

 

直接来看一个例子:

server {

    listen      8080;

    server_name example.com www.example.com;

    root        /data/www;

 

    location / {

        index   index.html index.php;

    }

    location ~ \.(gif|jpg|png)$ {

        expires 30d;  # 响应缓存30天

    }

    location ~ \.php$ {

        proxy_pass http://localhost:8080;

        proxy_set_header Accept-language zh,zh-CN;

    }

}

该主机监听8080端口, 注意root是放在server上下文中的, 此时若某请求匹配到的location块中没有root命令, 就会采用server块中的root命令.

假设URI为”/logo.gif”, 首先进行最长前缀匹配, 确定为第1个location块; 其次再进行正则匹配, 确定为第2个location块; 故最终选择后者, 并根据root命令映射URI到本机”/data/www/logo.gif”, 向客户端返回该资源.

例子中的proxy_set_header, 可对代理接收到的请求头增加或替换某字段, 以便将新值传给应用服务器. 当值为””时, 该字段便不会传给应用服务器.

proxy_set_header 域名 值;

 

捕获正则式

可以使用(?<domain>.+)捕获正则式, 配合root使用:

server {

    server_name   ~^(www\.)?(?<domain>.+)$;

    location / {

        root   /sites/$domain;

    }

}

 

负载均衡

location块可以通过proxy_pass命令, 将请求转发给某个应用服务器, 这里Nginx提供了一个便捷, 就是可以用upstream命令将多台服务器组成应用服务器阵列. 此时Nginx将成为一个负载均衡器, 将流量按算法分配到其背后的应用服务器上, 其支持以下几种方式的负载均衡:

 

1. 轮询(默认)

http {

    upstream example_array {

        server s1.example_array.com;

        server s2.example_array.com;

        server s3.example_array.com;

    }

    server {

        listen 80;

        location / {

            proxy_pass http://example_array;

        }

    }

}

所有请求都会被转发给”example_array”服务器集群, 请求会依次轮流分配给集群中的服务器. 如果想要使用HTTPS协议, 把协议名改为https即可. 其他则需要更换命令名称: FastCGI使用fastcgi_pass, uwsgi使用uwsgi_pass, memcached使用memcached_pass, gRPC使用grpc_pass.

 

2. 最少连接数

Nginx会把请求转发给当前集群中活跃连接数最少的应用服务器.

http {

    upstream example_array {

        least_conn;

        server s1.example_array.com;

        server s2.example_array.com;

        server s3.example_array.com;

    }

    server {

        listen 80;

        location / {

            proxy_pass http://example_array;

        }

    }

}

 

3. IP哈希

以客户端的IP地址作为hash的key, 使得某客户端的全部请求都能交给集群中某指定服务器, 便于服务器的session效果最大化.

http {

    upstream example_array {

        ip_hash;

        server s1.example_array.com weight=3 mail_fails=2 fail_timeout=30s;

        server s2.example_array.com;

        server s3.example_array.com;

    }

    server {

        listen 80;

        location / {

            proxy_pass http://example_array;

        }

    }

}

上面例子中列出了upstream的server命令三个常用参数:

 

1) weight参数

用以表示服务器承担请求的权重, 默认为1. 上例中, 平均每5个请求中, 有3个会分给s1, 其余s2与s3各分1个.

 

2) mail_fails与fail_timeout参数

Nginx反向代理包含被动的健康检查机制: 如果在fail_timeout时间内从某服务器上收到多于max_fails个异常响应, Nginx会将该服务器标记为"失败"状态, 并在其后fail_timeout时间内避免向该服务器发送后续请求. 经过这段时间后, Nginx会小心翼翼的对该"失败"服务器发送一个请求, 如果成功响应, 则将该服务器标记为"正常"状态.

max_fails参数默认为1, 当为0时, 被动的健康检查机制会被关闭. fail_timeout参数默认为10s.

 

 

文中如有不当之处, 还望包容和指出, 谢谢

 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值