Глубокое понимание модуля nginx Realip.
Глубокое понимание модуля nginx Realip.
  1. введение

Модуль Real IP nginx используется для решения проблем с IP-адресами, которые могут возникнуть, когда прокси-сервер перенаправляет запросы на nginx. Потому что, когда PROXY получает запрос клиента, он подключается к серверу nginx через свой собственный IP-адрес и пересылает запрос. В результате IP-адрес, зарегистрированный в приложении nginx, будет адресом прокси-сервера, а не адресом фактического клиента.

Пример показан ниже:

 Когда nginx получает HTTP-запрос от клиента, поскольку он прошел через промежуточный прокси-сервер PROXY, NGINX по умолчанию может знать только IP-адрес интрасети 192.168.0.1 от PROXY, а не реальный IP-адрес клиента 111.22.33.44. Поэтому необходим механизм, позволяющий NGINX получать реальный IP-адрес клиента. К счастью, протокол HTTP может прозрачно передавать реальный IP-адрес клиента на серверную часть через заголовок X-Forwarded-For или заголовок X-Real-IP. Например, когда ПРОКСИ получает запрос, он Заголовок X-Forwarded-For или заголовок X-Real-IP с IP-адресом клиента будет добавлен к заголовку запроса клиента, а затем перенаправлен на внутренний сервер NGINX. Сервер NGINX должен получить его из соответствующего заголовка HTTP-запроса. по договору Реальный IP клиента.

Задача модуля Real IP — восстановить реальный IP-адрес клиента, переданный прокси-сервером, до фактического IP-адреса клиента, чтобы модуль приложения в nginx мог получить реальный IP-адрес клиента.

 В этой статье сначала описывается использование и настройка модуля Real IP, а затем анализируется исходный код модуля Real IP, чтобы получить более глубокое понимание механизма его реализации.

2. Использование модуля Real IP.

2.1 Включить модуль Real IP

 ngx_http_realip_module по умолчанию не включен. Поэтому вам необходимо включить этот модуль во время настройки следующим образом:

Язык кода:javascript
копировать
./configure --with-http_realip_module

2.2 Настройка модуля Real IP

2.2.1 Инструкции по настройке

1. команда настройки real_ip_header

Язык кода:javascript
копировать
язык  Закон:    
        real_ip_header field | X-Real-IP | X-Forwarded-For | proxy_protocol;
значение по умолчанию:    
        real_ip_header X-Real-IP;
Контекст:    
        http, server, location

 Эта команда используется для определения места получения реального IP-адреса клиента, чтобы NGINX мог получить его и заменить полученный реальный IP-адрес клиента на IP-адрес прокси-сервера.

 Параметры включают заголовок X-Real-IP, заголовок X-Forwarded-For или пользовательский заголовок HTTP. Кроме того, он также поддерживает получение реального IP клиента через протокол proxy_protocol. Разумеется, чтобы использовать эту опцию, сначала нужно включить функцию proxy_protocol на nginx.

2. команда настройки real_ip_recursive

Язык кода:javascript
копировать
язык  Закон:    
        real_ip_recursive on | off;
значение по умолчанию:    
        real_ip_recursive off;
Контекст:    
        http, server, location

 Эта команда используется для включения или отключения использования многоуровневых прокси-серверов при получении реального IP-адреса клиента через заголовки, связанные с HTTP.

Если рекурсивный поиск отключен, исходный адрес клиента, соответствующий одному из доверенных адресов, будет заменен последним адресом в поле заголовка запроса, определенном директивой real_ip_header. Если включен рекурсивный поиск, исходный адрес клиента, соответствующий одному из доверенных адресов, будет заменен последним недоверенным адресом в поле заголовка запроса.

Включив опцию рекурсии, nginx может справиться с ситуацией, когда клиент и nginx использовали несколько прокси-серверов, nginx может удалить все IP-адреса ПРОКСИ через установленный список ПРОКСИ и найти первый IP-адрес, который не является ПРОКСИ, как реальный IP-адрес клиента. .

3. команда настройки set_real_ip_from

  Определите адреса одного или нескольких доверенных ПРОКСИ-серверов в следующем формате:

