[alibaba/tengine]dyups 内存泄漏问题

2024-05-15 276 views
5

在ngx_dyups_do_update函数中,如果是走的upstream reuse逻辑,那么找到的ngx_http_dyups_srv_conf_t* duscf中的pool将是非空的。然后再调用ngx_dyups_init_upstream,该函数中没有对pool是否空做判断,直接做了create pool操作,会导致原来的pool未被释放?

static ngx_int_t ngx_dyups_init_upstream(ngx_http_dyups_srv_conf_t duscf, ngx_str_t name, ngx_uint_t index) { ... umcf = ngx_http_cycle_get_module_main_conf(ngx_cycle, ngx_http_upstream_module); uscfp = umcf->upstreams.elts;

duscf->pool = ngx_create_pool(512, ngx_cycle->log);
if (duscf->pool == NULL) {
    return NGX_ERROR;
}

... }

  1. If applicable, add nginx debug log doc.

回答

9

应该是在这里清理了

https://github.com/alibaba/tengine/blob/a83220a7aa489f9d8912e85a9d21fa69735b9554/modules/ngx_http_upstream_dyups_module/ngx_http_dyups_module.c#L1549-L1552

按照ngx_dyups_do_update的逻辑,在里面第二次调用ngx_dyups_find_upstream的时候会调用ngx_destroy_pool(duscf->pool) 清理缓冲池,但是前提是duscf->ref == 0 ` duscf = ngx_dyups_find_upstream(name, &idx); if (duscf) { ngx_log_error(NGX_LOG_DEBUG, ngx_cycle->log, 0, "[dyups] upstream reuse, idx: [%i]", idx);

if (!duscf->deleted) {
  ngx_log_error(NGX_LOG_DEBUG, ngx_cycle->log, 0,
                "[dyups] upstream delete first");
  ngx_dyups_mark_upstream_delete(duscf);

  **duscf = ngx_dyups_find_upstream(name, &idx);**

  ngx_log_error(NGX_LOG_DEBUG, ngx_cycle->log, 0,
                "[dyups] find another, idx: [%i]", idx);
}

}`

` if (duscf->deleted == NGX_DYUPS_DELETING) {

  ngx_log_error(NGX_LOG_DEBUG, ngx_cycle->log, 0,
                "[dyups] find upstream idx: %ui ref: %ui "
                "on %V deleting",
                i, *(duscf->ref), &duscf->upstream->host);

  **if (*(duscf->ref) == 0)** {
    ngx_log_error(NGX_LOG_INFO, ngx_cycle->log, 0,
                  "[dyups] free dynamic upstream in find upstream"
                  " %ui",
                  duscf->idx);

    duscf->deleted = NGX_DYUPS_DELETED;

    if (duscf->pool) {
      ngx_destroy_pool(duscf->pool);
      duscf->pool = NULL;
    }
  }
}`
5

按照ngx_dyups_do_update的逻辑,在里面第二次调用ngx_dyups_find_upstream的时候会调用ngx_destroy_pool(duscf->pool) 清理缓冲池,但是前提是duscf->ref == 0

7

这个没啥问题。只有极特殊情况,请求会拽着ref不放。(比如说一个超长交互的请求 使用了一个upstream,这个upstream在使用过程中又被删除了

1

session sticky 模块也看看额