设为首页 收藏本站
查看: 745|回复: 0

[经验分享] nginx脚本引擎与设计设计(三)

[复制链接]

尚未签到

发表于 2016-12-27 09:17:33 | 显示全部楼层 |阅读模式
  

这一部分我们将探讨一些较细节的东西,加上前面(一),(二)两篇文章对典型情景的分析,我相信应该会对大家理解nginx的脚本解析机制有很大的帮助的。
  这里我们关注ngx_http_core_main_conf_t(下面简写为cmcf)结构中的这两个成员,cmcf->variables_keys和cmcf->variables,其中variables_keys是个hash数组,变量hash值相同的放到一个数组中,而且是唯一的,重复时会报错。重要的是这个hash数组,即cmcf->variables_keys,保存了整个系统中所有预定义的,自定义,几乎所有的变量(一些特定前缀的变量除外,如“http_”等,在函数ngx_http_variables_init_vars中都列出来了)。
  我们分条目来看:
  1. 系统中所有可能用到变量都会放到cmcf->variables_keys中。
  2.配置中出现的变量(在处理请求时会用到的),会放到cmcf->variables中。总体上来看,除去一些有特定前缀的变量(这类变量后面会讲),cmcf->variables可以看做是ngx_http_variables_init_vars的子集。从这里的设计可以看出来,系统定义的变量在请求处理时,并不会全部用到,我们只需根据配置,拿到有用的就可以了,所以cmcf->variables_keys使用了temp_pool(实际的元素则使用cf->pool),当variables收集变量完成之后,variables_keys结构也就没什么用处了。
  3. cmcf->variables是一个数组,它的元素类型为ngx_http_variable_t。

struct ngx_http_variable_s {
// 变量名字符串
ngx_str_t                    name;
// 使用变量中的值设置request的某个成员的值,所谓set
ngx_http_set_variable_pt   set_handler;
// 根据request中成员(如uri,args等)的值来设置,r->variables中对应变量的内容。
ngx_http_get_variable_pt   get_handler;
// 需要具体处理的具体内容,因为这个结构是通用的,那么具体处理的信息就放到// data成员中
uintptr_t                    data;
// 一些标识信息,区别不同处理,后面会详细讲
ngx_uint_t                   flags;
// 该变量在cmcf->variables数组中的下标
ngx_uint_t                   index;
};

  4. 在init_request阶段,我们看到有这样的处理:
  r->variables =ngx_pcalloc(r->pool, cmcf->variables.nelts * sizeof(ngx_http_variable_value_t));
  这里的设计思想是这样的,cmcf->variables是每个变量的处理信息的封装,而r-> variables里面则是处理该变量得到的内容(即value),所以cmcf->variables跟r->variables是一一对应的,成员之间就是var对value的关系,这不过这里的var和value是封装了很多信息的结构,不是单纯的值或字符串。这里我们看下r->variables的成员。

typedef struct {
unsigned    len:28;
unsigned    valid:1;          // 表示该变量在数组中并且有效,可以使用
// 表示使用该变量时,需要重新通过get_handler来获取,因为该变量的实际内容// 可能已经改变了。
unsigned    no_cacheable:1;
// 特定位置上的变量不存在(实际上是没有设置),那么它就是“not found”!
unsigned    not_found:1;
unsigned    escape:1; // 这里不管它,跟我们的情景没有多大关系
u_char     *data;
} ngx_variable_value_t;

  我们看到这个结构中处理包含代表直接变量值的指针和大小(即data和len)外,剩下的都是一些标记位。
  下面我们看几个宏:
  #define NGX_HTTP_VAR_CHANGEABLE 1
  #define NGX_HTTP_VAR_NOCACHEABLE 2
  #define NGX_HTTP_VAR_INDEXED 4
  #define NGX_HTTP_VAR_NOHASH 8
  1. NGX_HTTP_VAR_CHANGEABLE
  使用这个宏的时候意味着,该变量可以重复配置,一般后配置的会覆盖前面的配置。如:
  set $file $1
  set $file $2
  那么结果就是file的最终值就是$2所代表的。
  2. NGX_HTTP_VAR_NOCACHEABLE
  这个宏所影响的正是ngx_variable_value_t结构中的no_cacheable,前面注释里面提到过,凡是有该标记的变量,都要通过get_handler来获取变量的值。如下面函数:

ngx_http_get_flushed_variable(ngx_http_request_t *r, ngx_uint_tindex)
{
ngx_http_variable_value_t  *v;
v = &r->variables[index];
// 找到变量,发现是有效的,但是由于属于NGX_HTTP_VAR_NOCACHEABLE,所以// 需要在cmcf->variables找到它的处理结构来重新获取新值。
if (v->valid) {  // 变量有效,具备可以使用的潜质
if (!v->no_cacheable) { //可以直接用,就返回了
return v;
}
// 这是一个NGX_HTTP_VAR_NOCACHEABLE类型的变量,那么…
v->valid = 0;
v->not_found = 0;
}
// 重新获取,这个函数就不看了,大家可以自己分析
returnngx_http_get_indexed_variable(r, index);
}

  这种变量往往是跟特定的请求紧密相关的,如host,uri,args之类的,处理时每次重新获取新值时必要的。
  3. NGX_HTTP_VAR_INDEXED和NGX_HTTP_VAR_NOHASH
  这两个宏主要是在SSI相关处理中用到,而ssi的处理需要用到cmcf->variables_hash,这是hash表,可以高效的找到变量。NGX_HTTP_VAR_NOHASH类型的变量压根就不会被放到这个hash表中,而从hash表中找到的变量,是ngx_http_variable_t结构,如果我们从它flags发现NGX_HTTP_VAR_INDEXED标记,那么意味着我们可以直接到r->variables中去找,至于找到后可用与否,那要另作判断了!

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.iyunv.com/thread-320000-1-1.html 上篇帖子: 惊群”,看看nginx是怎么解决它的(转) 下篇帖子: Django以fastcgi模式下的Nginx配置文件
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表