---
title: Кеширование и CDN для OTT-раздачи
url: https://doc2.pstreamer.tv/ru/manual/extras/ott_caching.html
lang: ru
product: Perfect Streamer
version: 2.0.2.362
---

# Кеширование и CDN для OTT-раздачи

Приложение для эксплуатации крупных инсталляций: как устроено кеширование OTT-ответов Perfect Streamer и как поставить перед узлом кеширующий reverse proxy или CDN. Режимы раздачи, форматы URL и авторизация описаны в основном разделе [OTT и DVR](../streamer/ott_dvr.md#streamer-ott-dvr).

Сервер формирует ответы трёх категорий, различающихся сроком жизни содержимого и пригодностью для кеширования промежуточными узлами (reverse proxy, CDN, клиентский кеш).

## 1. Модель кеширования

### 1.1. Ресурсы и HTTP-заголовки

| Ресурс | URL | Content-Type | Cache-Control |
| --- | --- | --- | --- |
| TS-сегмент (HLS) | `/h<sess>/<keyHex>.ts` | `video/mp2t` | `public, max-age=60, immutable` |
| VTT-сегмент (субтитры) | `/h<sess>/sub/<pid>/<keyHex>.vtt` | `text/vtt; charset=utf-8` | `public, max-age=60, immutable` |
| fMP4-сегмент (DASH / LL-HLS) | `/h<sess>/init.mp4`, `/h<sess>/<key\|N>.m4s` | `video/mp4` | `public, max-age=60, immutable` |
| DASH MPD | `/h<sess>/index.mpd` | `application/dash+xml; charset=utf-8` | `public, max-age=1` |
| HLS master | `/hls/<stream>/<login>/<pass>/index.m3u8` | `application/vnd.apple.mpegurl` | `public, max-age=1` |
| HLS media | `/h<sess>/index.m3u8`, `/h<sess>/sub/<pid>/index.m3u8` | `application/vnd.apple.mpegurl` | `public, max-age=1` |
| 302 Redirect | `/dash/<stream>/<login>/<pass>/index.mpd` | — | `no-cache, no-store` |
| Raw TS | `/http/<stream>/<login>/<pass>` | `video/mp2t` | не задан; не кешируется |

### 1.2. Характеристики сегментов

Шестнадцатеричный идентификатор сегмента в URL (`<keyHex>` в путях `/h<sess>/<keyHex>.ts`) формируется как CRC64 от стартового времени сегмента и ID потока и глобально уникален. URL сегмента адресует неизменное содержимое — при повторных запросах того же URL возвращается идентичный байтовый поток (пока сегмент остаётся в пределах скользящего окна).

Директива `immutable` подавляет условную ревалидацию клиентом (`If-None-Match`, `If-Modified-Since`). Значение `max-age=60` обеспечивает совместимость с типичным `timeShiftBufferDepth=40s`.

fMP4-сегменты CMAF (`.m4s`) и общий `init.mp4` для DASH / Low-Latency HLS адресуются аналогично и кешируются по той же модели (`immutable`, `max-age=60`). Частичные сегменты (parts) LL-HLS — это byte-range-запросы внутрь того же `.m4s`, поэтому отдельной записи в кеше не образуют.

### 1.3. Характеристики манифестов

`max-age=1` ограничивает верхнюю границу устаревания содержимого в кеше одной секундой. При совместном использовании с `proxy_cache_lock on` (nginx) всплески запросов к манифесту коалесцируются в один запрос на origin в секунду.

### 1.4. Вариативность содержимого

При `absPath=0` (значение по умолчанию, URL-параметра `a` нет) манифесты HLS media и DASH MPD не содержат идентификатора сессии в теле. Содержимое манифеста идентично между сессиями, принадлежащими одной (stream, param)-комбинации. Это позволяет reverse-proxy кешу переиспользовать запись между сессиями при нормализации ключа кеша.

При `absPath=1` (URL-параметр `a=1`) в теле манифеста присутствуют абсолютные URL, включающие схему, хост и идентификатор сессии. Содержимое становится специфичным для сессии, возможность кросс-сессионного переиспользования кеша отсутствует.

## 2. Поведение клиентов

| Клиент | URL обновления манифеста | Воздействие на количество сессий |
| --- | --- | --- |
| HLS-плееры по media playlist | `/h<sess>/index.m3u8` | Одна сессия на сеанс воспроизведения |
| DASH-плееры по корневому URL | `/dash/<stream>/.../index.mpd` (цикл повтора) | Обрабатывается session reuse (см. 3.2) |
| Браузерные плееры (MSE) | `/h<sess>/...` через `<Location>` / session URL | Одна сессия на сеанс воспроизведения |

## 3. Специальные механизмы

### 3.1. HTTP 302 Redirect для DASH

Запрос вида `/dash/<stream>/<login>/<pass>/index.mpd` возвращает ответ `302 Found` с заголовком `Location: /h<sess>/index.mpd`. Тело ответа пустое. Авторизация и выделение сессии выполняются на этапе обработки редиректа.

Клиенты, поддерживающие кеширование редиректа, обращаются к session URL напрямую в последующих запросах. Клиенты, не поддерживающие его, повторяют запрос редиректа. Стоимость повторной обработки редиректа ограничена проверкой аутентификации и операциями session reuse.

### 3.2. Session reuse для DASH

При обработке запроса `/dash/.../index.mpd` от того же логина к тому же потоку (с тем же признаком adaptive) сервер находит уже существующую DASH-сессию и возвращает её идентификатор повторно. Новая сессия не создаётся, слот лимита одновременных подключений не расходуется. Переиспользуются только сессии в одном режиме воспроизведения: живая сессия и VOD-сессия архива (параметры `t`/`d`/`epg`) не объединяются.

Применяется только к DASH. Для HLS отдельный механизм reuse не требуется: HLS-клиенты обновляют media playlist по session-URL и не создают новую сессию на каждом обновлении.

### 3.3. Переиспользование сегментов между сессиями

Путь `/h<sess>/<keyHex>.ts` не зависит от `<sess>` при разрешении `<keyHex>` в содержимое: `<keyHex>` глобально однозначно идентифицирует TS-сегмент в рамках потока. Nginx с нормализованным cache key (обрезающим префикс `/h<sess>/`) обслуживает все запросы одного и того же `<keyHex>` из единственной записи кеша, независимо от того, какие клиенты их выдали.

Дедупликация применима только к content-addressed именам — сегментам с 16-символьным шестнадцатеричным идентификатором (`.ts`, `.m4s` с `<keyHex>`, `.vtt`). Нумерованные сегменты live-DASH (`<номер>.m4s`), `init.mp4` и манифесты уникальны лишь в рамках своей сессии — их ключ кеша должен сохранять префикс `/h<sess>/`, иначе кеш будет отдавать содержимое одного потока зрителям другого. Для DASH дедупликацию манифестов между клиентами одного логина обеспечивает session reuse (см. 3.2).

## 4. Параметры запроса

| Параметр | Значение по умолчанию | Влияние |
| --- | --- | --- |
| `a` | `0` | `1` — абсолютные URL в манифестах; `0` — относительные |
| `s` | `40` | `timeShiftBufferDepth` в секундах |
| `m` | `40` | Минимальная длина окна для выдачи манифеста |
| `v` | `6` для режимов OTT, `3` для Peering / HLS | `#EXT-X-VERSION` в HLS (игнорируется DASH); явное значение в URL переопределяет значение по умолчанию |
| `h3` | отсутствует (off) | opt-in на HTTP/3 (QUIC): заставляет сервер выдать `Alt-Svc` в ответе; sticky на session-URL. См. [HTTP/3 (QUIC)](../streamer/ott_dvr.md#streamer-ott-http3) |

Изменение параметра через query string обновляет сохранённые в сессии значения при её следующем переоткрытии. Параметры воспроизведения архива `t`, `d` и `epg` описаны в [Воспроизведение архива (VOD)](../streamer/ott_dvr.md#streamer-dvr-vod).

## 5. Нагрузочные характеристики

Нагрузка на origin масштабируется с числом одновременно наблюдаемых различных потоков. Увеличение числа клиентов, наблюдающих один и тот же поток, не увеличивает количество запросов к origin при наличии reverse-proxy кеша и нормализованного cache key.

| Сценарий | Частота origin-запросов (реф.) |
| --- | --- |
| 1 клиент на поток X | MPD: 0.4 req/s, segment: 0.2 req/s |
| N клиентов на один поток X (кеш включён) | MPD: 1 req/s, segment: 0.2 req/s |
| N DASH-клиентов в режиме повтора на одном потоке | MPD: 1 req/s (с `proxy_cache_lock`) |
| N клиентов на N различных потоков | MPD: 0.4·N req/s, segment: 0.2·N req/s |

Сегменты дедуплицируются глобально по content-addressed именам; дедупликацию манифестов между клиентами обеспечивают session reuse (DASH) и кеш в пределах сессии.

## 6. Nginx как кеширующий reverse proxy

### 6.1. Базовая конфигурация

```nginx
proxy_cache_path /var/cache/nginx/pss_segments
    levels=1:2 keys_zone=pss_segments:100m
    max_size=20g inactive=30m use_temp_path=off;

proxy_cache_path /var/cache/nginx/pss_manifests
    levels=1:2 keys_zone=pss_manifests:10m
    max_size=256m inactive=5m use_temp_path=off;

upstream pss_backend {
    server 127.0.0.1:43972;
    keepalive 64;
}

map $uri $pss_cache_key {
    "~^/h[0-9a-f]{16}(?<tail>(/[0-9]+)?/[0-9a-f]{16}\.(ts|m4s)|/sub/[0-9]+/[0-9a-f]{16}\.vtt)$"  "stream:$tail";
    default  $uri;
}

server {
    listen 80;
    server_name stream.example.com;

    location ~* "^/h[0-9a-f]{16}(/[0-9]+|/sub/[0-9]+)?/([0-9a-f]+\.(ts|m4s|vtt)|init\.mp4)$" {
        proxy_cache               pss_segments;
        proxy_cache_key           $pss_cache_key;
        proxy_cache_valid         200 60s;
        proxy_cache_valid         404 403 0s;
        proxy_cache_lock          on;
        proxy_cache_use_stale     updating error timeout;
        proxy_cache_revalidate    on;
        proxy_ignore_headers      Vary;
        add_header                X-Cache-Status $upstream_cache_status;

        proxy_pass                http://pss_backend;
        proxy_http_version        1.1;
        proxy_set_header          Connection "";
        proxy_buffering           on;
    }

    location ~* "(^/h[0-9a-f]{16}(/[0-9]+|/sub/[0-9]+)?/index\.(m3u8|mpd)$|^/(hls|dash|llhls)/.*\.(m3u8|mpd)$)" {
        proxy_cache               pss_manifests;
        proxy_cache_key           $pss_cache_key;
        proxy_cache_valid         200 1s;
        proxy_cache_valid         404 403 0s;
        proxy_cache_lock          on;
        proxy_cache_lock_timeout  2s;
        proxy_cache_use_stale     updating;
        add_header                X-Cache-Status $upstream_cache_status;

        proxy_pass                http://pss_backend;
        proxy_http_version        1.1;
        proxy_set_header          Connection "";
    }

    location / {
        proxy_pass                http://pss_backend;
        proxy_http_version        1.1;
        proxy_set_header          Connection "";
        proxy_set_header          X-Forwarded-Proto $scheme;
        proxy_set_header          X-Forwarded-Host  $host;
        proxy_buffering           off;
        proxy_read_timeout        3600s;
    }
}
```

Порт origin в примере — порт потокового HTTP-сервера по умолчанию (43972; HTTPS — 43982). Нормализуются только content-addressed имена сегментов (см. 3.3); манифесты, `init.mp4` и нумерованные сегменты кешируются по полному URI своей сессии. Директива `proxy_ignore_headers Vary` в location сегментов оправдана: сервер сопровождает OTT-ответы заголовком `Vary: Origin`, и без неё кеш делился бы на варианты по значению Origin клиента (см. 7).

### 6.2. Назначение директив

| Директива | Назначение |
| --- | --- |
| `proxy_cache_lock on` | Сериализует выполнение upstream-запросов при одновременных cache miss по одному ключу |
| `proxy_cache_use_stale updating` | Возвращает устаревшую копию параллельным запросам в период обновления кеша |
| `proxy_cache_revalidate on` | Использует `If-Modified-Since` при cache miss с сохранённой копией |
| `proxy_cache_valid 404 403 0s` | Запрещает кеширование ошибок авторизации и 404 |
| `keepalive 64` в upstream | Поддерживает пул persistent-соединений к origin |
| `proxy_buffering on` | Для сегментов; включает буферизацию ответа в nginx |
| `proxy_buffering off` | Для раздела `/`; отключает буферизацию (raw streaming) |

### 6.3. Расчёт `max_size` кеша сегментов

Ориентировочное значение: `bitrate × timeShiftBufferDepth × distinct_streams × 2`

Пример: 10 потоков × 8 Мбит/с × 40 с × 2 ≈ 800 МБ. Рекомендуется задать запас 10x для учёта вариативности битрейта.

### 6.4. TLS-терминация

Сервер Perfect Streamer принимает соединения на портах HTTP и HTTPS. При TLS-терминации на nginx upstream использует порт HTTP. Пересылка заголовков `X-Forwarded-Proto` и `X-Forwarded-Host` обязательна для корректного формирования абсолютных URL при `absPath=1`.

```nginx
server {
    listen 443 ssl http2;
    server_name stream.example.com;

    ssl_certificate           /etc/letsencrypt/live/stream.example.com/fullchain.pem;
    ssl_certificate_key       /etc/letsencrypt/live/stream.example.com/privkey.pem;
    ssl_protocols             TLSv1.2 TLSv1.3;
    ssl_session_cache         shared:SSL:10m;
    ssl_session_timeout       1d;

    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

    location ... {
        proxy_pass                http://pss_backend;
        proxy_set_header          X-Forwarded-Proto https;
        proxy_set_header          X-Forwarded-Host  $host;
        proxy_set_header          Host              $host;
        # + caching directives from 6.1
    }
}

server {
    listen 80;
    server_name stream.example.com;
    return 301 https://$host$request_uri;
}
```

При HTTPS между nginx и origin применяются директивы `proxy_ssl_verify`, `proxy_ssl_trusted_certificate`. Для loopback-соединений шифрование избыточно.

### 6.5. Мультихост

При обслуживании нескольких `server_name` из одного nginx-процесса `$host` добавляется в cache key для изоляции контента:

```nginx
map $uri $pss_cache_key {
    "~^/h[0-9a-f]{16}(?<tail>(/[0-9]+)?/[0-9a-f]{16}\.(ts|m4s)|/sub/[0-9]+/[0-9a-f]{16}\.vtt)$"  "$host:stream:$tail";
    default  "$host:$uri";
}
```

Размер `keys_zone` рассчитывается как 8000 ключей/MB. Для мультихост-инсталляций с тысячами потоков рекомендуется `keys_zone=...:300m` или выше.

## 7. Клиентское кеширование

`Cache-Control: immutable` обрабатывается современными браузерами. Клиентский кеш возвращает сегмент без условного запроса при повторном обращении (в том числе при обратном seek в пределах буфера плеера).

Service Workers могут применять стратегию `cache-first` на основании содержимого Cache-Control. DASH-плееры используют MSE через `SourceBuffer`; сегмент, помещённый в буфер, остаётся доступен без повторного HTTP-запроса до выхода за границу скольжения.

Для кросс-доменных запросов сервер отдаёт `Access-Control-Allow-Origin: *` вместе с заголовком `Vary: Origin, Access-Control-Request-Headers`. Кеширующий прокси, уважающий Vary, делит записи на варианты по значению Origin клиента (браузерные плееры шлют Origin, консольные — нет), что снижает HIT rate. Поскольку ACAO — универсальный «*», в location сегментов безопасно добавить `proxy_ignore_headers Vary` (см. 6.1).

## 8. Размещение через CDN

Perfect Streamer совместим с CDN в режиме pull-from-origin.

**Origin shield.** Рекомендуется размещение одного или нескольких shield-узлов между CDN edge и origin для снижения частоты запросов на origin при глобальном распределении клиентов.

**Purge.** Content-addressed сегменты не требуют purge. При изменении метаданных потока (кодек, разрешение) манифесты обновляются в течение `max-age=1` без явного purge.

**Cache warming.** При ожидаемом росте нагрузки на конкретный поток допустим прогрев CDN с нескольких географических точек до начала трансляции.

**Геораспределение.** Сегменты (`max-age=60`) хорошо подходят для географически распределённого кеширования. Манифесты (`max-age=1`) допускают задержку доставки до одной секунды — приемлемо для live-вещания без низкой задержки.

## 9. Мониторинг

### 9.1. `X-Cache-Status`

Добавление `add_header X-Cache-Status $upstream_cache_status;` в каждый location с кешированием. Значения:

| Значение | Описание |
| --- | --- |
| `HIT` | Ответ из кеша |
| `MISS` | В кеше отсутствовал, получен от origin и сохранён |
| `EXPIRED` | Просрочен, обновлён |
| `UPDATING` | Отдана stale-копия параллельному запросу во время обновления |
| `STALE` | `use_stale` вернул просроченную копию (origin недоступен) |
| `REVALIDATED` | Origin вернул 304 Not Modified |
| `BYPASS` | Сработал `proxy_cache_bypass` |

### 9.2. Формат access-log

```nginx
log_format pss_cache '$remote_addr $status $request_method "$request" '
                     '$body_bytes_sent rt=$request_time ut=$upstream_response_time '
                     'cache=$upstream_cache_status key=$pss_cache_key';

server {
    access_log /var/log/nginx/pss.log pss_cache;
}
```

### 9.3. Метрики

Модуль `nginx-vts` экспортирует метрики per-zone в формате Prometheus:

```
GET /status/format/prometheus
```

Рекомендуемые пороги для алертов:

| Метрика | Порог | Возможная причина |
| --- | --- | --- |
| Segment HIT rate | < 90% за 5 минут | Нарушена нормализация cache key; малый `max_size` |
| Manifest MISS rate | > 50% за 1 минуту | `proxy_cache_lock` не сериализует запросы |
| Upstream response time p95 | > 500 мс за 1 минуту | Перегрузка origin |
| Cache zone fill | > 90% за 10 минут | Приближение к `max_size`, планируется LRU-eviction |

Качество доставки на стороне узла видно по метрикам сессий на экране «Клиенты» ([Клиенты](../webui/monitor.md#webui-clients)).

## 10. Диагностика

| Симптом | Вероятная причина | Решение |
| --- | --- | --- |
| Segment HIT rate низкий | `Vary: Origin` делит кеш на варианты; нарушение нормализации в `map` | Добавить `proxy_ignore_headers Vary` в location сегментов; проверить regex в директиве `map` |
| 404 на сегментах после выхода из окна | Закешированный 404 при сегменте, выпавшем из sliding window | Добавить `proxy_cache_valid 404 0s` в location segments |
| Задержка playback start 2–5 с | `proxy_cache_lock_timeout` превышает target latency | Снизить до 1–2 с; включить `proxy_cache_use_stale updating` |
| Manifest не обновляется | задан `proxy_ignore_headers Cache-Control`, и действует `proxy_cache_valid` с большим TTL | Явно указать `proxy_cache_valid 200 1s` либо убрать игнорирование заголовков |
| Рост TIME_WAIT на upstream | Отсутствует `keepalive` в upstream-блоке | Добавить `keepalive 64`, `proxy_http_version 1.1`, `proxy_set_header Connection ""` |
| 403 на `/dash/.../<segment>.m4s` от консольных клиентов | Клиент разрешает относительные URL от pre-redirect URL | Сервер выдаёт `<BaseURL>` с абсолютным путём; совместимо в текущей сборке |
| Рывки воспроизведения, частые ребуферы у удалённых клиентов | Низкий эффективный throughput TCP из-за slow start и idle restart при больших RTT (300 мс и выше) | Тюнинг сетевого стека Linux на origin: см. 10.1 |

### 10.1. TCP-тюнинг origin для high-RTT клиентов

Проблема проявляется у клиентов с большим RTT до origin (например, 300 мс и выше) при битрейте потока, близком к пропускной способности канала. Симптомы в плеере — частые ребуферы и разрывы; на сервере клиент при этом выглядит нормально, ошибок нет.

Причина:

- **TCP slow start.** Каждое новое TCP-соединение начинает с congestion window около 14 КБ и наращивает его за несколько RTT. При RTT 300 мс выход на полное окно занимает 2–3 секунды. За это время HLS/DASH-сегмент длительностью 5 с (4–6 МБ) скачивается заметно медленнее реального времени.
- **TCP idle restart.** Между запросами сегментов клиент по HLS pull-модели делает паузу 4–5 с. По умолчанию ядро Linux после такой паузы сбрасывает congestion window соединения обратно к initial cwnd (поведение `net.ipv4.tcp_slow_start_after_idle=1`). В результате при следующем GET keep-alive-соединение начинает передачу с медленного старта заново — даже на уже разогретой сессии.

Дополнительно ситуацию усугубляет то, что congestion control CUBIC по умолчанию плохо переносит длинные RTT и пакетные потери на промежуточных участках сети.

Решение — два sysctl-параметра на origin:

```bash
# Keep congestion window across idle pauses inside keep-alive sessions.
sysctl -w net.ipv4.tcp_slow_start_after_idle=0

# Use BBR instead of CUBIC: better behaviour on long-RTT paths
# with mild packet loss; paces sending instead of bursting.
modprobe tcp_bbr
sysctl -w net.ipv4.tcp_congestion_control=bbr
```

Для постоянного применения:

```bash
cat > /etc/sysctl.d/99-pss-net.conf <<EOF
net.ipv4.tcp_slow_start_after_idle = 0
net.ipv4.tcp_congestion_control    = bbr
EOF
sysctl --system
```

Главный эффект даёт первый параметр (`tcp_slow_start_after_idle=0`) — он напрямую устраняет повторный slow start между сегментными запросами в одном keep-alive-соединении. Второй (BBR) даёт дополнительную устойчивость и применяется ко всем новым соединениям. Тюнинг не требует перезапуска Perfect Streamer. К клиентам HTTP/3 (QUIC) эти параметры не относятся: QUIC работает поверх UDP с собственным управлением перегрузкой.

## 11. Безопасность

### 11.1. Session URL

URL формата `/h<sess>/...` выполняет функцию сессионного токена — не требует повторной аутентификации. Срок жизни ограничен таймаутом неактивности 60 секунд; при отсутствии активности сессия удаляется автоматически.

Требования:

- HTTPS для всех OTT-путей (`/hls/`, `/dash/`, `/h<sess>/`) в production;
- Session ID в заголовке `Location` ответа 302 не кешируется (`no-cache, no-store`).

### 11.2. Rate limiting

```nginx
limit_req_zone $binary_remote_addr zone=dash_top:10m  rate=5r/s;
limit_req_zone $binary_remote_addr zone=hls_top:10m   rate=5r/s;
limit_req_zone $binary_remote_addr zone=llhls_top:10m rate=5r/s;

server {
    location /dash/ {
        limit_req zone=dash_top burst=20 nodelay;
        proxy_pass http://pss_backend;
    }
    location /hls/ {
        limit_req zone=hls_top burst=20 nodelay;
        proxy_pass http://pss_backend;
    }
    location /llhls/ {
        limit_req zone=llhls_top burst=20 nodelay;
        proxy_pass http://pss_backend;
    }
}
```

Session URL (`/h<sess>/`) не требует rate limiting — обработка дешёвая, ответы кешируются.

### 11.3. Кеширование ответов с ошибками

```nginx
proxy_cache_valid 200 60s;
proxy_cache_valid 301 302 0s;
proxy_cache_valid 404 403 0s;
proxy_cache_valid any 1s;
```

Запрещает кеширование редиректов (уникальный sess в Location) и ответов с ошибками авторизации или отсутствия ресурса.

### 11.4. Ограничение сетевого доступа к origin

Порт потокового HTTP-сервера (по умолчанию 43972; 43982 для HTTPS) должен быть закрыт для внешнего трафика. Допустимые конфигурации:

1. Bind Perfect Streamer на `127.0.0.1` (при локальном nginx)
2. Firewall-правило:

```
iptables -A INPUT -p tcp -m multiport --dports 43972,43982 ! -s 10.0.0.0/8 -j DROP
```

## 12. Интеграция с middleware

### 12.1. Модель prefix-login

Perfect Streamer поддерживает делегирование идентификации пользователя middleware-системе через механизм prefix-login — встроенную альтернативу полной интеграции с внешним биллингом (учётные записи, проверяемые внешней системой, настраиваются на экране «Пользователи / Логины», вкладка «Внешние (биллинг)», [Пользователи / Логины](../webui/configure.md#webui-users)).

У локального логина включается признак префикса, после чего сервер принимает URL с логином вида `<prefix><идентификатор_подписчика>`:

```
/dash/test1/sub42/xxx/index.mpd
/hls/test1/sub43/xxx/index.m3u8
```

Здесь `sub` — настроенный логин-префикс, а `42`/`43` — идентификаторы подписчиков middleware; пароль общий.

### 12.2. Статистика по подписчикам

В списке клиентов каждая сессия несёт и конфигурационный логин, и фактический URL-логин подписчика (match-login), по которому middleware сопоставляет сессии со своими абонентами. Данные видны на экране «Клиенты» ([Клиенты](../webui/monitor.md#webui-clients)).

### 12.3. Ограничения prefix-login

- **Общий пароль.** Все подписчики prefix-пула используют одно значение пароля. Компрометация пароля предоставляет доступ к любому `<prefix><строка>`.
- **Гранулярность доступа.** Список разрешённых потоков применяется ко всему prefix-пулу. Доступ на уровне отдельного подписчика обеспечивает интеграция с внешним биллингом.
- **Ротация пароля.** Изменение пароля отключает всех активных подписчиков. Для постепенной замены требуется временное использование двух prefix-логинов.
