Сервер для многопользовательского онлайн-чатика на userver framework.
-
Есть три готовых дашборда в grafana. Метрики, скрины дашбордов тут
-
Проводился нагрузочный тест. Тянуло 30 000 RPS (уперлись в сеть ВМ), на 10k RPS 98 квантиль времени отправки был 3мс.
-
Работает через long polling, API вот, аутентификация по JWT
-
Поддержан динамический конфиг, вот пример. Можно крутить максимальное время поллинга, количество открытых сессий, времени жизни очередей, rate limiter и так далее.
Для получения сообщений клиент создает на сервере сессию, которую будет в дальнейшем поллить. Сессия — по факту lock-free очередь (MPSC), которую наполняют другие пользователи. Сессии добавляются в Registry, откуда их можно достать, чтобы получить или отправить сообщения. Старые сессии удаляются фоновым процессом, который периодически делает обход и заодно снимает метрики.
В качестве структуры данных для Registry была реализована ShardedMap — шардированная мапа, где шард — это std::unordered_map с SharedMutex, что позволяет блокироваться не всех пользователей, а только один шард, читатели же в пределах одного шарда не конкурируют. ShardedMap хранит отображение user_id в "почтовый ящик" пользователя, который в себе инкапсулирует набор пользователських сессий. Их может быть максимум 5 (крутится через дин конфиг), поэтому используется FlatMap, защищенная через rcu::Variable. Один пользователь может иметь несколько сессий, допустим, с разных страниц браузере или устройств.
-
104 функциональных тестов на Python (
testsuite) -
382 модульных и интеграционных тестов на
gtest -
3 бенчмарка на шардированную мапу, MPSC-очередь и
rcu<flat_map>(хранилище сессий) -
Registry делает сервис statefull, поэтому была сделана отдельная таска доступная в тестах для сброса состояния сервиса
-
Для удобной правки в тесте динамических конфигов были реализованы фикстурки
*_config
Небольшой навайбкоденный фронтендик есть
chat.mp4
В качестве сервиса динконфигов можно поднять uservice-dynconf. Остальное материализуется само через
docker compose up
PRESET is either debug, release
make cmake-PRESET- run cmake configure, update cmake options and source file listsmake build-PRESET- build the servicemake test-PRESET- build the service and run all testsmake start-PRESET- build the service, start it in testsuite environment and leave it runningmake install-PRESET- build the service and install it in directory set in environmentPREFIXmakeormake all- build and run all tests indebugandreleasemodesmake format- reformat all C++ and Python sourcesmake dist-clean- clean build files and cmake cachemake docker-COMMAND- runmake COMMANDin docker environmentmake docker-clean-data- stop docker containers
Add in CMakePresets.json "USERVER_DEBUG_INFO_COMPRESSION": "none"