> For the complete documentation index, see [llms.txt](https://docs.iexexchanger.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.iexexchanger.com/server-i-dannye/proizvoditelnost.md).

# Производительность

Эта инструкция предназначена для проверки и настройки производительности уже установленного и работающего iEXExchanger на чистом сервере.

Обычно настройки производительности пересматривают после запуска проекта, когда появилась реальная нагрузка и можно определить, какого ресурса не хватает. Если сайт и административная панель работают стабильно, серверу хватает ресурсов, а системные службы не завершаются с ошибками, менять настройки только из-за прошедшего времени не требуется.

{% hint style="warning" %}
Не выбирайте профиль выше фактических характеристик сервера. Завышенные значения могут привести к нехватке оперативной памяти, активному использованию swap и остановке PHP-FPM, PostgreSQL или Redis.
{% endhint %}

Требования к операционной системе, диску и другим ресурсам находятся на отдельной странице.

{% content-ref url="/pages/RjtzBZHtqwFTm8nJo8p8" %}
[Системные требования](/ustanovka-i-obnovlenie/sistemnye-trebovaniya.md)
{% endcontent-ref %}

### Что настраивает профиль

Профиль производительности содержит согласованные значения для следующих компонентов:

* PHP-FPM — количество одновременно работающих PHP-процессов;
* PHP и OPcache — память одного запроса, загрузка файлов и кеш скомпилированного PHP-кода;
* PostgreSQL — память базы данных, количество подключений и объём WAL;
* Redis — максимальный объём памяти;
* Nginx — максимальный размер запроса;
* swap — резерв дисковой памяти для кратковременного дефицита RAM;
* Huge Pages — большие страницы памяти, которые PostgreSQL может использовать для общей памяти.

Профиль не исправляет медленные SQL-запросы, ошибки приложения, переполненный диск, проблемы сети, внешних сервисов или тяжёлые файлы Frontend. Перед увеличением профиля необходимо подтвердить, что серверу действительно не хватает CPU или RAM.

### Ограничение готового сервера

{% hint style="danger" %}
Не запускайте первичную установку повторно для изменения производительности. Installer блокирует повторный `install` после успешно завершённой установки.
{% endhint %}

Автоматическое применение профиля выполняется во время первичной установки. В текущем Installer нет отдельной пользовательской команды `performance apply` или `reconfigure` для уже работающего сервера.

Управляемые файлы PHP-FPM, PostgreSQL, Redis и Nginx нельзя заменять произвольными конфигурациями. Несогласованные значения могут нарушить запуск служб, а последующая операция Installer или Updater может перезаписать ручные изменения.

## Когда требуется настройка

{% stepper %}
{% step %}

### Признаки нехватки ресурсов

Проверьте производительность, если наблюдается хотя бы один из следующих признаков:

* сайт или административная панель замедляются во время нагрузки;
* средняя нагрузка процессора продолжительное время выше количества доступных vCPU;
* сервер постоянно переносит данные между RAM и swap;
* ядро завершает процессы из-за нехватки памяти;
* PHP-FPM сообщает о достижении `pm.max_children`;
* PostgreSQL создаёт всё больше временных файлов или фиксирует взаимные блокировки;
* сервер был расширен и требуется согласовать настройки с новым количеством vCPU и RAM;
* фактические значения PHP-FPM, PostgreSQL и Redis относятся к разным профилям.
  {% endstep %}

{% step %}

### Когда профиль менять не нужно

Не изменяйте профиль, если:

* Installer успешно проверяет систему;
* публичные адреса отвечают;
* упавших служб нет;
* OOM-события отсутствуют;
* PHP-FPM не достигает лимита процессов;
* `vmstat` не показывает постоянный обмен данными со swap;
* нагрузка процессора после кратковременного пика возвращается к нормальному уровню.

Занятый swap сам по себе не является ошибкой. Linux может сохранять в нём редко используемые страницы памяти даже после завершения нагрузки.
{% endstep %}
{% endstepper %}

***

## Промпт для AI агента

Промпт предназначен для диагностики уже установленного сервера. Агент получает только SSH-доступ, а домены, пути, службы и текущий профиль определяет из установленной системы.

{% prompt description="Проверить производительность iEXExchanger" icon="rectangle-terminal" openInAIProviders="true" defaultExpanded="partial" %}

```markdown
# Роль

Ты — технический агент по безопасной диагностике производительности уже установленного iEXExchanger на чистом сервере.

# Данные для подключения

- Сервер: [IP-адрес или имя сервера]
- Пользователь: [SSH-пользователь]
- Пароль или SSH-ключ: [данные доступа]

# Задача

Проведи полную диагностику производительности по инструкции:

https://docs.iexexchanger.com/server-i-dannye/proizvoditelnost.md?displayAgentInstructions=false

Определи фактически применённый профиль, оцени CPU, RAM, swap, PHP-FPM, PostgreSQL и состояние системных служб. Установи, требуется ли изменение профиля.

# Правила

1. Сначала выполняй только read-only проверки.
2. Не запускай первичную установку повторно.
3. Не выполняй обновление продукта и не запускай команды, изменяющие схему или данные PostgreSQL.
4. Не запускай `iex-updater apply`, `performance apply` или `reconfigure`.
5. Не изменяй `/home/installer/install.yaml`, active release, `/etc/iexexchanger/installation.json` и управляемые конфигурации собственным скриптом.
6. Не очищай swap и системный кеш.
7. Не выводи пароли, ключи, `.env`, лицензии и содержимое `/etc/iexexchanger/secrets`.
8. Определи профиль по фактическим значениям PHP-FPM, PHP, PostgreSQL, Redis и Nginx, а не только по строке `profile: auto`.
9. Если система исправна и подтверждённого дефицита ресурсов нет, не вноси изменений.
10. Если нужен более высокий профиль, сначала укажи требуемые vCPU и RAM и проверь, что эти ресурсы добавлены серверу.
11. Перед разрешённым изменением проверь состояние Updater, запусти штатный backup и создай root-only копию управляемых конфигураций по инструкции.
12. Используй только поддерживаемый способ применения профиля, подтверждённый для установленной сборки Installer.
13. Если отдельной post-install команды нет, не придумывай её и не подменяй собственной реализацией. Подготовь данные для технической поддержки.
14. После разрешённого изменения проверь конфигурации, фактические значения профиля, службы, Installer, публичные адреса, OOM-события и активность swap.

# Отчёт

- Общий статус: стабильно / есть предупреждения / есть ошибки.
- Фактически применённый профиль и подтверждающие значения.
- Количество vCPU, RAM, доступная память, swap, диск и текущая нагрузка.
- Состояние PHP-FPM, PostgreSQL, Redis, Nginx и проверки Installer.
- Найденные OOM-события или достижения `pm.max_children`.
- Нужен ли другой профиль и почему.
- Какие действия фактически выполнены.
- Путь к backup конфигураций, если он был создан.
- Результат проверки после разрешённых изменений.
```

{% endprompt %}

***

## Этап 1. Диагностика работающего сервера

### Перед началом

Для диагностики потребуется SSH-доступ с правами `root` или `sudo`.

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

{% stepper %}
{% step %}

#### Проверьте ресурсы сервера

Перейдите в режим `root`:

```bash
sudo -i
```

Выполните:

```bash
nproc
uptime
free -h
df -h /
vmstat 1 10
systemctl --failed --no-legend --no-pager
```

Команды показывают количество vCPU, среднюю нагрузку, доступную память, swap, свободное место и упавшие службы.
{% endstep %}

{% step %}

#### Проверьте текущий профиль

Выполните:

```bash
php_pool="$(find /etc/php -type f \
  -path '*/fpm/pool.d/iexexchanger.conf' -print -quit)"

postgresql_conf="$(find /etc/postgresql -type f \
  -path '*/main/conf.d/iexexchanger.conf' -print -quit)"

test -n "$php_pool"
test -n "$postgresql_conf"

grep -E '^(pm\.max_children|php_admin_value\[memory_limit\])' "$php_pool"
grep -E '^(shared_buffers|max_connections)' "$postgresql_conf"
grep -E '^(maxmemory |maxmemory-policy )' /etc/redis/redis.conf
grep -hE '^client_max_body_size ' \
  /etc/nginx/snippets/iexexchanger/routes-backend.conf \
  /etc/nginx/snippets/iexexchanger/routes-frontend.conf
```

Сопоставьте полученные значения с таблицами в разделе «Точные значения профилей».

Значение `profile: auto` в `/home/installer/install.yaml` означает только автоматический выбор во время первой установки. Оно не подтверждает фактически применённый профиль после изменения ресурсов сервера.
{% endstep %}

{% step %}

#### Проверьте нехватку памяти и процессов PHP-FPM

Выполните:

```bash
journalctl -k --since "-24 hours" --no-pager \
  | grep -Ei 'out of memory|oom-kill|killed process'

grep -Ei 'max_children|server reached' \
  /var/log/iexexchanger/php-fpm-error.log 2>/dev/null \
  | tail -n 50
```

Если первая команда ничего не вывела, ядро не фиксировало OOM-события за последние 24 часа.

Повторяющиеся сообщения о `pm.max_children` во время замедления означают, что PHP-FPM достиг разрешённого количества процессов. Перед увеличением лимита убедитесь, что серверу хватает RAM и vCPU для следующего профиля.
{% endstep %}

{% step %}

#### Проверьте нагрузку PostgreSQL

Выполните read-only запрос:

```bash
runuser -u postgres -- psql -X -d postgres -P pager=off -c "
SELECT
    datname,
    numbackends,
    deadlocks,
    temp_files,
    pg_size_pretty(temp_bytes) AS temp_data
FROM pg_stat_database
WHERE datname NOT IN ('template0', 'template1', 'postgres')
ORDER BY datname;
"
```

Запрос ничего не изменяет в базах данных.

`numbackends` показывает текущие подключения. `deadlocks` показывает взаимные блокировки запросов. `temp_files` и `temp_data` показывают временные файлы, созданные PostgreSQL.

Эти значения накапливаются. Для диагностики сравнивайте их до и после одинакового периода нагрузки, а не оценивайте только один результат.
{% endstep %}

{% step %}

#### Проверьте работу системы

Выполните:

```bash
/home/installer/iex-installer \
  --config /home/installer/install.yaml \
  verify --public-endpoints
```

Успешная проверка заканчивается строкой:

```
Итог installed verify: true
```

Команда проверяет системные службы, Frontend, Backend, локальные адреса, Redis, PostgreSQL, TLS, WebSocket и Планировщик задач.

{% hint style="info" %}
Эта проверка подтверждает работоспособность установленной системы и не изменяет данные или конфигурацию сервера.
{% endhint %}
{% endstep %}
{% endstepper %}

### Как оценить результаты

**Процессор.** Сравните `load average` из `uptime` с количеством vCPU из `nproc`. Кратковременный пик допустим. Если нагрузка долго остаётся выше количества vCPU и одновременно увеличивается время ответа, серверу может не хватать процессора.

**Оперативная память.** Оценивайте поле `available` в `free -h`, а не только `free`. Linux использует свободную память под кеш и освобождает её при необходимости.

**Swap.** В выводе `vmstat` оценивайте столбцы `si` и `so` со второй строки. Постоянные ненулевые значения во время замедления указывают на активный обмен данными между RAM и диском.

**Диск.** Нехватка места не исправляется профилем производительности. Учитывайте базу данных, логи, выпуски продукта и резервные копии.

**PHP-FPM.** Повторяющееся достижение `pm.max_children` может указывать на нехватку процессов, но увеличивать их можно только при наличии свободной RAM и CPU.

**PostgreSQL.** Рост временных файлов может указывать на тяжёлые операции или недостаточную память для отдельных запросов. Увеличение `work_mem` без расчёта способно, наоборот, привести к нехватке RAM.

{% hint style="info" %}
Не очищайте swap и системный кеш только ради уменьшения занятых значений. Это не устраняет причину нехватки памяти и может временно увеличить нагрузку.
{% endhint %}

## Этап 2. Выбор профиля

### Доступные профили

<table><thead><tr><th width="280.7578125">Профиль</th><th>Ресурсы сервера</th><th>Назначение</th></tr></thead><tbody><tr><td>Минимальный (<code>minimum</code>)</td><td>2 vCPU, 4 ГБ ОЗУ</td><td>Тестирование и небольшая нагрузка</td></tr><tr><td>Рекомендуемый (<code>recommended</code>)</td><td>4 vCPU, 8 ГБ ОЗУ</td><td>Большинство рабочих проектов</td></tr><tr><td>Высокая производительность (<code>high</code>)</td><td>8 vCPU, 16 ГБ ОЗУ</td><td>Высокая нагрузка на сайт, API и базу</td></tr><tr><td>Максимальная производительность (<code>maximum</code>)</td><td>от 16 vCPU, от 32 ГБ ОЗУ</td><td>Очень высокая подтверждённая нагрузка</td></tr></tbody></table>

Для выбранного профиля одновременно должны выполняться требования по vCPU и RAM. Если сервер находится между двумя профилями, используйте ближайший меньший профиль.

{% hint style="warning" %}
Сервер с 4 ГБ ОЗУ находится на нижней границе минимального профиля. Для рабочего проекта рекомендуется использовать не менее 8 ГБ ОЗУ, чтобы оставить запас для приложения, базы данных и операционной системы.
{% endhint %}

### Контрольные значения профиля

| Профиль                         | `pm.max_children` | `memory_limit` |
| ------------------------------- | ----------------- | -------------- |
| Минимальный                     | `3`               | `512M`         |
| Рекомендуемый                   | `6`               | `768M`         |
| Высокая производительность      | `12`              | `1024M`        |
| Максимальная производительность | `24`              | `1536M`        |

| Профиль                         | `shared_buffers` | Redis `maxmemory` |
| ------------------------------- | ---------------- | ----------------- |
| Минимальный                     | `512MB`          | `256mb`           |
| Рекомендуемый                   | `1024MB`         | `512mb`           |
| Высокая производительность      | `3072MB`         | `1024mb`          |
| Максимальная производительность | `6144MB`         | `2048mb`          |

Если значения относятся к разным профилям, конфигурация изменялась вручную или профиль применён не полностью. Не увеличивайте оставшиеся параметры отдельно.

## Этап 3. Подготовка и применение профиля

### Работающий сервер

{% stepper %}
{% step %}

#### Подтвердите необходимость изменения

Сохраните результаты диагностики во время проблемы. Не переходите на следующий профиль только потому, что сервер работает давно или swap содержит занятые данные.
{% endstep %}

{% step %}

#### Увеличьте ресурсы сервера

Если следующему профилю требуется больше vCPU или RAM, сначала измените характеристики сервера у провайдера и дождитесь его полного запуска.

Проверьте новые ресурсы:

```bash
nproc
free -h
```

Не применяйте более высокий профиль до фактического появления необходимых ресурсов.
{% endstep %}

{% step %}

#### Проверьте состояние обновления

Выполните:

```bash
/usr/local/sbin/iex-updater status
```

Не изменяйте серверные конфигурации во время выполняющегося обновления.
{% endstep %}

{% step %}

#### Создайте резервную копию данных

Запустите штатное резервное копирование:

```bash
systemctl start iex-backup.service

systemctl show iex-backup.service \
  -p Result -p ExecMainStatus --no-pager
```

Продолжайте только при следующих значениях:

```
Result=success
ExecMainStatus=0
```

{% endstep %}

{% step %}

#### Сохраните управляемые конфигурации

Выполните:

```bash
backup_dir="/root/iex-performance-backup-$(date -u +%Y%m%dT%H%M%SZ)"

php_pool="$(find /etc/php -type f \
  -path '*/fpm/pool.d/iexexchanger.conf' -print -quit)"

postgresql_conf="$(find /etc/postgresql -type f \
  -path '*/main/conf.d/iexexchanger.conf' -print -quit)"

test -n "$php_pool"
test -n "$postgresql_conf"

install -d -m 700 "$backup_dir"

cp --archive --parents \
  "$php_pool" \
  "$postgresql_conf" \
  /etc/redis/redis.conf \
  /etc/nginx/snippets/iexexchanger/routes-backend.conf \
  /etc/nginx/snippets/iexexchanger/routes-frontend.conf \
  /etc/sysctl.d/99-iexexchanger-postgresql.conf \
  /home/installer/install.yaml \
  "$backup_dir"

(
  cd "$backup_dir"

  find etc home -type f -print0 \
    | sort -z \
    | xargs -0 sha256sum > SHA256SUMS

  sha256sum --check SHA256SUMS
)

chmod -R go-rwx "$backup_dir"
printf 'Backup: %s\n' "$backup_dir"
```

Каждый файл должен получить статус `OK`. Сохраните выведенный путь до завершения проверки нового профиля.
{% endstep %}

{% step %}

#### Согласуйте применение профиля

На работающем сервере профиль необходимо менять как единый набор параметров PHP-FPM, PHP, PostgreSQL, Redis, Nginx, swap и Huge Pages.

В текущем Installer отдельная пользовательская команда для такой операции отсутствует. Передайте технической поддержке:

* выбранный профиль;
* количество vCPU и RAM после расширения сервера;
* путь к сохранённым конфигурациям;
* результат полной проверки Installer;
* вывод `uptime`, `free -h` и `vmstat 1 10` во время проблемы;
* найденные OOM-события или сообщения о `pm.max_children`.

Не отправляйте пароль сервера, файл `.env`, ключ лицензии, пароли баз данных и содержимое `/etc/iexexchanger/secrets`.

{% hint style="danger" %}
Не подменяйте отсутствующую команду собственным скриптом и не запускайте `install` повторно. Изменение только одного параметра не считается применением профиля.
{% endhint %}
{% endstep %}
{% endstepper %}

### Новая установка

Во время первичной установки рекомендуется использовать автоматический выбор:

```yaml
spec:
  performance:
    profile: auto
```

Installer выберет самый высокий профиль, которому одновременно хватает vCPU и RAM.

Значения `minimum`, `recommended`, `high` и `maximum` используют только до первой установки и только при наличии соответствующих ресурсов.

{% hint style="warning" %}
Изменение `profile` в `/home/installer/install.yaml` после установки само по себе не меняет работающий сервер.
{% endhint %}

## Точные значения профилей

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

{% tabs %}
{% tab title="Минимальный" %}

### PHP-FPM, PHP и OPcache

```ini
pm = dynamic
pm.max_children = 3
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 2
pm.max_requests = 500
request_terminate_timeout = 60s

php_admin_value[memory_limit] = 512M
php_admin_value[upload_max_filesize] = 200M
php_admin_value[post_max_size] = 220M
php_admin_value[max_execution_time] = 60
php_admin_value[max_input_time] = 60
php_admin_value[max_input_vars] = 10000
php_admin_value[realpath_cache_size] = 4096K
php_admin_value[realpath_cache_ttl] = 600

php_admin_flag[opcache.enable] = on
php_admin_value[opcache.memory_consumption] = 128
php_admin_value[opcache.interned_strings_buffer] = 16
php_admin_value[opcache.max_accelerated_files] = 20000
php_admin_value[opcache.max_wasted_percentage] = 10
php_admin_flag[opcache.save_comments] = on
php_admin_flag[opcache.validate_timestamps] = on
php_admin_value[opcache.revalidate_freq] = 2
php_admin_value[opcache.jit] = off
php_admin_value[opcache.jit_buffer_size] = 0
```

### PostgreSQL

```conf
shared_memory_type = 'mmap'
huge_pages = 'try'
huge_page_size = 0
shared_buffers = '512MB'
effective_cache_size = '1536MB'
work_mem = '4MB'
maintenance_work_mem = '128MB'
autovacuum_work_mem = '64MB'
max_connections = 50
min_wal_size = '512MB'
max_wal_size = '2048MB'
checkpoint_completion_target = 0.9
wal_compression = on
autovacuum = on
fsync = on
full_page_writes = on
synchronous_commit = on
```

### Redis, Nginx и swap

```conf
# Redis
maxmemory 256mb
maxmemory-policy noeviction

# Nginx для Frontend и Backend
client_max_body_size 220m;
```

Автоматический размер swap при новой установке: `2048MiB`.
{% endtab %}

{% tab title="Рекомендуемый" %}

### PHP-FPM, PHP и OPcache

```ini
pm = dynamic
pm.max_children = 6
pm.start_servers = 2
pm.min_spare_servers = 1
pm.max_spare_servers = 3
pm.max_requests = 500
request_terminate_timeout = 120s

php_admin_value[memory_limit] = 768M
php_admin_value[upload_max_filesize] = 200M
php_admin_value[post_max_size] = 220M
php_admin_value[max_execution_time] = 120
php_admin_value[max_input_time] = 120
php_admin_value[max_input_vars] = 20000
php_admin_value[realpath_cache_size] = 8192K
php_admin_value[realpath_cache_ttl] = 600

php_admin_flag[opcache.enable] = on
php_admin_value[opcache.memory_consumption] = 256
php_admin_value[opcache.interned_strings_buffer] = 32
php_admin_value[opcache.max_accelerated_files] = 50000
php_admin_value[opcache.max_wasted_percentage] = 10
php_admin_flag[opcache.save_comments] = on
php_admin_flag[opcache.validate_timestamps] = on
php_admin_value[opcache.revalidate_freq] = 2
php_admin_value[opcache.jit] = off
php_admin_value[opcache.jit_buffer_size] = 0
```

### PostgreSQL

```conf
shared_memory_type = 'mmap'
huge_pages = 'try'
huge_page_size = 0
shared_buffers = '1024MB'
effective_cache_size = '3072MB'
work_mem = '4MB'
maintenance_work_mem = '256MB'
autovacuum_work_mem = '128MB'
max_connections = 75
min_wal_size = '1024MB'
max_wal_size = '4096MB'
checkpoint_completion_target = 0.9
wal_compression = on
autovacuum = on
fsync = on
full_page_writes = on
synchronous_commit = on
```

### Redis, Nginx и swap

```conf
# Redis
maxmemory 512mb
maxmemory-policy noeviction

# Nginx для Frontend и Backend
client_max_body_size 220m;
```

Автоматический размер swap при новой установке: `4096MiB`.
{% endtab %}

{% tab title="Высокая производительность" %}

### PHP-FPM, PHP и OPcache

```ini
pm = dynamic
pm.max_children = 12
pm.start_servers = 4
pm.min_spare_servers = 2
pm.max_spare_servers = 6
pm.max_requests = 500
request_terminate_timeout = 180s

php_admin_value[memory_limit] = 1024M
php_admin_value[upload_max_filesize] = 500M
php_admin_value[post_max_size] = 520M
php_admin_value[max_execution_time] = 180
php_admin_value[max_input_time] = 180
php_admin_value[max_input_vars] = 30000
php_admin_value[realpath_cache_size] = 16384K
php_admin_value[realpath_cache_ttl] = 600

php_admin_flag[opcache.enable] = on
php_admin_value[opcache.memory_consumption] = 512
php_admin_value[opcache.interned_strings_buffer] = 64
php_admin_value[opcache.max_accelerated_files] = 100000
php_admin_value[opcache.max_wasted_percentage] = 10
php_admin_flag[opcache.save_comments] = on
php_admin_flag[opcache.validate_timestamps] = on
php_admin_value[opcache.revalidate_freq] = 2
php_admin_value[opcache.jit] = off
php_admin_value[opcache.jit_buffer_size] = 0
```

### PostgreSQL

```conf
shared_memory_type = 'mmap'
huge_pages = 'try'
huge_page_size = 0
shared_buffers = '3072MB'
effective_cache_size = '8192MB'
work_mem = '8MB'
maintenance_work_mem = '512MB'
autovacuum_work_mem = '256MB'
max_connections = 100
min_wal_size = '1024MB'
max_wal_size = '8192MB'
checkpoint_completion_target = 0.9
wal_compression = on
autovacuum = on
fsync = on
full_page_writes = on
synchronous_commit = on
```

### Redis, Nginx и swap

```conf
# Redis
maxmemory 1024mb
maxmemory-policy noeviction

# Nginx для Frontend и Backend
client_max_body_size 520m;
```

Автоматический размер swap при новой установке: `8192MiB`.
{% endtab %}

{% tab title="Максимальный" %}

### PHP-FPM, PHP и OPcache

```ini
pm = dynamic
pm.max_children = 24
pm.start_servers = 8
pm.min_spare_servers = 4
pm.max_spare_servers = 12
pm.max_requests = 500
request_terminate_timeout = 300s

php_admin_value[memory_limit] = 1536M
php_admin_value[upload_max_filesize] = 1000M
php_admin_value[post_max_size] = 1050M
php_admin_value[max_execution_time] = 300
php_admin_value[max_input_time] = 300
php_admin_value[max_input_vars] = 50000
php_admin_value[realpath_cache_size] = 32768K
php_admin_value[realpath_cache_ttl] = 600

php_admin_flag[opcache.enable] = on
php_admin_value[opcache.memory_consumption] = 512
php_admin_value[opcache.interned_strings_buffer] = 64
php_admin_value[opcache.max_accelerated_files] = 100000
php_admin_value[opcache.max_wasted_percentage] = 10
php_admin_flag[opcache.save_comments] = on
php_admin_flag[opcache.validate_timestamps] = on
php_admin_value[opcache.revalidate_freq] = 2
php_admin_value[opcache.jit] = off
php_admin_value[opcache.jit_buffer_size] = 0
```

### PostgreSQL

```conf
shared_memory_type = 'mmap'
huge_pages = 'try'
huge_page_size = 0
shared_buffers = '6144MB'
effective_cache_size = '18432MB'
work_mem = '16MB'
maintenance_work_mem = '1024MB'
autovacuum_work_mem = '512MB'
max_connections = 150
min_wal_size = '2048MB'
max_wal_size = '12288MB'
checkpoint_completion_target = 0.9
wal_compression = on
autovacuum = on
fsync = on
full_page_writes = on
synchronous_commit = on
```

### Redis, Nginx и swap

```conf
# Redis
maxmemory 2048mb
maxmemory-policy noeviction

# Nginx для Frontend и Backend
client_max_body_size 1050m;
```

Автоматический размер swap при новой установке: `8192MiB`.
{% endtab %}
{% endtabs %}

{% hint style="info" %}
Размер swap относится к автоматическому расчёту при новой установке с `sizeMiB: 0`. Если на сервере уже существует достаточный swap, Installer может сохранить его. Swap не заменяет оперативную память.
{% endhint %}

## Что означают основные параметры

### PHP и PHP-FPM

**`memory_limit`** ограничивает память одного PHP-запроса. Увеличение значения не ускоряет запрос и не устраняет утечку памяти.

**`upload_max_filesize`** ограничивает размер одного файла, а **`post_max_size`** — размер всего POST-запроса. `post_max_size` должен быть больше `upload_max_filesize`.

**`max_execution_time`** разрешает запросу выполняться дольше, но не делает его быстрее.

**`pm.max_children`** ограничивает количество одновременных PHP-процессов. Завышенное значение позволяет создать больше процессов, чем сервер способен удержать в RAM.

### OPcache

**`opcache.memory_consumption`** задаёт память для скомпилированного PHP-кода. Увеличение сверх фактического размера кеша не даёт дополнительного ускорения.

**`opcache.max_accelerated_files`** ограничивает количество PHP-файлов в кеше.

Во всех профилях проверка изменений файлов включена, а JIT выключен:

```ini
php_admin_flag[opcache.validate_timestamps] = on
php_admin_value[opcache.revalidate_freq] = 2
php_admin_value[opcache.jit] = off
php_admin_value[opcache.jit_buffer_size] = 0
```

### PostgreSQL

**`shared_buffers`** задаёт собственный кеш PostgreSQL. База также использует файловый кеш операционной системы, поэтому ей нельзя передавать всю RAM сервера.

**`effective_cache_size`** сообщает планировщику предполагаемый доступный кеш, но не резервирует этот объём памяти.

**`work_mem`** ограничивает память одной операции сортировки или хеширования. Один запрос может использовать несколько таких операций.

**`max_connections`** ограничивает количество подключений. Большое значение не ускоряет PostgreSQL и увеличивает возможное потребление памяти.

**`min_wal_size`** и **`max_wal_size`** управляют объёмом WAL между контрольными точками. Больший `max_wal_size` требует дополнительного места на диске.

Следующие параметры защищают подтверждённые данные и должны оставаться включёнными:

```conf
autovacuum = on
fsync = on
full_page_writes = on
synchronous_commit = on
```

{% hint style="danger" %}
Не отключайте `fsync`, `full_page_writes` или `synchronous_commit` ради скорости. После сбоя сервера это может привести к потере подтверждённых данных.
{% endhint %}

### Redis, Nginx и swap

**`maxmemory`** ограничивает память Redis. Политика `noeviction` запрещает Redis автоматически удалять прикладные ключи при достижении лимита.

**`client_max_body_size`** в Nginx согласован с `post_max_size` PHP. Изменение только одного из этих параметров создаёт разные ограничения на загрузку файлов.

**Swap** защищает сервер от мгновенного завершения процессов при кратковременном пике памяти, но работает значительно медленнее RAM. Постоянная активность `si` и `so` означает, что серверу требуется больше оперативной памяти или меньший профиль.

## Этап 4. Проверка после настройки

### Проверьте конфигурации и службы

Выполните:

```bash
sudo -i

nginx -t

php_fpm_binary="$(find /usr/sbin -maxdepth 1 -type f \
  -name 'php-fpm*' -print | sort -V | tail -n 1)"

test -n "$php_fpm_binary"
"$php_fpm_binary" -t

pg_isready -h 127.0.0.1 -p 5432
systemctl --failed --no-legend --no-pager
```

Ожидаемый результат:

* Nginx и PHP-FPM сообщают об успешной проверке конфигурации;
* PostgreSQL отвечает `accepting connections`;
* список упавших служб пуст.

### Проверьте применённый профиль

Повторите команды из раздела «Проверьте текущий профиль».

Значения PHP-FPM, PHP, PostgreSQL, Redis и Nginx должны относиться к одному выбранному профилю.

Проверьте Huge Pages:

```bash
runuser -u postgres -- psql -AtXqc "SHOW huge_pages_status"
sysctl -n vm.nr_hugepages
```

PostgreSQL может вывести `on` или `off`. При политике `huge_pages = 'try'` значение `off` означает безопасный возврат к обычным страницам памяти, если ядро не смогло выделить полный объём Huge Pages.

### Проверьте iEXExchanger

Выполните:

```bash
/home/installer/iex-installer \
  --config /home/installer/install.yaml \
  verify --public-endpoints
```

Проверьте сайт и административную панель:

```bash
curl -L -sS -o /dev/null -w '%{http_code}\n' https://ваш_домен
curl -sS -o /dev/null -w '%{http_code}\n' https://app.ваш_домен
```

Оба запроса должны вернуть код `200`.

### Проверьте сервер под обычной нагрузкой

Повторите:

```bash
uptime
free -h
vmstat 1 10

journalctl -k --since "-1 hour" --no-pager \
  | grep -Ei 'out of memory|oom-kill|killed process'
```

Проверьте, что сервер не создаёт OOM-события, не выполняет постоянный обмен со swap и не держит нагрузку процессора выше количества доступных vCPU продолжительное время.

{% hint style="success" %}
Настройка считается проверенной, если значения относятся к одному профилю, конфигурации проходят проверку, упавших служб нет, Installer выводит `Итог installed verify: true`, оба публичных адреса возвращают `200`, а во время обычной нагрузки не появляются OOM-события и постоянный обмен со swap.
{% endhint %}

***

## Если возникла проблема

### PHP-FPM достигает `pm.max_children`

Проверьте повторяющиеся сообщения:

```bash
grep -Ei 'max_children|server reached' \
  /var/log/iexexchanger/php-fpm-error.log 2>/dev/null \
  | tail -n 50
```

Если сообщения совпадают по времени с замедлением, проверьте наличие ресурсов следующего профиля. Не увеличивайте `pm.max_children` отдельно от остальных параметров.

### Swap занят после завершения нагрузки

Выполните:

```bash
vmstat 1 10
```

Если со второй строки `si` и `so` остаются около нуля, активного обмена со swap нет. Очищать swap не требуется.

### После настройки сайт отвечает 502

Определите службу PHP-FPM и проверьте журнал:

```bash
php_fpm_unit="$(systemctl list-units --type=service --all \
  'php*-fpm.service' --no-legend | awk 'NR == 1 {print $1}')"

systemctl status nginx "$php_fpm_unit" --no-pager
journalctl -u nginx -u "$php_fpm_unit" -n 100 --no-pager
```

Не перезапускайте службы многократно. Передайте журнал и путь к сохранённым конфигурациям технической поддержке.

### PostgreSQL не запускается

Проверьте состояние и журнал:

```bash
systemctl status postgresql --no-pager
journalctl -u postgresql -n 100 --no-pager
```

Не отключайте `fsync`, `full_page_writes`, `synchronous_commit` или `autovacuum`. Используйте сохранённые конфигурации для проверенного возврата предыдущего профиля.

### Публичные адреса не отвечают, а локальная проверка успешна

Причина может находиться в DNS, CDN или маршруте между публичным адресом и сервером. Используйте отдельные результаты `Публичный` и `Origin` в отчёте Installer. Если Origin отвечает успешно, сначала проверьте DNS и proxy, а не увеличивайте профиль.
