Глава 20 / 51
Том 3 · Разработка протоколов

vhost на практике: ферма сайтов в одном процессе

Глава 8 разобрала механизм vhost, здесь — его инженерную организацию; образец — продакшн-репозиторий home: один процесс XServer, 14 vhost, вперемешку динамические и чисто статические сайты.

Обзор

Позиционирование: место слияния тома 2 (конфигурация) и тома 3 (протоколы). Новых механизмов нет — только как собрать механизмы в ферму, пригодную для многолетней эксплуатации.

20.1 Введение: продакшн-образец

Репозиторий home (продакшн-развёртывание XServer) в реальном виде: один xs.json, один server (двойной эндпоинт 80/443), 14 vhost — сообщество разработчиков, RPA-сайты на китайском и английском, академия, блоги, ферма документации (доки XRT/XGE/XServer — чисто статические хосты с devlang=static) и тестовые сайты. У каждого динамического сайта свой скрипт и сертификаты, у статических скриптов ноль. Один процесс обслуживает всё; один reload обновляет любой отдельный сайт.

20.2 Планировка фермы

Раскладка host репозитория home (абстракция продакшна)
home/
├── xs / xs.exe / xs.json          /* хост и главный конфиг */
├── host/
│   ├── default/                   /* host_default: сайт по умолчанию */
│   │   ├── script/main.c          /*   динамический сайт: скрипт */
│   │   ├── wwwroot/  tls/  db/
│   ├── xxdevs/                    /* сайт сообщества (свой скрипт + серт) */
│   │   ├── script/main.c  wwwroot/  tls/
│   ├── xrt/                       /* сайт документации: чистая статика */
│   │   └── wwwroot/               /*   без каталога script */
│   └── ...                        /* остальные сайты той же формы */
└── tools/ dev/                    /* эксплуатация и разработка */

Что только что произошло: три решения планировки — один самодостаточный каталог на host (wwwroot/tls/script/db рядом; каталог переносится целиком); имя каталога host = идентификатор сайта (name/host в конфигурации совпадает с каталогом, отладка без сверок); статический сайт — просто «host без script» (devlang=static, форма та же).

20.3 Организация конфигурации

  • Один server забирает весь 80/443: все сайты делят эндпоинты, разводка по Host/SNI — не открывайте server на каждый сайт (управление портами уедет в файрвол)
  • Сертификаты лежат рядом с сайтом: в tls/ каждого host; таблица SNI строится по host автоматически (гл. 08/12)
  • Мультидомены перечисляются явно: "a.com;www.a.com" — точное сопоставление, без wildcards (яма из гл. 08)
  • Сайт по умолчанию — подстраховка: host_default указывает на страницу с минимальным риском (навигация / пояснение 404), не на реальный бизнес
  • Custom распределяется по сайтам: частные ручки сайта — в Custom своего host (ключи с префиксом, гл. 09)

20.4 Переиспользование и изоляция скриптов

Четырнадцать динамических сайтов = четырнадцать независимых рантаймов скриптов. Баланс переиспользования и изоляции:

  • Переиспользование — копированием modules/: подход home — копировать общие модули (ответные помощники, база, шаблоны) в нужные сайты; каждая площадка компилирует свою копию, межсайтовых конфликтов символов нет
  • Изоляция бесплатна: статики, дескрипторы базы и падения сайта заперты в своём поколении; reload сайта A не трогает сайт B (единица публикации — поколение server этого host, но разводка уровня конфигурации полностью выводит неизменённые сайты из участия)
  • Межсайтовый обмен — только по явным каналам: файловая система (db/) или запрос топологии xsServerFind — неявных глобалов нет

20.5 Контракт

  • Планировка: каталог host самодостаточен, имя каталога — идентификатор, статические сайты той же формы.
  • Эндпоинты: один server, два эндпоинта, разводка по Host/SNI.
  • Изменения: reload подаётся по host; неизменённые сайты не участвуют.

Частые ошибки

На сайте по умолчанию повесили админку
Симптом
Сканеры, бьющие по IP напрямую (без Host или со случайным), попадают в административную панель.
Причина
Весь трафик, не попавший в vhost, уходит в host_default — а это должен быть наименее чувствительный из ваших сайтов.
Новому сайту забыли сертификат
Симптом
TLS-рукопожатие нового домена проваливается или выдаёт чужой сертификат.
Причина
Каждый host на TLS-эндпоинте обязан иметь свой сертификат (таблица SNI строится по host); host с одним полем host без tls_cert/key не завершит выбор личности на 443.

Упражнения

БазовыйФерма из трёх сайтов

По планировке 20.2 соберите: сайт-навигатор по умолчанию + один статический сайт документации + один динамический (со скриптом и каталогом db).

Приёмка: три имени Host приходят каждый в свой сайт; несовпавшее — на страницу-навигатор.
ПродвинутыйГорячее обновление одного сайта

Правьте скрипт динамического сайта и подайте reload только по этому host; два остальных под непрерывной нагрузкой.

Приёмка: ноль ошибок нагрузки; в логе запись о смене поколения только целевого сайта.
ВызовМаршрут инспекции фермы

Реализуйте /status на сайте по умолчанию: перечислить все server/host в таблицу состояния (API запросов из гл. 11).

Приёмка: вывод покрывает все сайты с верными состояниями; на остальных сайтах маршрута нет.

Итоги

ТезисВывод
Образецпродакшн home: один процесс, 14 vhost, статика и динамика вперемешку
Планировкакаталог host самодостаточен; имя — идентификатор; статика той же формы
Эндпоинтыодин server забирает 80/443, разводка по Host/SNI
Переиспользованиеmodules/ копируется по сайтам; изоляция бесплатна; обмен по явным каналам
Подстраховкав host_default — контент минимального риска
API, затронутые в главе
Что дальше по xrt