《深入剖析ngx》——upstream模块
0. 什么是upstream
如,ngx通过proxy模块,将请求转发给上游http服务器,并最终返回给客户端。ngx通过cgi,将请求转发给php服务器,并返回给客户端。
1. 配置解析
简单配置如下
http {
upstream {
server localhost:8080;
server localhost:8081;
}
server {
listen 80;
location {
proxy_buffering off; // 关闭缓存,确保转发客户端所有请求
proxy_pass http://load_balance;
}
}
}
涉及指令 upstream, proxy_buffering, proxy_pass
1.1 upstream 指令
5745 static char *
5746 ngx_http_upstream(ngx_conf_t *cf, ngx_command_t *cmd, void *dummy)
5747 {
5756 ngx_http_upstream_srv_conf_t *uscf;
// 创建upstream 配置块
5765 uscf = ngx_http_upstream_add(cf, &u, NGX_HTTP_UPSTREAM_CREATE
5766 |NGX_HTTP_UPSTREAM_WEIGHT
5767 |NGX_HTTP_UPSTREAM_MAX_CONNS
5768 |NGX_HTTP_UPSTREAM_MAX_FAILS
5769 |NGX_HTTP_UPSTREAM_FAIL_TIMEOUT
5770 |NGX_HTTP_UPSTREAM_DOWN
5771 |NGX_HTTP_UPSTREAM_BACKUP);
// 切换上下文为upstream
5839 pcf = *cf;
5840 cf->ctx = ctx;
5841 cf->cmd_type = NGX_HTTP_UPS_CONF;
5842
5843 rv = ngx_conf_parse(cf, NULL);
5844
5845 *cf = pcf;
5857 return rv;
5858 }
1.2 proxy_pass 指令
4103 static char *
4104 ngx_http_proxy_pass(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
4105 {
4113 ngx_http_core_loc_conf_t *clcf;
// 设置location handler
4120 clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module);
4122 clcf->handler = ngx_http_proxy_handler;
由于 proxy_pass 设置对应 location 的 clcf->handler ,会导致 r->content_handler 被设置为 ngx_http_proxy_pass。如下
451 static ngx_int_t
452 ngx_http_init_phase_handlers(ngx_conf_t *cf, ngx_http_core_main_conf_t *cmcf)
453 {
497 case NGX_HTTP_FIND_CONFIG_PHASE:
498 find_config_index = n;
499
500 ph->checker = ngx_http_core_find_config_phase;
501 n++;
502 ph++;
503
504 continue;
请求处理的 NGX_HTTP_FIND_CONFIG_PHASE 阶段时调用 ngx_http_core_find_config_phase
ngx_http_core_find_config_phase -> ngx_http_core_find_location : 设置 r->loc_conf 为 设置了 proxy_pass 指令的 loc_conf
ngx_http_core_find_config_phase -> ngx_http_update_location_config:由于 clcf->handler被设置,所以会设置 r->content_handler 为 ngx_http_init_phase_handlers
1302 void
1303 ngx_http_update_location_config(ngx_http_request_t *r)
1304 {
1305 ngx_http_core_loc_conf_t *clcf;
1379 if (clcf->handler) {
1380 r->content_handler = clcf->handler;
1381 }
1382 }
2. 请求处理
如下 在NGX_HTTP_CONTENT_PHASE阶段时,调用 ngx_http_core_content_phase
451 static ngx_int_t
452 ngx_http_init_phase_handlers(ngx_conf_t *cf, ngx_http_core_main_conf_t *cmcf)
453 {
538 case NGX_HTTP_CONTENT_PHASE:
539 checker = ngx_http_core_content_phase;
540 break;
ngx_http_core_content_phase : 由于 r->content_handler 为 ngx_http_proxy_handler,所以调用 ngx_http_proxy_handler
1249 ngx_int_t
1250 ngx_http_core_content_phase(ngx_http_request_t *r,
1251 ngx_http_phase_handler_t *ph)
1252 {
1257 if (r->content_handler) {
1258 r->write_event_handler = ngx_http_request_empty_handler;
1259 ngx_http_finalize_request(r, r->content_handler(r));
1260 return NGX_OK;
1261 }
ngx_http_proxy_handler
相关回调
整体流程
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律