Язык кода:javascript
копировать
язык  Закон:    
        set_real_ip_from address | CIDR | unix:;
значение по умолчанию:    
        —
Контекст:    
        http, server, location

Команда set_real_ip_from может быть определена несколько раз. Определенный адрес ПРОКСИ-сервера может быть указан в форме IP/маски (т. е. CIDR) или в форме имени домена. Его также можно указать как «unix:» для выражения доверия. во всех unix-сокетах соединение установлено.

  Например, так:

Язык кода:javascript
копировать
set_real_ip_from 192.168.0.0/24;
set_real_ip_from unix:
set_real_ip_from www.test_proxy.com;

2.2.2 Примеры

Давайте сначала приведем пример:

Язык кода:javascript
копировать
http {
    # ...
    real_ip_header X-Forwarded-For;
    real_ip_recursive on;
    # ...
}

Приведенный выше пример включает функцию Real IP, и nginx будет искать заголовок X-Forwarded-For, чтобы получить реальный IP-адрес клиента.

3. Использование переменных

После того, как этот модуль получит реальный IP-адрес клиента, он заменит подключенный к нему IP-адрес на реальный IP-адрес клиента. Конечно, иногда нам все равно необходимо получить IP-адрес и порт ПРОКСИ, поэтому nginx также предоставляет его. соответствующий механизм для ее получения. То есть эта информация предоставляется через переменные. Включает две переменные следующим образом:

  • $realip_remote_addr: IP-адрес ПРОКСИ.
  • realip_remote_port: PROXY и nginxсоединятьиз номера локального порта PROXY
  1. Анализ исходного кода

3.1 Анализ инструкций по настройке

3.1.1 set_real_ip_from

Язык кода:javascript
копировать
    
Язык кода:javascript
копировать
{ ngx_string("set_real_ip_from"),
      NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
      ngx_http_realip_from,
      NGX_HTTP_LOC_CONF_OFFSET,
      0,
      NULL },

  В функции обратного вызова ngx_http_realip_from, указанной в приведенной выше конфигурации, разрешенный адрес доверенного прокси-сервера будет сохранен в rlcf->fromвнутри массива。Например, следующий код:

Язык кода:javascript
копировать
 if (ngx_strcmp(value[1].data, "unix:") == 0) {
        cidr = ngx_array_push(rlcf->from);
        if (cidr == NULL) {
            return NGX_CONF_ERROR;
        }

        cidr->family = AF_UNIX;
        return NGX_CONF_OK;
    }

  При анализе unix: в массив будет добавлен тип семейства. Запись для AF_UNIX.  Для CDIR, представленного IP/MASK, будет проанализирован cdir (поддерживается адреса типа ipv4 и ipv6).  длядоменное имя,Затем nginx вызовет ngx_inet_resolve_host для разрешения имени домена.,Следует отметить, что из,Эта операция разрешения доменного имени представляет собой синхронный запрос.,Если операция разрешения доменного имени выполняется медленно,может привести кnginxзапускатьизиногда застреваю。Разобрать этоизнесколькоIPАдреса будут добавляться один за другимrlcf->fromв массиве。

3.1.2 real_ip_header

Язык кода:javascript
копировать
    
Язык кода:javascript
копировать
{ ngx_string("real_ip_header"),
      NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE1,
      ngx_http_realip,
      NGX_HTTP_LOC_CONF_OFFSET,
      0,
      NULL },

В функции обратного вызова ngx_http_realip, указанной в приведенной выше конфигурации, будет анализироваться тип источника реального IP-адреса клиента, включая стандартный HTTP-заголовок с именем X-Real-IP, X-Forwarded-For или собственный HTTP-заголовок. Вы также можете указать. proxy_protocol. Использовать реальный IP-адрес клиента, прозрачно передаваемый по протоколу proxy_protocol.  

Исходный код выглядит следующим образом:

