nginx 读书笔记

来源:互联网 发布:千人基因组数据库 编辑:程序博客网 时间:2024/06/08 16:18

正向代理和反向代理的区别

正向代理:翻墙、订外卖、vpn,访问某些不能直接访问的网站,通过代理配置,达到访问的目的,即域名解析出来的是实际目的ip反向代理:构建无差别向外提供相同接口的集群,通过负载均衡,提高服务可用性,即域名解析下出来的是负载均衡的ip

nginx http处理11个阶段

    // 接收到完整的HTTP头部后处理阶段    NGX_HTTP_POST_READ_PHASE,    // 将请求URI与location表达式匹配前,修改URI,即重定向阶段    NGX_HTTP_SERVER_REWRITE_PHASE,    // 只能由ngx_http_core_module模块实现,用于根据请求URI寻找location表达式(仅由Http框架实现)    NGX_HTTP_FIND_CONFIG_PHASE,    // 上一过程结束后修改URI    NGX_HTTP_REWRITE_PHASE,    // 为了防止rewrite造成死循环(一个请求执行10次会被Nginx认定为死循环)(仅由Http框架实现)    NGX_HTTP_POST_REWRITE_PHASE,    // 在“决定请求访问权限”阶段前    NGX_HTTP_PREACCESS_PHASE,    // 决定访问权阶段,判断该请求是否可以访问Nginx服务器    NGX_HTTP_ACCESS_PHASE,    // 当然请求不被允许访问Nginx服务器时,该阶段负责向用户返回错误响应(仅由Http框架实现)    NGX_HTTP_POST_ACCESS_PHASE,    // 用try_files配置项。顺序访问多个静态文件资源阶段(仅由Http框架实现)    NGX_HTTP_TRY_FILES_PHASE,    // 处理HTTP请求内容阶段,这是大部分HTTP模块介入的阶段    NGX_HTTP_CONTENT_PHASE,    // 记录日志阶段    NGX_HTTP_LOG_PHASE

多阶段执行链:

// 一个阶段typedef struct {    ngx_http_phase_handler_t  *handlers; //多个模块处理函数链表    ngx_uint_t                 server_rewrite_index;    ngx_uint_t                 location_rewrite_index;} ngx_http_phase_engine_t;// 一个模块处理函数struct ngx_http_phase_handler_s {    ngx_http_phase_handler_pt  checker; // checker函数指针,一般函数内部调用handler    ngx_http_handler_pt        handler; // 函数指针,模块处理函数,NGX_HTTP_FIND_CONFIG_PHASE,NGX_HTTP_POST_REWRITE_PHASE,NGX_HTTP_POST_ACCESS_PHASE和NGX_HTTP_TRY_FILES_PHASE 不能注册此函数    ngx_uint_t                 next; // 实现处理顺序跳跃,NGX_AGAIN等等};

Lua 基本8个阶段

set 指令来自 ngx_rewrite 模块,运行于 rewrite 阶段;rewrite_by_lua 指令来自 ngx_lua 模块,运行于 rewrite 阶段的末尾;deny 指令来自 ngx_access 模块,运行于 access 阶段;access_by_lua 指令同样来自 ngx_lua 模块,运行于 access 阶段的末尾;echo 指令则来自 ngx_echo 模块,运行在 content 阶段。content_by_lua 指令来自 ngx_lua 模块,运行于 content 阶段;不要将它和其它的内容处理指令在同一个location内使用如proxy_pass。header_filter_by_lua 运行于 content 阶段output-header-filter 一般用来设置cookie和headers。

每个阶段Http模块下ngx_http_handler_pt的返回值

NGX_OK:直接跳至下个阶段的ngx_http_handler_pt处理方法NGX_DECLIEND:跳至本阶段的下一个ngx_http_handler_pt处理方法NGX_AGAIN,NGX_DONE:下次还是在本阶段本ngx_http_handler_pt处理方法NGX_ERROR,其他:调用ngx_http_finalize_request结束请求

Http框架初始化流程

