之前介绍了Nginx作为静态资源服务器的用法,除此之外,Nginx更多的场景是作为反向代理服务器,提高网站的并发和可用性。下面几节着重说一下作为反向代理的http模块,并且了解一些Nginx的架构。
一. 前言
1. 指令冲突时以谁为准
Nginx的大多指令都支持多层级配置,比如配置在server层或者location层都可以生效。当指令冲突时,Nginx会遵从如下几个原则。
a)Nginx的指令分为两种:值指令和动作指令,值指令是指存储配置项的值 比如root、access_log,动作指令是指定Nginx的行为 比如rewrite proxy_pass。遇到动作指令时Nginx会直接执行相关的功能(比如重定向),并根据该功能的返回值决定是否继续往下执行。所以动作类指令是遇到一个执行一个,不会合并。而值指令是Nginx执行流程过程中去读取相关配置的值,而读取到的值只能是一个。所以值指令是运行时获取的配置,会将相同的值指令进行合并。
b)值指令合并规则:向上覆盖。子配置不存在时,使用父配置块。子配置存在时,覆盖父配置块。
二. Listen指令
listen指令放在server配置块下,监听端口或者地址,使Nginx和客户端可以建立一个tcp连接。
例: listen unix:/var/run/nginx.sock;
listen 127.0.0.1:8000;
listen 127.0.0.1;
listen 8000;
listen *:8000;
listen localhost:8000 bind;
listen [::]8000 ipv6only=on;
listen [::1]
三. 接收请求事件模块
建立了listen监听端口以后,客户端就可以与Nginx进行通讯了,Nginx做的第一步就是接收请求。
客户端的请求发送到服务器后,会与操作系统的内核(端口)建立三次握手连接。当Nginx监听到端口成功建立起一个连接后,会从内核态将连接拷贝到Nginx用户态,然后由Nginx会根据它的负载均衡算法选择一个worker进程为这个连接添加一个epoll_wait读事件,然后调用accept方法为连接分配连接内存池、添加接收data数据超时定时器等。当客户端发送data以后,还是会经由内核态拷贝到Nginx用户态,Nginx添加另一个epoll_wait读事件来分配内存、解析请求头、关闭超时定时器等。如下图所示:
四. 接收请求HTTP模块
Nginx建立好连接并接收完header后,就会正式进入到Http模块了。Http模块有十一个处理流程,如下图所示:
五. server_name指令
server_name指令绑定域名,指令后可以跟多个域名,第一个是主域名,可以出现在http、server、location模块下
泛域名:仅支持在最前或最后,如:server_name *.taobao.com;
正则表达式:加~前缀 server_name www.taobao.com ~^www\.taobao\.\d+\.com$;
正则表达式创建变量,用()括起正则表达式,使用$1 $2获取变量
server_name_in_redirect on|off 命令:如果为off时,那么将会以当前服务器的IP地址进行拼接URL;如果该命令为on,那么首先查找server_name,如果没有找到,查找请求头的HOST字段,如果没有,则以当前服务器的IP进行拼接。
server匹配顺序
- 精确匹配
- *在前的泛域名
- *在后的泛域名
- 按文件中的顺序匹配正则表达式域名
- default server:第1个 或者是listen指定的default
·
六. HTTP请求处理的11个阶段
- POST_READ:获取到Header后的第一个阶段。模块:realip
- SERVER_REWRITE:配置在server模块中的rewrite阶段。模块:rewrite
- FIND_CONFIG:根据配置查找由谁处理请求的阶段。
- REWRITE:配置在location模块中的rewrite阶段。模块:rewrite
- POST_REWRITE
- PREACCESS:向上游服务请求连接前的阶段。模块:limit_conn、limit_req
- ACCESS:与上游服务器连接的验证阶段。模块:auth_basic、access、auth_request
- POST_ACCESS
- PRECONTENT:发送data数据前的阶段。模块:try_files
- CONTENT:发送数据极端。模块:index、autoindex、concat
- LOG:记录请求日志、错误日志阶段。模块:access_log