Язык кода:javascript
копировать
static char *
ngx_http_realip(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
    ngx_http_realip_loc_conf_t *rlcf = conf;

    ngx_str_t  *value;

    if (rlcf->type != NGX_CONF_UNSET_UINT) {
        return "is duplicate";
    }

    value = cf->args->elts;

    if (ngx_strcmp(value[1].data, "X-Real-IP") == 0) {
        rlcf->type = NGX_HTTP_REALIP_XREALIP;
        return NGX_CONF_OK;
    }

    if (ngx_strcmp(value[1].data, "X-Forwarded-For") == 0) {
        rlcf->type = NGX_HTTP_REALIP_XFWD;
        return NGX_CONF_OK;
    }

    if (ngx_strcmp(value[1].data, "proxy_protocol") == 0) {
        rlcf->type = NGX_HTTP_REALIP_PROXY;
        return NGX_CONF_OK;
    }

    /* Здесь предварительно рассчитайте поиск в заголовке HTTP-запроса по имени пользовательского HTTP-заголовка и хеш-значению. 
       для X-Real-IP и X-Forwarded-Forheadа, когда nginx анализирует заголовок запроса из
       было автоматически установлено значениеr->headers_inпереписыватьсяизв поле,Таким образом, вы можете извлечь его напрямую, без поиска.,
       Таким образом, только пользовательские заголовки HTTP должны вычислять хеш-значение.
    */
    rlcf->type = NGX_HTTP_REALIP_HEADER;
    rlcf->hash = ngx_hash_strlow(value[1].data, value[1].data, value[1].len);
    rlcf->header = value[1];

    return NGX_CONF_OK;
}

3.1.3 real_ip_recursive

Язык кода:javascript
копировать
{ ngx_string("real_ip_recursive"),
      NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG,
      ngx_conf_set_flag_slot,
      NGX_HTTP_LOC_CONF_OFFSET,
      offsetof(ngx_http_realip_loc_conf_t, recursive),
      NULL },

Директива конфигурации real_ip_recursive устанавливает только один флаг — рекурсивный.

3.2 Инициализация модуля

  Инициализация модуля завершается функцией ngx_http_realip_init, которая выполняется на этапе постконфигурации. Эта функция монтирует функцию обратного вызова на этапе NGX_HTTP_POST_READ_PHASE. Когда nginx завершает чтение заголовка запроса, он вызывает обратный вызов ngx_http_realip_handler. В то же время эта функция также монтирует функцию обратного вызова на этапе NGX_HTTP_PREACESS_PHASE, которая также является функцией ngx_http_realip_handler.

 Почему нам нужно выполнять одну и ту же функцию обратного вызова в два этапа? Я думаю, что в нормальных обстоятельствах его нужно выполнить только на этапе NGX_HTTP_POST_READ_PHASE. Однако в случае, когда настроен пользовательский заголовок HTTP HEADER, этот модуль позволяет другим пользовательским модулям добавлять этот пользовательский HTTP перед этапом NGX_HTTP_PREACCESS_PHASE. Заголовок запроса HEADER анализируется ngx_http_realip_handler на этапе NGX_HTTP_PREACCESS_PHASE для получения реального IP-адреса клиента. Эта реализация является более гибкой. Способ получения реального IP-адреса клиента может быть настроен пользователем и даже может быть помещен в URL-адрес запроса. HTTP BODY середина.

3.3 Обработка запросов

Когда nginx получает входящий запрос, он вызывает функцию ngx_http_realip_handler на этапе NGX_HTTP_POST_READ_PHASE. Давайте проанализируем функцию ngx_http_realip_handler.

  Сначала будет оценено, включен ли реальный ipФункция,Это переданоrlcf->fromЭтоNULLсудитьиз,Следующий код:

Язык кода:javascript
копировать
rlcf = ngx_http_get_module_loc_conf(r, ngx_http_realip_module);

    if (rlcf->from == NULL) {
        return NGX_DECLINED;
    }

 Если он равен NULL, возвращается NGX_DECLINED, остальная логика этого модуля пропускается, и nginx выполняет последующую обработку.

Следующим шагом является получение контекстной информации. Если контекстная информация уже существует, это означает, что текущий запрос был обработан этим модулем, и логика этого модуля напрямую пропускается, как показано в следующем коде:

