AWH — ANYKS Web Hub
Собственная сетевая основа: от распределителя памяти до HTTP/3. Одна библиотека вместо сборки из четырёх десятков чужих. Написана с листа по текстам стандартов, работает на двенадцати операционных системах, измерена против эталонов своей области.
Фундамент, на котором строятся сетевые программы
Любая программа, которая общается по сети — сайт, банковское приложение, система связи, промышленный контроллер, — состоит из одних и тех же слоёв: работа с памятью, разбор данных, шифрование, протоколы обмена.
Обычно эти слои берут готовыми у разных авторов и складывают как конструктор. AWH — тот же набор слоёв, но написанный целиком нами и как единое целое: один стиль, один договор об ошибках, один способ работы с памятью на весь стек.
| Слой | Что делает | Строк |
|---|---|---|
| Сеть и движки | обмен данными с операционной системой | 476 777 |
| Кодеки | JSON, XML, YAML, TOML, INI, CSV, CEF, SysLog, ABC | 181 032 |
| Протоколы | HTTP/1, HTTP/2, HTTP/3, QUIC, SOCKS5 | 91 835 |
| Системный слой | потоки, волокна, сигналы, время, файлы | 56 237 |
| Кодировки | UTF-8, преобразования, хэши | 53 772 |
| Регулярные выражения | своя замена PCRE2 с кодогенерацией | 51 319 |
| Шифрование | ГОСТ, TLS, хранилище ключей | 48 734 |
| Числа и память | длинная арифметика, свой распределитель | 47 421 |
| Готовые узлы | DNS, NTP, ICMP, туннели, кластер, таймеры | 45 510 |
Одна деталь вместо сорока
Ниже — не оценка, а перечень: все эти библиотеки физически лежат в репозитории как эталоны для замеров и прогоняются на тех же данных, что и наш код. Замещение доказано числами, а не заявлено.
Протоколы
Разбор данных
Основание
Внешними остаются только библиотеки сжатия — zlib, zstd, lz4, brotli, lzma, bz2. Они узкие, взаимозаменяемые и не несут ни протокольной логики, ни криптографии.
Цена сборки из чужих деталей
Дороже
Сорок библиотек — сорок стилей, типов и правил владения памятью. Каждое обновление безопасности одной из них — отдельная проверка совместимости со всеми остальными. Сорок лицензий, часть — с ограничениями на распространение.
Медленнее
Данные копируются между слоями, потому что у соседних библиотек несовместимые представления. Одна блокирует поток, другая нет; одна выделяет память, другая требует чужую. Ошибка на стыке двух библиотек — ничья.
Рискованнее
Обновления приходят извне и могут прекратиться в любой момент. Проверить сорок чужих кодовых баз на закладки нереально. Уязвимость в одной библиотеке — уязвимость во всём продукте, а срок исправления определяет чужой человек.
Единая основа: разбор протокола смотрит прямо во входной буфер без копий, один журнал решений и одна система проверок на весь стек, а ошибку в любом слое мы чиним сами и в свой срок.
HTTP/3 и HTTP/2: доля от эталонной реализации
Сто процентов — уровень эталона: nghttp3 и nghttp2, на которых работает значительная часть интернета. Правее черты — мы быстрее. Снято измерителями обеих сторон на одной машине, сборка Release.
HTTP/3 · против nghttp3
HTTP/2 · против nghttp2
Кодирование заголовков — известная слабость обеих реализаций: разобрана по шагам, семь правок уже дали прирост, остаток измерен. Отчёты — benchmark/proto/*/COMPARISON.md в репозитории.
Предсказуемость важнее пиковой скорости
Распределитель памяти вызывают миллионы раз в секунду. Мы не самые быстрые, но одинаковы на всех системах, а соперники разбегаются на два-три порядка. Для связи, встраиваемой техники и систем реального времени равномерность дороже рекорда: она позволяет считать худший случай, а не средний.
Наносекунд на действие, логарифмическая шкала. Ширина полосы — разброс между операционными системами. Подробно о распределителе →
| Показатель | Результат |
|---|---|
| Regex против PCRE2 | машинным кодом быстрее в 37 сценариях из 41, толкователем позади ни в одном из 45; медианы долей 1,18 и 1,46 |
| HTTP/1: разбор тела | 1-е место из 6 — 20 607 МБ/с |
| HTTP/1: заголовки | 3-е из 6 — вдвое быстрее nginx, http-parser и Beast |
| HTTP/1: выделения памяти | ноль на сообщение, при более сильном договоре |
| ГОСТ против gost-engine | правильность доказана сличением по числам эталона |
Где мы уступаем и почему
Ни один пункт ниже не скрыт: каждый измерен, причина каждого установлена и записана.
| Слабость | Величина | Причина и рычаг |
|---|---|---|
| QUIC против ngtcp2 | 1,05× / 1,38× | копирование при приёме против передачи без копий; рычаг известен, работа спланирована |
| Кодирование заголовков HTTP/2 | 70 % | разобрано по шагам, семь правок уже дали прирост; остаток измерен |
| Кодирование HTTP/3 | 82 % | та же причина, что у HTTP/2 |
| Распределитель против tcmalloc | 7–15 % | цена предсказуемости и разбора адреса сбоя; jemalloc и системный обойдены везде |
| Сборка регулярного выражения | 0,44 от PCRE2 | разовая операция, не в горячем пути; плата за две программы — прямую и обратную — и более глубокий разбор выражения |
Чем закрыты риски: 6 091 проверка на каждой из двенадцати систем, прогоны под санитайзерами памяти и неопределённого поведения, ворошители на разборе протоколов и данных, журнал намеренных решений, где каждое отступление от очевидного записано с доводом и закреплено проверкой.
Пять механизмов ядра за одним договором
| Система | Движок | Набор команд |
|---|---|---|
| Astra Linux, Alt Linux | epoll / io_uring | x86-64 |
| Debian, Ubuntu, Fedora, openSUSE, Alpine | epoll / io_uring | x86-64 · ARM64 |
| macOS | kqueue | x86-64 · ARM64 |
| FreeBSD, NetBSD, OpenBSD | kqueue | x86-64 · ARM64 |
| DragonFly BSD | kqueue | x86-64 |
| Solaris 11.4, OpenIndiana | event ports | x86-64 |
| OpenWRT (musl) | epoll | x86-64 |
| Windows · MSVC и MinGW | IOCP | x86-64 · ARM64 |
| iOS, Android | kqueue / epoll | ARM64 |
| Elbrus Linux 8.1 | epoll / io_uring | e2k · перенос идёт |
Прикладной код от системы не зависит. Пять разных механизмов ядра — kqueue, epoll, io_uring, event ports и IOCP — спрятаны за одним договором: перенос на новую систему — это новый движок внизу, а не переписывание продукта.
- Работа в изоляции. Ни сборка, ни работа не требуют доступа в интернет и внешних репозиториев.
- Долгий срок жизни изделия. Редкие и старые системы без переписывания прикладного кода.
- Кластер процессов даже под Windows. Мастер принимает соединения и раздаёт их работникам.
- Статическая и динамическая сборка — одной настройкой CMake.
Перенос на «Эльбрус» идёт, и результаты уже хорошие
Отечественные платформы поддерживаются у нас первостепенно, и сейчас AWH переносится на Эльбрус-8С2 (Elbrus Linux 8.1, компилятор lcc). Уже работают распределитель памяти, волокна и системные модули, а порождатель машинного кода регулярных выражений обучен набору команд e2k.
У эталона PCRE2 машинного кода под «Эльбрус» нет вовсе, и появиться ему неоткуда: его порождатель этой архитектуры не знает. Поэтому на «Эльбрусе» наш машинный код сличается с его толкователем — и обгоняет его почти везде.
| Сличение на Эльбрус-8С2 | Итог |
|---|---|
| Наш машинный код против PCRE2 | впереди в 39 сценариях из 41, в середине ряда в 6,6 раза |
| Толкователь против толкователя | впереди в 22, вровень в 23, позади — ни в одном; медиана 1,36 |
| Лучшие строки кода | до 34 раз быстрее эталона |
Криптография идёт тем же путём: A-NTS на «Эльбрусе» уже работает целиком и местами в разы быстрее OpenSSL.
Что строится на AWH
Готово к сборке сегодня
- Веб-сервер и шлюз API — HTTP/1, HTTP/2, HTTP/3 и QUIC
- Балансировщик — кластер и передача принятых соединений
- VPN и защищённые туннели — туннельные устройства, SCTP, QUIC
- Прокси-сервер — SOCKS5 в составе
- Служебные узлы — свои DNS, NTP, ICMP, portmap
Следующий шаг
- Узел доставки содержимого на своём HTTP/3
- Брокер сообщений на своём транспорте
- Анализ трафика и журналов — regex и Grok
- Промышленный шлюз телеметрии
- Встраиваемые устройства
Уже строится
- ACU — преобразование форматов
- AWF — платформа веб-проектов
- ABS — резервное копирование
- Умный контейнер Crisper
- A-NTS — заменит BoringSSL