nginx:代理服务器(涉及upstream)的例子

本文详细介绍了Nginx中upstream模块的作用,它作为代理服务器转发客户端请求给第三方服务器。通过一个实际的例子,展示了如何创建并初始化upstream模块,包括设置三个关键的回调方法。此外,还讨论了配置文件的解析过程以及在调试过程中遇到的问题,如无法获取Nginx的core文件和GDB调试时的疑问。
摘要由CSDN通过智能技术生成

缘由

今天阅读 深入理解nginx 的第五章,前半部分讲解了upstream的问题,并且指导完成了一个例子。


upstream

先来回答upstream拿来做什么:客户端请求nginx,nginx将请求转发给第三方服务器(也称上游服务器),第三方服务器返回响应,nginx将响应转发给客户端。这时,nginx作为了一个代理服务器。一般,我们只是把第三方服务器的内容原封不动的返回给客户端。这样做的目的主要是减轻上游服务器端的压力。


例子

背景描述

我们要利用nginx的upstream完成这样一个功能,当然我们访问“http://localhost/test?word”的时候,nginx会把word这个单词(可以是任意单词),传递归google,那么google就用这个word完成搜索,然后将搜索后的页面返回给nginx,nginx再返回给我们。这个例子基本就说清楚了为什么在国内用反向代码就可以访问。

思路总览

那么下面,我按照我的思路来为大家理一下,当然我的思路肯定是比不上书上清晰,代码写的也没有书上工整。首先看我们使用到了那些结构体和方法。下面一幅截图看清楚了,我使用的所有的结构体和方法。


作为一个单独的模块

由于我们写的是一个独立的模块,所以肯定要按照nginx的要求完成ngx_module_t 这个结构体:
这是对于所有模块都需要有的ngx_module_t,书中87页有描述:
ngx_module_t  ngx_http_mytest_module =
{
    NGX_MODULE_V1,
    &ngx_http_mytest_module_ctx,           /* module context */
    ngx_http_mytest_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_mytest_commands如下,:
static ngx_command_t  ngx_http_mytest_commands[] =
{


    {
        ngx_string("mytest"),
        NGX_HTTP_MAIN_CONF | NGX_HTTP_SRV_CONF | NGX_HTTP_LOC_CONF | NGX_HTTP_LMT_CONF | NGX_CONF_NOARGS,
        ngx_http_mytest,
        NGX_HTTP_LOC_CONF_OFFSET,
        0,
        NULL
    },


    ngx_null_command
};


其中表明当我们遇见了mytest配置项目的时候,将会调用ngx_http_mytest,如下:
static char *
ngx_http_mytest(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
    ngx_http_core_loc_conf_t  *clcf;


    //首先找到mytest配置项所属的配置块,clcf貌似是location块内的数据
//结构,其实不然,它可以是main、srv或者loc级别配置项,也就是说在每个
//http{}和server{}内也都有一个ngx_http_core_loc_conf_t结构体
    clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module);


    //http框架在处理用户请求进行到NGX_HTTP_CONTENT_PHASE阶段时,如果
//请求的主机域名、URI与mytest配置项所在的配置块相匹配,就将调用我们
//实现的ngx_http_mytest_handler方法处理这个请求
    clcf->handler = ngx_http_mytest_handler;


    return NGX_CONF_OK;
}

其中又调用了 ngx_http_mytest_handler:
static ngx_int_t ngx_http_mytest_handler(ngx_http_request_t *r){
	ngx_http_mytest_ctx_t *myctx = ngx_http_get_module_ctx(r,ngx_http_mytest_module);
	if(myctx == NULL){
		myctx = ngx_palloc(r->pool,sizeof(ngx_http_mytest_ctx_t));


		if(myctx == NULL){
			return NGX_ERROR;
		}


		ngx_http_set_ctx(r,myctx,ngx_http_mytest_module);


	}
	if(ngx_http_upstream_create(r) != NGX_OK){
		ngx_log_error(NGX_LOG_DEBUG,r->connection->log,0,"ngx_http_upstream_create failed");
		return NGX_ERROR;
	}
	//得到配置结构体
	ngx_http_mytest_conf_t *mycf = (ngx_http_mytest_conf_t *)ngx_http_get_module_loc_conf(r,ngx_http_mytest_module);


	ngx_http_upstream_t *u = r->upstream;


	u->conf = &mycf->upstream;
	u->buffering = mycf->upstream.buffering;
	//resolved 用于存放上游服务器的地址
	u->resolved = (ngx_http_upstream_resolved_t *) ngx_palloc(r->pool,sizeof(ngx_http_upstream_resolved_t)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值