当前位置: 首页> 娱乐> 影视 > yy8848青苹果影私人视院_电影网站网页设计_鸿星尔克网络营销_企业网站开发公司

yy8848青苹果影私人视院_电影网站网页设计_鸿星尔克网络营销_企业网站开发公司

时间:2025/8/31 21:49:14来源:https://blog.csdn.net/Morso/article/details/144312999 浏览次数:0次
yy8848青苹果影私人视院_电影网站网页设计_鸿星尔克网络营销_企业网站开发公司

文章目录

  • 前言
  • 一、Nginx组件开发
    • 1.1 组件如何使用?
  • 二、过滤器模块实现
    • 2.1 相关Nginx源码解析
      • 2.1.1 ngx_command_t
      • 2.1.2 ngx_http_module_t
      • 2.1.3 ngx_module_s
    • 2.2 过滤器模块设计
      • 2.2.1 完成模块编写中问题
  • 三、handler模块实现
    • 3.1 handler流程实现
    • 3.2 多进程的slab
  • 总结


前言

本文首先介绍了的Nginx的组件以及使用,并实现了一个filter模块。


一、Nginx组件开发

上一节中我们知道了Nginx的基本概念,在本节中我们将利用Nginx进行相对应的组件开发。

  • 首先明确Nginx可以进行哪些组件开发

三个模块开发

  1. upstream(两条黑线箭头)
    1. 负载均衡模块
  2. filter(红线,可以用来加一些广告等)
    1. 对响应内容进行增加等
  3. handle(黑加红,黑加红)
    1. 处理响应内容,例如对发起请求的ip地址进行计数

image.png

1.1 组件如何使用?

我们完成了组件,怎样将这个组件添加到Nginx中?

  1. config文件+原文件(ngx_http_prefix_filter_module.c)编写
    1. 注意windows中编写的config不能直接用于Linux中,会有字符编码问题
# config文件
ngx_addon_name=ngx_http_prefix_filter_module
HTTP_FILTER_MODULES="$HTTP_FILTER_MODULES ngx_http_prefix_filter_module"
NGX_ADDON_SRCS="$NGX_ADDON_SRCS $ngx_addon_dir/ngx_http_prefix_filter_module.c"
  1. 重新编译Nginx,注意最后一句,会将我们的模块文件信息放入Nginx编译环境中。
./configure --prefix=/usr/local/nginx --with-http_realip_module --with-http_addition_module --with-http_ssl_module --with-http_gzip_static_module --with-http_secure_link_module --with-http_stub_status_module --with-stream --with-pcre=/root/install_package/nginx/pcre-8.45 --with-zlib=/root/install_package/nginx/zlib-1.2.13 --with-openssl=/root/install_package/nginx/openssl-1.1.1s --add-module=/root/install_package/nginx/ngx_code_test/ngx_http_prefix_filter_module/
  1. make && make install
  2. 将实现的功能在nginx.conf中进行描述

二、过滤器模块实现

2.1 相关Nginx源码解析

2.1.1 ngx_command_t

struct ngx_command_s {ngx_str_t             name; // 配置指令的名称ngx_uint_t            type; // 配置指令的属性char               *(*set)(ngx_conf_t *cf, ngx_command_t *cmd, void *conf); // 处理读取的数据ngx_uint_t            conf; // 使用那一块内存池ngx_uint_t            offset; // 配置项在相应结构体的准确存放位置void                 *post; // 一般为NULL
};

2.1.2 ngx_http_module_t