Язык кода:javascript
копировать
 ctx = ngx_http_realip_get_module_ctx(r);

    if (ctx) {
        return NGX_DECLINED;
    }

Ниже необходимо обработать различные типы источников, установленные клиентом, для получения реального IP-адреса, а именно заголовка X-Real-IP, заголовка X-Forwarded-For, протокола proxy_protocol и других пользовательских заголовков. Исходный код такой. следует:

Язык кода:javascript
копировать
switch (rlcf->type) {

    case NGX_HTTP_REALIP_XREALIP:

        if (r->headers_in.x_real_ip == NULL) {
            return NGX_DECLINED;
        }

        value = &r->headers_in.x_real_ip->value;
        xfwd = NULL;

        break;

    case NGX_HTTP_REALIP_XFWD:

        xfwd = r->headers_in.x_forwarded_for;

        if (xfwd == NULL) {
            return NGX_DECLINED;
        }

        value = NULL;

        break;

    case NGX_HTTP_REALIP_PROXY:

        if (r->connection->proxy_protocol == NULL) {
            return NGX_DECLINED;
        }

        value = &r->connection->proxy_protocol->src_addr;
        xfwd = NULL;

        break;

    default: /* NGX_HTTP_REALIP_HEADER */

        part = &r->headers_in.headers.part;
        header = part->elts;

        hash = rlcf->hash;
        len = rlcf->header.len;
        p = rlcf->header.data;

        /* Просмотрите список заголовков http-запроса, чтобы найти пользовательские заголовки. */
        for (i = 0; /* void */ ; i++) {

            if (i >= part->nelts) {
                if (part->next == NULL) {
                    break;
                }

                part = part->next;
                header = part->elts;
                i = 0;
            }

            if (hash == header[i].hash
                && len == header[i].key.len
                && ngx_strncmp(p, header[i].lowcase_key, len) == 0)
            {
                value = &header[i].value;
                xfwd = NULL;

                goto found;
            }
        }
        /* Если пользовательскую голову невозможно найти, пропустите этот модуль и другую логику. */
        return NGX_DECLINED;
    }

 Наконец, полученному реальному IP-адресу клиента присваивается значение sockaddr в объекте соединения c. Исходный код выглядит следующим образом:

Язык кода:javascript
копировать
found:

    c = r->connection;

    addr.sockaddr = c->sockaddr;
    addr.socklen = c->socklen;
    /* addr.name = c->addr_text; */

    if (ngx_http_get_forwarded_addr(r, &addr, xfwd, value, rlcf->from,
                                    rlcf->recursive)
        != NGX_DECLINED)
    {
        if (rlcf->type == NGX_HTTP_REALIP_PROXY) {
            ngx_inet_set_port(addr.sockaddr, c->proxy_protocol->src_port);
        }

        /* Установите реальный IP-адрес клиента */
        return ngx_http_realip_set_addr(r, &addr);
    }

    return NGX_DECLINED;

3.4 Получите реальный IP клиента

 Функция ngx_http_realip_handler получает поля, которые можно использовать для получения реального IP-адреса клиента в соответствии с набором различных категорий, а затем вызывает ngx_http_get_forwarded_addr для получения IP-адреса.

  Необходимо понимать, что этот модуль использует две стратегии обработки для X-Real-IP и пользовательских заголовков, а также X-Forwarded-For. В первом случае просто установите поле значения перед вызовом ngx_http_get_forwarded_addr, а во втором будет установлено поле xfwd для сохранения всех заголовков X-Forwarded-For (возможно, более одного, но нескольких).

 Для запросов, отличных от X-Forwarded-For, в функции ngx_http_get_forwarded_addr выполните следующую логику:

Язык кода:javascript
копировать
if (headers == NULL) {
    return ngx_http_get_forwarded_addr_internal(r, addr, value->data,
                                                value->len, proxies,
                                                recursive);
}

Для запросов X-Forwarded-For в функции ngx_http_get_forwarded_addr в этом случае при включенной рекурсии нужно пройти по всем одноименным заголовкам X-Forwarded-For и выполнить следующую логику:

