鼎鼎知识库
Nevar pievienot vairāk kā 25 tēmas Tēmai ir jāsākas ar burtu vai ciparu, tā var saturēt domu zīmes ('-') un var būt līdz 35 simboliem gara.

17详解HTTP模块.md 6.9KB

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]

11个阶段之前的处理

处理HTTP请求头部。

--操作系统内核
	三次握手,SYN, SYN-ACK, ACK
	Nginx选择自己的worker
--事件模块
	worker进程通过epoll_wait方法返回获取刚才建立连接的句柄
	拿到建立连接的句柄,是一个读事件
	调用accept方法,分配连接内存池,内存池包括连接内存池和请求内存池(connection_pool_size:512)
--HTTP模块
	通过一个回调方法,把读事件通过epoll_ctl函数添加到epoll的事件队列中,并且添加超时定时器(client_header_timeout:60s)
	

当客户端再次发送请求,操作系统读取报文,把请求交给NginxHTTP模块,把内核中的DATA读取到用户态的内存(大小通过client_header_bufer_size:1k)中。具体如下:

--分配请求内存池:request_pool_size:4k
--状态机解析请求行
--分配大内存:large_client_header_buffers 4 8k;最多32k
--状态机解析请求行
--标识URI
--状态机解析header
--分配大内存large_client_header_buffers:4 8k
--标识header
--移除超时定时器:client_header_timeout:60s
--开始11个阶段的http请求处理

正则表达式

正则表达式--元字符

. 换行符以外的任意
\w
\s 空白
\d
\b 单词
^ 字符串开始
$ 字符串结束

正则表达式--重复

* 零或更多
+ 一次或更多
? 零次或一次
{n}重复n次
{n,}n次或更多
{n,m}n到m次

正则表达式,例子

原始:/admin/website/article/35/change/uploads/party/5.jpg
编写正则表达式:/^\/admin\/website\/article\/(\d+)\/change\/uploads\/(\w+)\/(\w+)\.(png|jpg|gif|jpeg|bmp)$/
使用工具:pcretest
输入正则标识
观察结果

处理请求,使用哪一个server

--跟多个域名
	server_name example.com www.example.com
--泛域名
	server_name *.example.com
--正则表达式
	server_name ~^www\.d+\.example\.com$;

server_name_in_redirect的使用

--配置文件

server {
	server_name primary.example.com  second.example.com;
	server_name_in_redirect on;
	return 302 /redirect;
}
--请求:curl second.exmaple.com -I
Location:http://primary.example.com/redirect

使用正则表达式创建变量

server {
	server_name ~^(www\.)?(.+)$;
	location / {root /sites/$2;}
}

server {
	server_name ~^(www\.)?(?<domain>.+)$;
	location / {root/sites/$domain;}
}

另外

.example.com 匹配example.com  *.example.com
_匹配所有域名
""匹配没有传递Host头部的情况

请求的11个阶段

--POST_READ:处理请求头之后,realip模块处理
--SEVER_REWRITE:rewrite模块
--FIND_CONFIG:
--REWRITE:rewrite模块
--POST_REWRITE
--PRE_ACCESS:使用limit_conn, limit_req模块
--ACCESS:使用auth_basic, access, auth_request模块
--POST_ACCESS
--PRECONTENT:使用try_files模块
--CONTENT:使用index, autoindex, concat模块
--LOG:使用access_log模块

11个阶段顺序处理

--postread
	realip模块
	rewrite模块
	find_config模块
	rewrite模块
--preaccess
	limit_req模块
	limit_conn模块
--access
	access模块
	auth_basic模块
	auth_request模块
--precontent
	tyr_files模块
	mirrorsMok 
--content
	concat模块
	random_index模块
	index模块
	auto_index模块
	static模块
--log

postread阶段的realip模块

server {
	server_name realip.example.com;
	
	error_log logs/myerror.log debug;
	set_real_ip_from xx.xx.xx.xx;
	real_ip_recursive off;
	real_ip_header X-Forwarded-For;
	
	location / {
		return 200 "Client real ip: $remote_addr\n";
	}
}

--请求:curl -H 'X-Forwared-For:1.1.1.1,xx.xx.xx.xx' realip.example.com

postread阶段的rewrite模块

--postread
	realip模块
	rewrite模块
	find_config模块
	rewrite模块

如果rewrite模块中return,就不会往下执行了。

return指令

444:关闭连接
301:永久重定向
302:临时重定向
303: 临时重定向,允许改变方法,禁止被缓存
307: 临时重定向,允许改变方法,禁止被缓存
308: 永久重定向,不允许改变方法

error_page指令

error_page 404 /404.html;
error_page 500 502 503 504 /50x.html;
error_page 404=200 /empty.gif;
error_page 404=/404.php;

location / {
	error_page 404=@fallback;
}
location @fallback {
	proxy_pass http:backend;
}

error_page 403 http://example.com/s.html;
error_page 404=201 http://example.com/b.html;

例子

server {
	server_name www.example.com;
	listen 8080;
	
	root html/;
	error_page 404 /403.html;
	location / {
		return 404 "find nothing";	
	}
}
返回"find nothing"


server {
	server_name www.example.com;
	listen 8080;
	
	root html/;
	error_page 404 /403.html;
	return 405;
	location / {
		return 404 "find nothing";	
	}
}
返回"405"

rewrite指令,用来替换url

rewrite regex replacement[flag];

--当replacement以http://, https://, $schema开头,返回302
--flag指定方式
	--last: 把replacement作为新的url与location匹配
	--break:停止当前脚本执行
	--redirect:302重定向
	--perment:301重定向

rewrite指令例子

root html/;
locatioin /first {
	rewrite /first(.*)/second$1 last;
	return 200 'first';
}

rewrite指令中的if指令

if($http_user_agen~MSIE) {
	rewrite ^(.*)$/msie/$1 break;
}

postread阶段的find_config

location指令

= 精确匹配
^~匹配上后则不再进行正则表达式匹配
~大小写敏感正则匹配
~*大小写不敏感正则匹配

preaccess阶段限制并发连接数

limit_conn_zone $binary_remote_addr zone=addr:10m;
server {
	server_name www.example.com;
	root html/;
	error_log myerror.log info;
	
	location / {
		limit_conn_status 500;
		limit_conn_log_level warn;
		limit_rate 50;//每秒50次
		limit_conn addr 1; //1个字节
	}
}

preaccess限制每秒处理请求数


limit_req_zone $binary_remote_addr zone=one:10m rate=2/m;
server {
	server_name www.example.com;
	root html/;
	error_log myerror.log info;
	
	location / {
		limit_conn_status 500;
		limit_conn_log_level warn;
		limit_req zone=one;
		#limit_req zone=one burst=3 nodelay;
	}
}

access阶段对ip做限制

access模块。

location / {
	deny 192.168.8.1;
	allow ...;
}

access阶段对用户名密码做限制

auth_basic模块。使用了RFC2617协议中的HTTP Basic Authentication。本身用明文,但用了HTTPS以后加密。

access阶段使用第三方做权限控制

auth_request模块。

access阶段的satisfy指令

precontent阶段按序访问资源

try_files模块。

precontent阶段实时拷贝流量

mirror模块。

content阶段rootalias指令

static模块

indexautoindex模块

提升多个小文件性能的concat模块

过滤模块

Nginx变量

提升连接效率

keepalive