typedef struct {// 在解析配置文件中http{}配置块前调用ngx_int_t   (*preconfiguration)(ngx_conf_t *cf);// 在解析配置文件中http{}配置块后调用ngx_int_t   (*postconfiguration)(ngx_conf_t *cf);// 创建http模块的main configvoid       *(*create_main_conf)(ngx_conf_t *cf);// 初始化http模块的main configchar       *(*init_main_conf)(ngx_conf_t *cf, void *conf);// 创建http模块的server configvoid       *(*create_srv_conf)(ngx_conf_t *cf);// 合并http模块的server config,用于实现server config到main config的指令的继承、覆盖char       *(*merge_srv_conf)(ngx_conf_t *cf, void *prev, void *conf);// 创建http模块的location configvoid       *(*create_loc_conf)(ngx_conf_t *cf);// 合并http模块的location config,用于实现location config到server config的指令的继承、覆盖char       *(*merge_loc_conf)(ngx_conf_t *cf, void *prev, void *conf);
} ngx_http_module_t;

2.1.3 ngx_module_s

struct ngx_module_s {ngx_uint_t            ctx_index; // 是该模块在同一类模块中的序号ngx_uint_t            index; // 该模块在所有Nginx模块中的序号, 即在ngx_modules数组里的唯一索引char                 *name; // 模块的名字,用NGX_MODULE_V1初始化为NULLngx_uint_t            spare0; //保留字段,用NGX_MODULE_V1初始化为0ngx_uint_t            spare1;ngx_uint_t            version; // 版本号const char           *signature;void                 *ctx; // ctx为ngx_module_s与各个模块的纽带,也可以说是具体模块的公共接口。ngx_command_t        *commands; // 模块支持的指令,数组形式,最后用空对象表示结束ngx_uint_t            type;// 以下7个函数指针,俗称钩子函数,会在程序启动、结束等不同阶段被调用ngx_int_t           (*init_master)(ngx_log_t *log);ngx_int_t           (*init_module)(ngx_cycle_t *cycle);ngx_int_t           (*init_process)(ngx_cycle_t *cycle);ngx_int_t           (*init_thread)(ngx_cycle_t *cycle);void                (*exit_thread)(ngx_cycle_t *cycle);void                (*exit_process)(ngx_cycle_t *cycle);void                (*exit_master)(ngx_cycle_t *cycle);// 下面八个预留字段,用NGX_MODULE_V1_PADDING宏全部初始化为0uintptr_t             spare_hook0;uintptr_t             spare_hook1;uintptr_t             spare_hook2;uintptr_t             spare_hook3;uintptr_t             spare_hook4;uintptr_t             spare_hook5;uintptr_t             spare_hook6;uintptr_t             spare_hook7;
};

2.2 过滤器模块设计

我们的目的是在返回的网页中添加额外的内容。
所以第一步是设计对应的指令add_prefix

typedef struct {ngx_flag_t enable;
} ngx_http_prefix_filter_conf_t;static ngx_command_t ngx_http_prefix_filter_commands[] = {{ngx_string("add_prefix"),NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LMT_CONF|NGX_CONF_FLAG,ngx_conf_set_flag_slot,NGX_HTTP_LOC_CONF_OFFSET,offsetof(ngx_http_prefix_filter_conf_t, enable),NULL},ngx_null_command
};

第二步:在对应的执行位置填充相关的函数

进入location调用create,遇到add_prefix调用ngx_conf_set_flag_slot,当location返回调用merge

static ngx_http_module_t ngx_http_prefix_filter_module_ctx = {NULL, // confngx_http_prefix_filter_init, // 将写的该filter模块采用头插法加入到链表中,在这个函数中我们可以将想要加入的内容写到head和bodyNULL, // mainNULL,NULL, // serverNULL,ngx_http_prefix_filter_create_conf, // locngx_http_prefix_filter_merge_conf
};

第三步:完成模块以及各种信息的拼接

ngx_module_t ngx_http_prefix_filter_module = {NGX_MODULE_V1,&ngx_http_prefix_filter_module_ctx,ngx_http_prefix_filter_commands, // 循环遍历读取指令NGX_HTTP_MODULE,NULL,NULL,NULL,NULL,NULL,NULL,NULL,NGX_MODULE_V1_PADDING
}; 

第四步:完成具体的函数。