1. 顺序设置http模块的ctx_index2. 调用所有http模块的create_main_conf,create_srv_conf,create_loc_conf,解析main的conf,调用init_main_conf,合并main配置3. 调用所有http模块的postconfiguration函数4. 构造静态的平衡二叉树,针对location快速检索5. 初始化可动态添加http模块的7个阶段的动态数组6. 调用所有http模块的postconfiguration函数,使之可以接入Http阶段7. 构造phase_engine_handlers数组,11个成员,每个成员都是一个数组7. server 快速匹配散列表8. 构造监听端口和server的关联关系没设置新连接事件的回调方法

Http框架执行流程

大体执行流程:

1. 与下游客户端建立或复用tcp连接2. 接收解析Http请求行、请求头、请求和包体3. 定位到指定server(散列表)和location(类似于字典树的平衡二叉树)4. 构建subrequest去第三方服务端请求,响应Http请求5. 使用upstream机制构造上游服务端请求和转发响应6. 结束或者keepalive请求

与下游客户端建立或复用tcp连接:

1. 新建连接,在定时器中添加指定缓冲区数据到达回调方法2. 若超时且未发生指定读事件的回调,主动close请求;若有数据到达缓冲区,调用ngx_http_init_request方法,初始化ngx_http_request_t,定位到指定server,以及分配内存缓冲区,ps:只有数据到达才会分配内存3. 向epoll中设置相对应的读事件和回调(ngx_http_process_request_line)

接收解析Http请求行、请求头、请求和包体:

1. epoll回调执行ngx_http_process_request_line,由于请求行不定长,可能导致多次调用该函数(NGX_AGAIN),拷贝tcp流从内核态到用户态,解析校验http请求行,解析完成后,重新设置epoll和定时器的回调(ngx_http_process_request_headers),等待回调执行2. epoll回调执行,ngx_http_process_request_headers,由于请求头不定长,可能导致多次调用该函数(NGX_AGAIN),同上,最后设置回调(ngx_http_process_request),等待回调执行3. epoll回调执行ngx_http_process_request,开始基于事件驱动的异步处理http请求,解析定位location4. 若是请求的body的content-length不为0,Http框架也会对包体进行处理,直接弃包或者写入临时文件,该过程应当在2与3之间读取Http头部进行的初始化操作:1. 设置回调函数和定时器2. 分配缓冲区保存头部内容3. 分配请求内存池4. 分配响应头链表,初始化长度为205. 创建ctx数组6. 设置main字段,表示这是原始请求7. 设置count,用于引用计数,防止非法销毁8. 保存start_sec和start_msec9. 设置请求其他字段,例如重定向次数限制,子请求个数等等

定位到指定server(散列表)和location(类似于字典树的平衡二叉树):

参考上面描述

构建subrequest去第三方服务端请求,响应Http请求

1. 构造子请求,并且建立与原始请求的关系(post_requests单向链表、parent、main),进行引用计数,防止原始请求被非法销毁2. Http框架执行某请求,其子请求一定会被执行3. 响应Http请求,向定时器和epoll添加写事件回调,当事件可写,会经过过滤链将响应行和头写到客户端,这个阶段可能多次发生,直到响应完全写到客户端(out保存未写到客户端的数据)

使用upstream机制构造上游服务端请求和转发响应(基于事件驱动的upstream机制支持所有tcp连接的上游服务器):

1. 建立tcp套接字,同时防止三次握手阻塞,将套接字的读写事件加入epoll,一旦发生回调,说明tcp连接已经建立2. 添加读定时器,开始将缓冲区内下游客户端的数据写到上游服务器(上下游网速差距不大+上下游网速差异大),可能由于数据过大,而发生多次定时器和读写事件回调的设置3. 读事件回调执行,将上游服务器的响应写入到缓冲区,然后写到下游客户端(不转发响应+上下游网速差距不大+上下游网速差异大)upstream转发请求:上下游速度差异不大,公用缓冲区;上下游速度差异大,申请大缓冲区内存,缓存上游数据upstream转发响应:不转发响应;上下游速度差异不大,公用缓冲区;上下游速度差异大,申请大缓冲区内存,缓存上游数据大体处理场景:1. 接收头部的时候也可能接收到包体2. 没有达到bufs.num的数量,继续分配缓存充当缓冲区3. 如果下游客户端恰好可读,应当优先发送响应清空缓存4. 缓存区写满,写临时文件

结束或者keepalive请求

引用计数,防止非法销毁请求
原创粉丝点击