Nginx源代码分析之反向代理(十三)

ngx_http_core_module.c负责处理nginx里面的所有配置


其中的关键还是这个变量:ngx_http_core_module

一个ngx_module_t类型的结构体,这个结构体在前面已经提到过,他遍布ngx的各个Module,包括底层i/o模型的module均是用这个结构体来传递上下文

这里的定义是这样的


ngx_module_t  ngx_http_core_module = {
    NGX_MODULE_V1,
    &ngx_http_core_module_ctx,             /* module context */
    ngx_http_core_commands,                /* module directives */
    NGX_HTTP_MODULE,                       /* module type */
    NULL,                                  /* init master */
    NULL,                                  /* init module */
    NULL,                                  /* init process */
    NULL,                                  /* init thread */
    NULL,                                  /* exit thread */
    NULL,                                  /* exit process */
    NULL,                                  /* exit master */
    NGX_MODULE_V1_PADDING
};

其中重点是ngx_http_core_commands这个成员,它包含了所有ngx主配置文件涉及的关键字已经处理这个关键字的函数

内容太多,先看看涉及location的一段


    { ngx_string("location"),
      NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_BLOCK|NGX_CONF_TAKE12,
      ngx_http_core_location,
      NGX_HTTP_SRV_CONF_OFFSET,
      0,
      NULL },


大致了解一下这些数据结构,再来看看函数调用栈


前面upstream一节已经介绍,当ngx需要执行反向代理,向后端apache或者tomcat之类发起请求的时候,会调用ngx_http_proxy_handler

ngx_http_proxy_handler是如何被初始化并挂载到处理流程中的?

先看看各个module的初始化

ngx_http_static_handler,ngx_http_proxy_handler,ngx_http_indixe_handler的初始化在各自模块的init函数进行,比如初始化ngx_http_static_handler的是ngx_http_static_init

,这个函数需要在ngx_http.c的 ngx_http_block中初始化。


ngx_modules.c的

ngx_module_t *ngx_modules[] = {
    &ngx_core_module,
    &ngx_errlog_module,
    &ngx_conf_module,
    &ngx_events_module,
    &ngx_event_core_module,
    &ngx_epoll_module,
    &ngx_regex_module,
    &ngx_http_module,
    &ngx_http_core_module,
    &ngx_http_log_module,
    &ngx_http_upstream_module,
    &ngx_http_static_module,
    &ngx_http_autoindex_module,
    &ngx_http_index_module,
    &ngx_http_auth_basic_module,
    &ngx_http_access_module,
    &ngx_http_limit_conn_module,
    &ngx_http_limit_req_module,
    &ngx_http_geo_module,
    &ngx_http_map_module,
    &ngx_http_split_clients_module,
    &ngx_http_referer_module,
    &ngx_http_rewrite_module,
    &ngx_http_proxy_module,
    &ngx_http_fastcgi_module,
    &ngx_http_uwsgi_module,
    &ngx_http_scgi_module,
    &ngx_http_memcached_module,
    &ngx_http_empty_gif_module,
    &ngx_http_browser_module,
    &ngx_http_upstream_hash_module,
    &ngx_http_upstream_ip_hash_module,
    &ngx_http_upstream_least_conn_module,
    &ngx_http_upstream_keepalive_module,
    &ngx_http_write_filter_module,
    &ngx_http_header_filter_module,
    &ngx_http_chunked_filter_module,
    &ngx_http_range_header_filter_module,
    &ngx_http_gzip_filter_module,
    &ngx_http_postpone_filter_module,
    &ngx_http_ssi_filter_module,
    &ngx_http_charset_filter_module,
    &ngx_http_userid_filter_module,
    &ngx_http_headers_filter_module,
    &ngx_http_echo_module,
    &ngx_http_copy_filter_module,
    &ngx_http_range_body_filter_module,
    &ngx_http_not_modified_filter_module,
    NULL
};

定义了所有的模块,里面可以看到ngx_http_static_module,

下面的代码正式调用各模块的init

    for (m = 0; ngx_modules[m]; m++) {
        if (ngx_modules[m]->type != NGX_HTTP_MODULE) {
            continue;
        }


        module = ngx_modules[m]->ctx;


        if (module->postconfiguration) {
            if (module->postconfiguration(cf) != NGX_OK) {
                return NGX_CONF_ERROR;
            }
        }
    }


static module的初始化函数代码如下


static ngx_int_t
ngx_http_static_init(ngx_conf_t *cf)
{
    ngx_http_handler_pt        *h;
    ngx_http_core_main_conf_t  *cmcf;


    cmcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_core_module);


    h = ngx_array_push(&cmcf->phases[NGX_HTTP_CONTENT_PHASE].handlers);
    if (h == NULL) {
        return NGX_ERROR;
    }


    *h = ngx_http_static_handler;


    return NGX_OK;
}