static void *ngx_http_prefix_filter_create_conf(ngx_conf_t *cf) {ngx_http_prefix_filter_conf_t *conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_prefix_filter_conf_t));if (conf == NULL) {return NULL;}conf->enable = NGX_CONF_UNSET;return conf;
}static char *ngx_http_prefix_filter_merge_conf(ngx_conf_t *cf, void *parent, void *child) {ngx_http_prefix_filter_conf_t *prev = (ngx_http_prefix_filter_conf_t*)parent;ngx_http_prefix_filter_conf_t *conf = (ngx_http_prefix_filter_conf_t*)child;ngx_conf_merge_value(conf->enable, prev->enable, 0);return NGX_CONF_OK;
}static ngx_int_t ngx_http_prefix_filter_init(ngx_conf_t *cf) {ngx_http_next_header_filter = ngx_http_top_header_filter;ngx_http_top_header_filter = ngx_http_prefix_filter_header_filter;ngx_http_next_body_filter = ngx_http_top_body_filter;ngx_http_top_body_filter = ngx_http_prefix_filter_body_filter;return NGX_OK;
}static ngx_int_t ngx_http_prefix_filter_header_filter(ngx_http_request_t *r) {ngx_http_prefix_filter_ctx_t *ctx;ngx_http_prefix_filter_conf_t *conf;if (r->headers_out.status != NGX_HTTP_OK) {return ngx_http_next_header_filter(r);}ctx = ngx_http_get_module_ctx(r, ngx_http_prefix_filter_module);if (ctx) {return ngx_http_next_header_filter(r);}conf = ngx_http_get_module_loc_conf(r, ngx_http_prefix_filter_module);if (conf == NULL) {return ngx_http_next_header_filter(r);}if (conf->enable == 0) {return ngx_http_next_header_filter(r);}ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_prefix_filter_ctx_t));if (ctx == NULL) {return NGX_ERROR;}ctx->add_prefix = 0;ngx_http_set_ctx(r, ctx, ngx_http_prefix_filter_module);if (r->headers_out.content_type.len >= sizeof("text/html") - 1&& ngx_strncasecmp(r->headers_out.content_type.data, (u_char*)"text/html", sizeof("text/html")-1) == 0) {ctx->add_prefix = 1;if (r->headers_out.content_length_n > 0) {r->headers_out.content_length_n += filter_prefix.len;}}return ngx_http_prefix_filter_header_filter(r);
}static ngx_int_t ngx_http_prefix_filter_body_filter(ngx_http_request_t *r, ngx_chain_t *in) {ngx_http_prefix_filter_ctx_t *ctx = ngx_http_get_module_ctx(r, ngx_http_prefix_filter_module);if (ctx == NULL || ctx->add_prefix != 1) {return ngx_http_next_body_filter(r, in);}ctx->add_prefix = 2;ngx_buf_t *b = ngx_create_temp_buf(r->pool, filter_prefix.len);b->start = b->pos = filter_prefix.data;b->last = b->pos + filter_prefix.len;ngx_chain_t *cl = ngx_alloc_chain_link(r->pool);cl->buf = b;cl->next = in;return ngx_http_next_body_filter(r, cl);
}

2.2.1 完成模块编写中问题

image.png

config文件需要在Linux环境下编写,不然会出现^M字符多余。

三、handler模块实现

3.1 handler流程实现

  1. nginx启动流程
  2. nginx中conf文件的功能开启
  3. 当HTTP请求来的时候

3.2 多进程的slab

采用共享内存来实现多进程之间的资源共享。


总结

本文介绍了Nginx组件的使用以及filter模块的开发。Handler模块也是同样的流程,只是利用这一套流程实现了不同的功能

参考链接:
https://github.com/0voice
https://zhuanlan.zhihu.com/p/410743061
https://blog.csdn.net/chosen0ne/article/details/7730292

关键字:yy8848青苹果影私人视院_电影网站网页设计_鸿星尔克网络营销_企业网站开发公司

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: