Nginx中的ctx
(context)是一种在不同处理阶段之间共享数据的机制。下面我将详细介绍如何使用ctx实现数据共享。
Nginx提供了几种上下文类型用于数据共享:
1. 请求级ctx (ngx_http_request_t
中的ctx
数组) - 只在单个请求生命周期内有效
2. 主配置ctx - 在配置重载时会被重置
3. 位置配置ctx - 特定location块内的数据共享
typedef struct {
ngx_str_t shared_data;
int shared_value;
} my_module_ctx_t;
static my_module_ctx_t *get_my_module_ctx(ngx_http_request_t *r) {
my_module_ctx_t *ctx = ngx_http_get_module_ctx(r, my_module);
if (ctx == NULL) {
ctx = ngx_pcalloc(r->pool, sizeof(my_module_ctx_t));
if (ctx == NULL) {
return NULL;
}
ngx_http_set_ctx(r, ctx, my_module);
}
return ctx;
}
// 在某个处理阶段设置数据
static ngx_int_t my_handler(ngx_http_request_t *r) {
my_module_ctx_t *ctx = get_my_module_ctx(r);
if (ctx == NULL) {
return NGX_ERROR;
}
ctx->shared_value = 42;
ctx->shared_data = ngx_string("Hello from ctx");
return NGX_OK;
}
// 在另一个处理阶段读取数据
static ngx_int_t my_other_handler(ngx_http_request_t *r) {
my_module_ctx_t *ctx = ngx_http_get_module_ctx(r, my_module);
if (ctx == NULL) {
return NGX_ERROR;
}
ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
"Shared value: %d, data: %V",
ctx->shared_value, &ctx->shared_data);
return NGX_OK;
}
typedef struct {
ngx_str_t config_data;
int config_value;
} my_module_main_conf_t;
static ngx_http_module_t my_module_ctx = {
NULL, /* preconfiguration */
NULL, /* postconfiguration */
ngx_http_my_module_create_main_conf, /* create main configuration */
NULL, /* init main configuration */
NULL, /* create server configuration */
NULL, /* merge server configuration */
NULL, /* create location configuration */
NULL /* merge location configuration */
};
static void *ngx_http_my_module_create_main_conf(ngx_conf_t *cf) {
my_module_main_conf_t *conf;
conf = ngx_pcalloc(cf->pool, sizeof(my_module_main_conf_t));
if (conf == NULL) {
return NULL;
}
// 初始化默认值
conf->config_value = 100;
conf->config_data = ngx_string("default");
return conf;
}
static ngx_int_t my_handler(ngx_http_request_t *r) {
my_module_main_conf_t *mcf = ngx_http_get_module_main_conf(r, my_module);
ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
"Config value: %d, data: %V",
mcf->config_value, &mcf->config_data);
return NGX_OK;
}
ngx_module_t
定义和正确的索引假设我们要在Nginx中实现一个简单的请求计数器:
typedef struct {
int request_count;
} my_counter_ctx_t;
static ngx_int_t my_counter_handler(ngx_http_request_t *r) {
my_counter_ctx_t *ctx = ngx_http_get_module_ctx(r, my_module);
if (ctx == NULL) {
ctx = ngx_pcalloc(r->pool, sizeof(my_counter_ctx_t));
if (ctx == NULL) {
return NGX_ERROR;
}
ngx_http_set_ctx(r, ctx, my_module);
ctx->request_count = 0;
}
ctx->request_count++;
ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
"Request count: %d", ctx->request_count);
return NGX_OK;
}
通过这种方式,你可以在Nginx的不同处理阶段高效地共享数据。