可以看到在cmcf->phases[NGX_HTTP_CONTENT_PHASE].handlers中写入了ngx_http_static_handler的函数指针,以后在处理请求的NGX_HTTP_CONTENT_PHASE阶段,这个函数会被调用

但回头看看proxy module。他并没有直接注册handler。而是在初始化配置文件过程中,ngx_http_proxy_pass函数会处理proxy_pass关键字,这时会在ngx_http_core_loc_conf_s结构中填写ngx_http_proxy_handler函数指针。


调用过程则是这样的:

在HTTP处理流程的NGX_HTTP_FIND_CONFIG_PHASE阶段。ngx_http_core_find_config_phase函数会查找ngx_http_request_t对应的location,然后调用ngx_http_update_location_config

这里,会把刚才注册的ngx_http_proxy_handler传递给ngx_http_request_t下面的content_handler


继续流程,会执行到NGX_HTTP_CONTENT_PHASE这个阶段,对应的处理函数是ngx_http_core_content_phase


这里首先就会判断r是否存在content_handler指针,如果是,则会直接调用ngx_http_finalize_request(r, r->content_handler(r));

首先执行ngx_http_proxy_handler,然后执行ngx_http_finalize_request本身结束当前的流程。


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 要使用Nginx作为反向代理服务器,首先需要下载Nginx的安装包。以下是下载Nginx的步骤: 1. 打开Nginx的官方网站(https://nginx.org/)。 2. 在网站的首页,点击"Download"按钮。 3. 在下载页面中,你可以选择下载最新稳定版或者其他版本的Nginx。点击对应的版本号下载。 4. 下载完成后,可以将下载的文件(通常是一个.tar.gz或.zip文件)保存到任意位置。 接下来,你需要安装Nginx。以下是安装Nginx的步骤: 1. 解压下载的文件。如果是.tar.gz文件,可以使用以下命令解压: ```bash tar -zxvf nginx-1.20.1.tar.gz ``` 这将会在当前目录下创建一个名为nginx-1.20.1的文件夹。 2. 进入解压后的文件夹: ```bash cd nginx-1.20.1 ``` 3. 在文件夹中运行配置命令: ```bash ./configure ``` 这将会根据系统环境生成编译配置。如果需要自定义配置,可以通过添加参数来进行。 4. 编译Nginx: ```bash make ``` 5. 编译完成后,安装Nginx: ```bash make install ``` Nginx将会被安装到默认的目录(通常是/usr/local/nginx)。 安装完成后,你可以在Nginx的安装目录中找到Nginx的配置文件(通常是nginx.conf)。你可以根据需要编辑该配置文件,添加反向代理的相关配置。 希望以上回答对你有帮助! ### 回答2: 要从Nginx官方网站下载反向代理的代码非常简单。首先,打开Nginx官方网站(https://nginx.org/),找到下载页面。在下载页面,可以找到不同版本的Nginx。我们可以根据自己的需求选择最新版本或者稳定版本的Nginx。 一旦确定了版本,点击相应的链接进入下载页面。在下载页面上,可以找到针对不同操作系统的安装包或源代码。对于大多数用户来说,选择预编译的二进制安装包会更方便。根据自己使用的操作系统选择并下载。如果你对编译和安装有经验,也可以选择源代码进行下载。 下载完成后,解压下载的压缩包。如果你下载的是二进制安装包,解压后会得到一个包含Nginx可执行文件的文件夹。如果你下载的是源代码,解压后会得到一个包含编译和安装所需文件的文件夹。 接下来,根据需要进行配置。打开文件夹中的配置文件,可以根据自己的需求修改反向代理相关的配置选项。例如,你可以指定要代理的服务器地址和端口等。 完成配置后,执行Nginx可执行文件,启动Nginx服务。启动后,Nginx将会开始监听指定端口,并将请求转发到配置的代理服务器。 以上就是通过Nginx官方网站下载反向代理代码及其简单使用的过程。希望对你有所帮助! ### 回答3: 要使用nginx作为反向代理,首先需要在服务器上安装nginx软件。安装完成后,可以通过以下步骤进行配置: 1. 打开nginx配置文件,一般位于`/etc/nginx/nginx.conf`或`/etc/nginx/conf.d/default.conf`。 2. 在`http`块内添加以下代码: ``` server { listen 80; server_name your_domain.com; location / { proxy_pass http://backend_server; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } } ``` 这段代码定义了反向代理的参数,将请求转发到`backend_server`上。 3. 在上述代码中,将`your_domain.com`替换为你的域名,而`backend_server`替换为真实的后端服务器地址。可以使用IP地址或域名作为后端服务器地址。 4. 保存并关闭配置文件。 5. 检查nginx配置是否正确,可以运行`nginx -t`命令进行验证。 6. 如果验证通过,则重新加载nginx配置,可以运行`nginx -s reload`命令。 以上步骤完成后,nginx就可以通过反向代理将请求转发到指定的后端服务器上了。请确保后端服务器能够正常访问,并且端口号与配置文件中相匹配。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值