鼎鼎知识库
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

17详解HTTP模块.md 6.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460
  1. ```
  2. listen unix:/var/run/nginx.sock;
  3. listen 127.0.0.1:8000;
  4. listen 127.0.0.1;
  5. listen 8000;
  6. listen *:8000;
  7. listen localhost:8000 bind;
  8. listen [::]:8000 ipv6only=on;
  9. listen [::1]
  10. ```
  11. # 11个阶段之前的处理
  12. 处理`HTTP`请求头部。
  13. ```
  14. --操作系统内核
  15. 三次握手,SYN, SYN-ACK, ACK
  16. Nginx选择自己的worker
  17. --事件模块
  18. worker进程通过epoll_wait方法返回获取刚才建立连接的句柄
  19. 拿到建立连接的句柄,是一个读事件
  20. 调用accept方法,分配连接内存池,内存池包括连接内存池和请求内存池(connection_pool_size:512)
  21. --HTTP模块
  22. 通过一个回调方法,把读事件通过epoll_ctl函数添加到epoll的事件队列中,并且添加超时定时器(client_header_timeout:60s)
  23. ```
  24. 当客户端再次发送请求,操作系统读取报文,把请求交给`Nginx`的`HTTP`模块,把内核中的DATA读取到用户态的内存(大小通过`client_header_bufer_size`:`1k`)中。具体如下:
  25. ```
  26. --分配请求内存池:request_pool_size:4k
  27. --状态机解析请求行
  28. --分配大内存:large_client_header_buffers 4 8k;最多32k
  29. --状态机解析请求行
  30. --标识URI
  31. --状态机解析header
  32. --分配大内存large_client_header_buffers:4 8k
  33. --标识header
  34. --移除超时定时器:client_header_timeout:60s
  35. --开始11个阶段的http请求处理
  36. ```
  37. # 正则表达式
  38. 正则表达式--元字符
  39. ```
  40. . 换行符以外的任意
  41. \w
  42. \s 空白
  43. \d
  44. \b 单词
  45. ^ 字符串开始
  46. $ 字符串结束
  47. ```
  48. 正则表达式--重复
  49. ```
  50. * 零或更多
  51. + 一次或更多
  52. ? 零次或一次
  53. {n}重复n次
  54. {n,}n次或更多
  55. {n,m}n到m次
  56. ```
  57. 正则表达式,例子
  58. ```
  59. 原始:/admin/website/article/35/change/uploads/party/5.jpg
  60. 编写正则表达式:/^\/admin\/website\/article\/(\d+)\/change\/uploads\/(\w+)\/(\w+)\.(png|jpg|gif|jpeg|bmp)$/
  61. 使用工具:pcretest
  62. 输入正则标识
  63. 观察结果
  64. ```
  65. # 处理请求,使用哪一个`server`
  66. ```
  67. --跟多个域名
  68. server_name example.com www.example.com
  69. --泛域名
  70. server_name *.example.com
  71. --正则表达式
  72. server_name ~^www\.d+\.example\.com$;
  73. ```
  74. `server_name_in_redirect`的使用
  75. ```
  76. --配置文件
  77. server {
  78. server_name primary.example.com second.example.com;
  79. server_name_in_redirect on;
  80. return 302 /redirect;
  81. }
  82. --请求:curl second.exmaple.com -I
  83. Location:http://primary.example.com/redirect
  84. ```
  85. 使用正则表达式创建变量
  86. ```
  87. server {
  88. server_name ~^(www\.)?(.+)$;
  89. location / {root /sites/$2;}
  90. }
  91. server {
  92. server_name ~^(www\.)?(?<domain>.+)$;
  93. location / {root/sites/$domain;}
  94. }
  95. ```
  96. 另外
  97. ```
  98. .example.com 匹配example.com *.example.com
  99. _匹配所有域名
  100. ""匹配没有传递Host头部的情况
  101. ```
  102. # 请求的11个阶段
  103. ```
  104. --POST_READ:处理请求头之后,realip模块处理
  105. --SEVER_REWRITE:rewrite模块
  106. --FIND_CONFIG:
  107. --REWRITE:rewrite模块
  108. --POST_REWRITE
  109. --PRE_ACCESS:使用limit_conn, limit_req模块
  110. --ACCESS:使用auth_basic, access, auth_request模块
  111. --POST_ACCESS
  112. --PRECONTENT:使用try_files模块
  113. --CONTENT:使用index, autoindex, concat模块
  114. --LOG:使用access_log模块
  115. ```
  116. # 11个阶段顺序处理
  117. ```
  118. --postread
  119. realip模块
  120. rewrite模块
  121. find_config模块
  122. rewrite模块
  123. --preaccess
  124. limit_req模块
  125. limit_conn模块
  126. --access
  127. access模块
  128. auth_basic模块
  129. auth_request模块
  130. --precontent
  131. tyr_files模块
  132. mirrorsMok
  133. --content
  134. concat模块
  135. random_index模块
  136. index模块
  137. auto_index模块
  138. static模块
  139. --log
  140. ```
  141. # `postread`阶段的`realip`模块
  142. ```
  143. server {
  144. server_name realip.example.com;
  145. error_log logs/myerror.log debug;
  146. set_real_ip_from xx.xx.xx.xx;
  147. real_ip_recursive off;
  148. real_ip_header X-Forwarded-For;
  149. location / {
  150. return 200 "Client real ip: $remote_addr\n";
  151. }
  152. }
  153. --请求:curl -H 'X-Forwared-For:1.1.1.1,xx.xx.xx.xx' realip.example.com
  154. ```
  155. # `postread`阶段的`rewrite`模块
  156. ```
  157. --postread
  158. realip模块
  159. rewrite模块
  160. find_config模块
  161. rewrite模块
  162. ```
  163. 如果`rewrite`模块中`return`,就不会往下执行了。
  164. `return`指令
  165. ```
  166. 444:关闭连接
  167. 301:永久重定向
  168. 302:临时重定向
  169. 303: 临时重定向,允许改变方法,禁止被缓存
  170. 307: 临时重定向,允许改变方法,禁止被缓存
  171. 308: 永久重定向,不允许改变方法
  172. ```
  173. `error_page`指令
  174. ```
  175. error_page 404 /404.html;
  176. error_page 500 502 503 504 /50x.html;
  177. error_page 404=200 /empty.gif;
  178. error_page 404=/404.php;
  179. location / {
  180. error_page 404=@fallback;
  181. }
  182. location @fallback {
  183. proxy_pass http:backend;
  184. }
  185. error_page 403 http://example.com/s.html;
  186. error_page 404=201 http://example.com/b.html;
  187. ```
  188. 例子
  189. ```
  190. server {
  191. server_name www.example.com;
  192. listen 8080;
  193. root html/;
  194. error_page 404 /403.html;
  195. location / {
  196. return 404 "find nothing";
  197. }
  198. }
  199. 返回"find nothing"
  200. server {
  201. server_name www.example.com;
  202. listen 8080;
  203. root html/;
  204. error_page 404 /403.html;
  205. return 405;
  206. location / {
  207. return 404 "find nothing";
  208. }
  209. }
  210. 返回"405"
  211. ```
  212. `rewrite`指令,用来替换`url`。
  213. ```
  214. rewrite regex replacement[flag];
  215. --当replacement以http://, https://, $schema开头,返回302
  216. --flag指定方式
  217. --last: 把replacement作为新的url与location匹配
  218. --break:停止当前脚本执行
  219. --redirect:302重定向
  220. --perment:301重定向
  221. ```
  222. `rewrite`指令例子
  223. ```
  224. root html/;
  225. locatioin /first {
  226. rewrite /first(.*)/second$1 last;
  227. return 200 'first';
  228. }
  229. ```
  230. `rewrite`指令中的`if`指令
  231. ```
  232. if($http_user_agen~MSIE) {
  233. rewrite ^(.*)$/msie/$1 break;
  234. }
  235. ```
  236. # `postread`阶段的`find_config`
  237. `location`指令
  238. ```
  239. = 精确匹配
  240. ^~匹配上后则不再进行正则表达式匹配
  241. ~大小写敏感正则匹配
  242. ~*大小写不敏感正则匹配
  243. ```
  244. # `preaccess`阶段限制并发连接数
  245. ```
  246. limit_conn_zone $binary_remote_addr zone=addr:10m;
  247. server {
  248. server_name www.example.com;
  249. root html/;
  250. error_log myerror.log info;
  251. location / {
  252. limit_conn_status 500;
  253. limit_conn_log_level warn;
  254. limit_rate 50;//每秒50次
  255. limit_conn addr 1; //1个字节
  256. }
  257. }
  258. ```
  259. # `preaccess`限制每秒处理请求数
  260. ```
  261. limit_req_zone $binary_remote_addr zone=one:10m rate=2/m;
  262. server {
  263. server_name www.example.com;
  264. root html/;
  265. error_log myerror.log info;
  266. location / {
  267. limit_conn_status 500;
  268. limit_conn_log_level warn;
  269. limit_req zone=one;
  270. #limit_req zone=one burst=3 nodelay;
  271. }
  272. }
  273. ```
  274. # `access`阶段对`ip`做限制
  275. `access`模块。
  276. ```
  277. location / {
  278. deny 192.168.8.1;
  279. allow ...;
  280. }
  281. ```
  282. # `access`阶段对用户名密码做限制
  283. `auth_basic`模块。使用了`RFC2617`协议中的`HTTP Basic Authentication`。本身用明文,但用了`HTTPS`以后加密。
  284. ```
  285. ```
  286. # `access`阶段使用第三方做权限控制
  287. `auth_request`模块。
  288. # `access`阶段的`satisfy`指令
  289. # `precontent`阶段按序访问资源
  290. `try_files`模块。
  291. # `precontent`阶段实时拷贝流量
  292. `mirror`模块。
  293. # `content`阶段`root`和`alias`指令
  294. # `static`模块
  295. # `index`和`autoindex`模块
  296. # 提升多个小文件性能的`concat`模块
  297. # 过滤模块
  298. # `Nginx`变量
  299. # 提升连接效率
  300. `keepalive`