[nginx] Upstream: allow multiple upstreams to use the same share...
Ruslan Ermilov
ru at nginx.com
Wed Apr 22 15:49:38 UTC 2015
details: http://hg.nginx.org/nginx/rev/caa103acf180
branches:
changeset: 6123:caa103acf180
user: Ruslan Ermilov <ru at nginx.com>
date: Wed Apr 22 18:37:34 2015 +0300
description:
Upstream: allow multiple upstreams to use the same shared zone.
diffstat:
src/http/modules/ngx_http_upstream_zone_module.c | 98 +++++++++++++----------
src/stream/ngx_stream_upstream_zone_module.c | 98 +++++++++++++----------
2 files changed, 112 insertions(+), 84 deletions(-)
diffs (truncated from 324 to 300 lines):
diff -r 85f00678e54a -r caa103acf180 src/http/modules/ngx_http_upstream_zone_module.c
--- a/src/http/modules/ngx_http_upstream_zone_module.c Tue Apr 21 21:04:36 2015 +0200
+++ b/src/http/modules/ngx_http_upstream_zone_module.c Wed Apr 22 18:37:34 2015 +0300
@@ -14,12 +14,14 @@ static char *ngx_http_upstream_zone(ngx_
void *conf);
static ngx_int_t ngx_http_upstream_init_zone(ngx_shm_zone_t *shm_zone,
void *data);
+static ngx_int_t ngx_http_upstream_zone_copy_peers(ngx_slab_pool_t *shpool,
+ ngx_http_upstream_srv_conf_t *uscf);
static ngx_command_t ngx_http_upstream_zone_commands[] = {
{ ngx_string("zone"),
- NGX_HTTP_UPS_CONF|NGX_CONF_TAKE2,
+ NGX_HTTP_UPS_CONF|NGX_CONF_TAKE12,
ngx_http_upstream_zone,
0,
0,
@@ -63,11 +65,13 @@ ngx_module_t ngx_http_upstream_zone_mod
static char *
ngx_http_upstream_zone(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
- ngx_http_upstream_srv_conf_t *uscf;
- ssize_t size;
- ngx_str_t *value;
+ ssize_t size;
+ ngx_str_t *value;
+ ngx_http_upstream_srv_conf_t *uscf;
+ ngx_http_upstream_main_conf_t *umcf;
uscf = ngx_http_conf_get_module_srv_conf(cf, ngx_http_upstream_module);
+ umcf = ngx_http_conf_get_module_main_conf(cf, ngx_http_upstream_module);
value = cf->args->elts;
@@ -77,18 +81,23 @@ ngx_http_upstream_zone(ngx_conf_t *cf, n
return NGX_CONF_ERROR;
}
- size = ngx_parse_size(&value[2]);
+ if (cf->args->nelts == 3) {
+ size = ngx_parse_size(&value[2]);
- if (size == NGX_ERROR) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid zone size \"%V\"", &value[2]);
- return NGX_CONF_ERROR;
- }
+ if (size == NGX_ERROR) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "invalid zone size \"%V\"", &value[2]);
+ return NGX_CONF_ERROR;
+ }
- if (size < (ssize_t) (8 * ngx_pagesize)) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "zone \"%V\" is too small", &value[1]);
- return NGX_CONF_ERROR;
+ if (size < (ssize_t) (8 * ngx_pagesize)) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "zone \"%V\" is too small", &value[1]);
+ return NGX_CONF_ERROR;
+ }
+
+ } else {
+ size = 0;
}
uscf->shm_zone = ngx_shared_memory_add(cf, &value[1], size,
@@ -97,19 +106,8 @@ ngx_http_upstream_zone(ngx_conf_t *cf, n
return NGX_CONF_ERROR;
}
- if (uscf->shm_zone->data) {
- uscf = uscf->shm_zone->data;
-
- ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
- "upstream \"%V\" in %s:%ui "
- "is already bound to zone \"%V\"",
- &uscf->host, uscf->file_name, uscf->line,
- &value[1]);
- return NGX_CONF_ERROR;
- }
-
uscf->shm_zone->init = ngx_http_upstream_init_zone;
- uscf->shm_zone->data = uscf;
+ uscf->shm_zone->data = umcf;
uscf->shm_zone->noreuse = 1;
@@ -120,21 +118,11 @@ ngx_http_upstream_zone(ngx_conf_t *cf, n
static ngx_int_t
ngx_http_upstream_init_zone(ngx_shm_zone_t *shm_zone, void *data)
{
- ngx_http_upstream_srv_conf_t *ouscf = data;
-
size_t len;
+ ngx_uint_t i;
ngx_slab_pool_t *shpool;
- ngx_http_upstream_rr_peer_t *peer, **peerp;
- ngx_http_upstream_rr_peers_t *peers, *backup;
- ngx_http_upstream_srv_conf_t *uscf;
-
- uscf = shm_zone->data;
-
- if (ouscf) {
- ngx_log_error(NGX_LOG_EMERG, shm_zone->shm.log, 0,
- "zone \"%V\" cannot be reused", &shm_zone->shm.name);
- return NGX_ERROR;
- }
+ ngx_http_upstream_srv_conf_t *uscf, **uscfp;
+ ngx_http_upstream_main_conf_t *umcf;
shpool = (ngx_slab_pool_t *) shm_zone->shm.addr;
@@ -142,9 +130,6 @@ ngx_http_upstream_init_zone(ngx_shm_zone
return NGX_ERROR;
}
-
- /* copy peers to shared memory */
-
len = sizeof(" in upstream zone \"\"") + shm_zone->shm.name.len;
shpool->log_ctx = ngx_slab_alloc(shpool, len);
@@ -155,6 +140,35 @@ ngx_http_upstream_init_zone(ngx_shm_zone
ngx_sprintf(shpool->log_ctx, " in upstream zone \"%V\"%Z",
&shm_zone->shm.name);
+
+ /* copy peers to shared memory */
+
+ umcf = shm_zone->data;
+ uscfp = umcf->upstreams.elts;
+
+ for (i = 0; i < umcf->upstreams.nelts; i++) {
+ uscf = uscfp[i];
+
+ if (uscf->shm_zone != shm_zone) {
+ continue;
+ }
+
+ if (ngx_http_upstream_zone_copy_peers(shpool, uscf) != NGX_OK) {
+ return NGX_ERROR;
+ }
+ }
+
+ return NGX_OK;
+}
+
+
+static ngx_int_t
+ngx_http_upstream_zone_copy_peers(ngx_slab_pool_t *shpool,
+ ngx_http_upstream_srv_conf_t *uscf)
+{
+ ngx_http_upstream_rr_peer_t *peer, **peerp;
+ ngx_http_upstream_rr_peers_t *peers, *backup;
+
peers = ngx_slab_alloc(shpool, sizeof(ngx_http_upstream_rr_peers_t));
if (peers == NULL) {
return NGX_ERROR;
diff -r 85f00678e54a -r caa103acf180 src/stream/ngx_stream_upstream_zone_module.c
--- a/src/stream/ngx_stream_upstream_zone_module.c Tue Apr 21 21:04:36 2015 +0200
+++ b/src/stream/ngx_stream_upstream_zone_module.c Wed Apr 22 18:37:34 2015 +0300
@@ -14,12 +14,14 @@ static char *ngx_stream_upstream_zone(ng
void *conf);
static ngx_int_t ngx_stream_upstream_init_zone(ngx_shm_zone_t *shm_zone,
void *data);
+static ngx_int_t ngx_stream_upstream_zone_copy_peers(ngx_slab_pool_t *shpool,
+ ngx_stream_upstream_srv_conf_t *uscf);
static ngx_command_t ngx_stream_upstream_zone_commands[] = {
{ ngx_string("zone"),
- NGX_STREAM_UPS_CONF|NGX_CONF_TAKE2,
+ NGX_STREAM_UPS_CONF|NGX_CONF_TAKE12,
ngx_stream_upstream_zone,
0,
0,
@@ -57,11 +59,13 @@ ngx_module_t ngx_stream_upstream_zone_m
static char *
ngx_stream_upstream_zone(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
- ssize_t size;
- ngx_str_t *value;
- ngx_stream_upstream_srv_conf_t *uscf;
+ ssize_t size;
+ ngx_str_t *value;
+ ngx_stream_upstream_srv_conf_t *uscf;
+ ngx_stream_upstream_main_conf_t *umcf;
uscf = ngx_stream_conf_get_module_srv_conf(cf, ngx_stream_upstream_module);
+ umcf = ngx_stream_conf_get_module_main_conf(cf, ngx_stream_upstream_module);
value = cf->args->elts;
@@ -71,18 +75,23 @@ ngx_stream_upstream_zone(ngx_conf_t *cf,
return NGX_CONF_ERROR;
}
- size = ngx_parse_size(&value[2]);
+ if (cf->args->nelts == 3) {
+ size = ngx_parse_size(&value[2]);
- if (size == NGX_ERROR) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "invalid zone size \"%V\"", &value[2]);
- return NGX_CONF_ERROR;
- }
+ if (size == NGX_ERROR) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "invalid zone size \"%V\"", &value[2]);
+ return NGX_CONF_ERROR;
+ }
- if (size < (ssize_t) (8 * ngx_pagesize)) {
- ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
- "zone \"%V\" is too small", &value[1]);
- return NGX_CONF_ERROR;
+ if (size < (ssize_t) (8 * ngx_pagesize)) {
+ ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
+ "zone \"%V\" is too small", &value[1]);
+ return NGX_CONF_ERROR;
+ }
+
+ } else {
+ size = 0;
}
uscf->shm_zone = ngx_shared_memory_add(cf, &value[1], size,
@@ -91,19 +100,8 @@ ngx_stream_upstream_zone(ngx_conf_t *cf,
return NGX_CONF_ERROR;
}
- if (uscf->shm_zone->data) {
- uscf = uscf->shm_zone->data;
-
- ngx_conf_log_error(NGX_LOG_WARN, cf, 0,
- "upstream \"%V\" in %s:%ui "
- "is already bound to zone \"%V\"",
- &uscf->host, uscf->file_name, uscf->line,
- &value[1]);
- return NGX_CONF_ERROR;
- }
-
uscf->shm_zone->init = ngx_stream_upstream_init_zone;
- uscf->shm_zone->data = uscf;
+ uscf->shm_zone->data = umcf;
uscf->shm_zone->noreuse = 1;
@@ -114,21 +112,11 @@ ngx_stream_upstream_zone(ngx_conf_t *cf,
static ngx_int_t
ngx_stream_upstream_init_zone(ngx_shm_zone_t *shm_zone, void *data)
{
- ngx_stream_upstream_srv_conf_t *ouscf = data;
-
size_t len;
+ ngx_uint_t i;
ngx_slab_pool_t *shpool;
- ngx_stream_upstream_rr_peer_t *peer, **peerp;
- ngx_stream_upstream_rr_peers_t *peers, *backup;
- ngx_stream_upstream_srv_conf_t *uscf;
-
- uscf = shm_zone->data;
-
- if (ouscf) {
- ngx_log_error(NGX_LOG_EMERG, shm_zone->shm.log, 0,
- "zone \"%V\" cannot be reused", &shm_zone->shm.name);
- return NGX_ERROR;
- }
+ ngx_stream_upstream_srv_conf_t *uscf, **uscfp;
+ ngx_stream_upstream_main_conf_t *umcf;
shpool = (ngx_slab_pool_t *) shm_zone->shm.addr;
@@ -136,9 +124,6 @@ ngx_stream_upstream_init_zone(ngx_shm_zo
return NGX_ERROR;
}
-
- /* copy peers to shared memory */
-
len = sizeof(" in upstream zone \"\"") + shm_zone->shm.name.len;
shpool->log_ctx = ngx_slab_alloc(shpool, len);
@@ -149,6 +134,35 @@ ngx_stream_upstream_init_zone(ngx_shm_zo
ngx_sprintf(shpool->log_ctx, " in upstream zone \"%V\"%Z",
&shm_zone->shm.name);
+
+ /* copy peers to shared memory */
+
+ umcf = shm_zone->data;
+ uscfp = umcf->upstreams.elts;
+
+ for (i = 0; i < umcf->upstreams.nelts; i++) {
+ uscf = uscfp[i];
More information about the nginx-devel
mailing list