Язык кода:javascript
копировать
/* Отсортируйте заголовок X-Forwarded-For в обратном порядке, в порядке, указанном в заголовке HTTP-запроса. */
for (h = headers, headers = NULL; h; h = next) {
    next = h->next;
    h->next = headers;
    headers = h;
}

/* iterate over all headers in reverse order */

rc = NGX_DECLINED;

found = 0;

/* Пройти все X-Forwarded-Forheadа, извлечь IP-адрес клиента */
for (h = headers; h; h = h->next) {
    rc = ngx_http_get_forwarded_addr_internal(r, addr, h->value.data,
                                              h->value.len, proxies,
                                              recursive);

    if (!recursive) {   /* Если режим рекурсии не включен, может обрабатываться только один заголовок X-Forwarded-For. */    
        break;
    }


    if (rc == NGX_DECLINED && found) {
        rc = NGX_DONE;  /* Когда рекурсияиз включена, возвращается первый ненадежный IP-адрес сзади вперед. */
        break;
    }

    if (rc != NGX_OK) {
        break;
    }

    /* Когда режим рекурсии включен, он продолжит поиск следующего заголовка X-Forwarded-For. */
    found = 1;
}

/* Восстановите все заголовки X-Forwarded-For в исходном порядке. */ 
for (h = headers, headers = NULL; h; h = next) {
    next = h->next;
    h->next = headers;
    headers = h;
}

return rc;

Ниже приведен исходный код реализации ngx_http_get_forwarded_addr_internal:

Язык кода:javascript
копировать
static ngx_int_t
ngx_http_get_forwarded_addr_internal(ngx_http_request_t *r, ngx_addr_t *addr,
    u_char *xff, size_t xfflen, ngx_array_t *proxies, int recursive)
{
    u_char      *p;
    ngx_addr_t   paddr;
    ngx_uint_t   found;

    found = 0;

    do {
        /* ngx_cidr_matchфункция возвращает NGX_OK при совпадении сегмента изIP в заданном списке прокси
           В противном случае верните NGX_DECLINED. */
        if (ngx_cidr_match(addr->sockaddr, proxies) != NGX_OK) {
            /* Если совпадения ранее не было, верните NGX_DECLINED.
               Если ранее было совпадение, возвращается NGX_DONE. 
                 выражать Когда рекурсияиз включена, возвращается первый ненадежный IP-адрес сзади вперед. */
             */
            return found ? NGX_DONE : NGX_DECLINED;
        }

        /* Обратный поиск следующего IP-адреса. Используйте пробелы или пробелы для разделения нескольких IP-адресов. */
        for (p = xff + xfflen - 1; p > xff; p--, xfflen--) {
            if (*p != ' ' && *p != ',') {
                break;
            }
        }

        for ( /* void */ ; p > xff; p--) {
            if (*p == ' ' || *p == ',') {
                p++;
                break;
            }
        }

        /* На основе приведенного выше текста определите реальный IP-адрес клиента. */
        if (ngx_parse_addr_port(r->pool, &paddr, p, xfflen - (p - xff))
            != NGX_OK)
        {
            return found ? NGX_DONE : NGX_DECLINED;
        }

        *addr = paddr;
        found = 1;
        xfflen = p - 1 - xff;

    } while (recursive && p > xff);  /* Продолжить сканирование с включенной рекурсияиз */

    return NGX_OK;
}

Подведем итог: логика приведенного выше кода заключается в том, что при отключении рекурсии, когда IP-адрес, подключенный к nginx, находится в списке PROXY, будет возвращен HTTP. Последний IP-адрес, установленный в заголовке HEADER, в противном случае действие по настройке реального IP-адреса клиента не будет выполнено, а при включенной рекурсии, когда IP-адрес, подключенный к nginx, находится в списке PROXY, заголовок HTTP-запроса будет установлен из Among; IP-адреса расположены задом наперед, первый IP-адрес, которого нет в списке ПРОКСИ, всегда считается реальным IP-адресом клиента. В противном случае действие по настройке реального IP-адреса клиента не будет выполнено.

Таким образом, включив рекурсивную опцию, nginx может справиться с ситуацией, когда клиент и nginx используют несколько прокси-серверов. nginx может выделить все IP-адреса ПРОКСИ через установленный список ПРОКСИ и найти первый IP-адрес, который не является ПРОКСИ. реальный IP-адрес клиента. Но несмотря ни на что, вам необходимо убедиться, что адрес ПРОКСИ, который имеет реальное TCP-соединение с nginx, должен быть в списке ПРОКСИ. Только тогда nginx сможет получить реальный IP-адрес клиента, а затем установить реальный IP-адрес клиента.

3.5 Установите реальный IP-адрес клиента

 После получения реального IP-адреса клиента этот модуль вызывает функцию ngx_http_realip_set_addr для установки реального адреса клиента.

 Во-первых, необходимо преобразовать IP-адрес в текст. Исходный код выглядит следующим образом:

Язык кода:javascript
копировать
len = ngx_sock_ntop(addr->sockaddr, addr->socklen, text,
                        NGX_SOCKADDR_STRLEN, 0);
if (len == 0) {
    return NGX_HTTP_INTERNAL_SERVER_ERROR;
}

 После вышеуказанной операции текстовая информация IP-адреса помещается в массив текстовых строк.  Затем выделите пространство памяти из пула памяти для сохранения содержимого массива текстовых строк. Исходный код выглядит следующим образом:

Язык кода:javascript
копировать
p = ngx_pnalloc(c->pool, len);
if (p == NULL) {
    return NGX_HTTP_INTERNAL_SERVER_ERROR;
}

ngx_memcpy(p, text, len);

 Установите контекстную информацию модуля, исходный код выглядит следующим образом:

Язык кода:javascript
копировать
ngx_http_set_ctx(r, ctx, ngx_http_realip_module);

    ctx->connection = c;
    ctx->sockaddr = c->sockaddr;
    ctx->socklen = c->socklen;
    ctx->addr_text = c->addr_text;

Как только контекст модуля установлен, это означает, что модуль обработал этот запрос и установил реальный IP клиента. Нет необходимости обрабатывать его повторно при повторном входе в функцию ngx_http_realip_handler.

  Наконец, введите текстовую информацию об IP-адресе в поле информации о подключенном адресе. Исходный код выглядит следующим образом:

Язык кода:javascript
копировать
c->sockaddr = addr->sockaddr;
c->socklen = addr->socklen;
c->addr_text.len = len;
c->addr_text.data = p;

После выполнения вышеуказанной операции с исходным кодом вы получите вновь установленный реальный IP-адрес клиента, когда впоследствии получите IP-адрес клиента в других модулях nginx.

 В приведенном выше процессе анализа механизм окончательной обработки после завершения запроса был намеренно пропущен. Давайте объясним ниже:

  Завершающая обработка реализована с использованием механизма самого пула памяти nginx. Исходный код выглядит следующим образом:

Язык кода:javascript
копировать
cln = ngx_pool_cleanup_add(r->pool, sizeof(ngx_http_realip_ctx_t));
    if (cln == NULL) {
        return NGX_HTTP_INTERNAL_SERVER_ERROR;
    }
......

    /* Установить функцию обратного вызова  */
    cln->handler = ngx_http_realip_cleanup;

......

Найдите объект перезапуска в пуле памяти текущего запроса. Функция обратного вызова, установленная в смонтированном объекте перезапуска, будет автоматически вызвана, когда пул памяти будет освобожден в конце запроса. Вот функция ngx_http_realip_cleanup.

3.6 Отделочные работы

  ngx_http_realip_cleanup будет вызван обратно, когда текущий запрос завершится, и его основная задача — восстановить реальный IP-адрес клиента, установленный выше. Поскольку сеанс TCP-соединения клиента может инициировать несколько HTTP-запросов, nginx необходимо восстановить контекст соединения после завершения HTTP-запроса.

Так зачем нам восстанавливать контекст соединения? Разве нельзя использовать реальный IP-адрес подключенного в данный момент клиента до следующего запроса? Ответ — нет. Поскольку соединение между PROXY и nginx может быть повторно использовано PROXY, и когда поступит следующий запрос, вполне возможно, что это не исходный клиент. Если вы будете следовать этой логике, и PROXY повторно использует предыдущее соединение с nginx, это будет так. вполне возможно, что это «переход».

 Исходный код следующий:

Язык кода:javascript
копировать
static void
ngx_http_realip_cleanup(void *data)
{
    ngx_http_realip_ctx_t *ctx = data;

    ngx_connection_t  *c;

    c = ctx->connection;

    c->sockaddr = ctx->sockaddr;
    c->socklen = ctx->socklen;
    c->addr_text = ctx->addr_text;
}

 Из исходного кода функции ngx_http_realip_cleanup мы видим, что никакой логики для переработки памяти нет, потому что логика переработки памяти полностью обрабатывается автоматически пулом памяти nginx, и нам не нужно об этом заботиться.

boy illustration
Учебное пособие по Jetpack Compose для начинающих, базовые элементы управления и макет
boy illustration
Код js веб-страницы, фон частицы, код спецэффектов
boy illustration
【новый! Суперподробное】Полное руководство по свойствам компонентов Figma.
boy illustration
🎉Обязательно к прочтению новичкам: полное руководство по написанию мини-программ WeChat с использованием программного обеспечения Cursor.
boy illustration
[Забавный проект Docker] VoceChat — еще одно приложение для мгновенного чата (IM)! Может быть встроен в любую веб-страницу!
boy illustration
Как реализовать переход по странице в HTML (html переходит на указанную страницу)
boy illustration
Как решить проблему зависания и низкой скорости при установке зависимостей с помощью npm. Существуют ли доступные источники npm, которые могут решить эту проблему?
boy illustration
Серия From Zero to Fun: Uni-App WeChat Payment Practice WeChat авторизует вход в систему и украшает страницу заказа, создает интерфейс заказа и инициирует запрос заказа
boy illustration
Серия uni-app: uni.navigateЧтобы передать скачок значения
boy illustration
Апплет WeChat настраивает верхнюю панель навигации и адаптируется к различным моделям.
boy illustration
JS-время конвертации
boy illustration
Обеспечьте бесперебойную работу ChromeDriver 125: советы по решению проблемы chromedriver.exe не найдены
boy illustration
Поле комментария, щелчок мышью, специальные эффекты, js-код
boy illustration
Объект массива перемещения объекта JS
boy illustration
Как открыть разрешение на позиционирование апплета WeChat_Как использовать WeChat для определения местонахождения друзей
boy illustration
Я даю вам два набора из 18 простых в использовании фонов холста Power BI, так что вам больше не придется возиться с цветами!
boy illustration
Получить текущее время в js_Как динамически отображать дату и время в js
boy illustration
Вам необходимо изучить сочетания клавиш vsCode для форматирования и организации кода, чтобы вам больше не приходилось настраивать формат вручную.
boy illustration
У ChatGPT большое обновление. Всего за 45 минут пресс-конференция показывает, что OpenAI сделал еще один шаг вперед.
boy illustration
Copilot облачной разработки — упрощение разработки
boy illustration
Микросборка xChatGPT с низким кодом, создание апплета чат-бота с искусственным интеллектом за пять шагов
boy illustration
CUDA Out of Memory: идеальное решение проблемы нехватки памяти CUDA
boy illustration
Анализ кластеризации отдельных ячеек, который должен освоить каждый&MarkerгенетическийВизуализация
boy illustration
vLLM: мощный инструмент для ускорения вывода ИИ
boy illustration
CodeGeeX: мощный инструмент генерации кода искусственного интеллекта, который можно использовать бесплатно в дополнение к второму пилоту.
boy illustration
Машинное обучение Реальный бой LightGBM + настройка параметров случайного поиска: точность 96,67%
boy illustration
Бесшовная интеграция, мгновенный интеллект [1]: платформа больших моделей Dify-LLM, интеграция без кодирования и встраивание в сторонние системы, более 42 тысяч звезд, чтобы стать свидетелями эксклюзивных интеллектуальных решений.
boy illustration
LM Studio для создания локальных больших моделей
boy illustration
Как определить количество слоев и нейронов скрытых слоев нейронной сети?
boy illustration
[Отслеживание целей] Подробное объяснение ByteTrack и детали кода