Учебный сервис программы по проектированию систем Хекслета. Один сервис развивается на протяжении четырёх курсов.
| Курс | Каталог |
|---|---|
| Монолитное приложение | monolith, стенд курса; monolith-project, стартовый набор проекта |
| События и стриминг | events, примеры моделей взаимодействия и порядка записей в Kafka |
| Распределённая система | Материалы появятся по мере разработки курса |
| Глобальная система | Материалы появятся по мере разработки курса |
Во всех курсах студент работает с готовым кодом сервиса. В «Распределённой системе» монолит разделяется на сервисы, но их код уже лежит в репозитории, и студент меняет конфигурацию и вносит небольшие правки. Знание TypeScript не требуется.
В каталоге monolith лежит работающий сервис заказа поездок вместе со стендом курса. На нём выполняются опыты уроков.
Стартовый набор проекта «Сервис такси под нагрузкой» лежит в каталоге monolith-project, и студент копирует его содержимое в корень своего репозитория. Это тот же сервис на стенде из балансировщика, двух экземпляров приложения, базы и генератора нагрузки. Копии базы и стаба уведомлений там нет, а вместо документов стенда лежит шаблон проектного документа design.md.
Сервис работает с выключенными механизмами защиты. Индексов сверх первичных ключей нет, ожидание сервиса уведомлений ничем не ограничено, очередь запросов не имеет предела, копия базы стоит рядом и не используется. Что из этого менять и в каком порядке, решают по замеру.
Механизмы таймаутов, повторов, ограничения нагрузки, кэширования, чтения с копии и вывода экземпляра из работы уже встроены в сервис. Их включает файл monolith/service.env. Для опытов уроков меняются настройки, SQL-миграции и nginx. Знание TypeScript не требуется.
cd monolith
make upСервис поднимается на http://localhost:8080 через балансировщик. Порт меняется переменной WEB_PORT. Схема и учебные данные накатываются при первом запуске базы, миграции применяет цель make up.
curl -s localhost:8080/health
curl -s localhost:8080/trips/1| Путь | Назначение |
|---|---|
| docker-compose.yml | стенд, то есть два экземпляра приложения, база, копия базы, балансировщик, стаб уведомлений и генератор нагрузки |
| service.env | переключатели и численные пределы поведения сервиса |
| src/ | приложение на TypeScript, запускается нодой без сборки |
| db/schema.sql | базовые таблицы пассажиров, водителей, поездок и истории |
| db/seed.sql | учебные данные, 20 тысяч поездок |
| db/seed-large.sql | два миллиона поездок для замеров, заливается целью make seed-large |
| db/migrations/ | изменения схемы поверх базовой |
| load/first-load.ts | первый пример k6 с двумя виртуальными клиентами |
| load/read.ts | чтение поездки с постоянной частотой |
| load/mixed.ts | профиль сервиса, то есть заказы, чтения, координаты и история одновременно |
| load/data-access.ts | профиль истории, геопоиска и поиска поддержки для сравнения индексов |
| load/profile.json | частоты и цели, из которых сценарии берут числа |
| nginx/nginx.conf | балансировщик перед двумя экземплярами стенда |
| nginx/local.conf | тот же балансировщик для запуска на хосте без compose, его разбирает урок о масштабировании |
| stub/index.ts | стаб сервиса уведомлений с настраиваемой задержкой и долей отказов |
| Метод и путь | Назначение |
|---|---|
GET /health |
готовность экземпляра |
GET /metrics |
счётчики запросов, ожидания пула, времени SQL |
POST /trips |
создать заказ, обязателен заголовок Idempotency-Key |
GET /trips/{id} |
прочитать поездку |
POST /trips/{id}/accept |
назначить водителя |
POST /trips/{id}/cancel |
отменить поездку |
GET /trips/search?q= |
найти поездку по адресу |
POST /drivers/{id}/location |
обновить координаты водителя |
GET /drivers/nearby?lat=&lon=&radius= |
свободные водители рядом |
GET /passengers/{id}/trips |
история пассажира |
GET /tariffs/{code} |
тариф |
make load PROFILE=read # чтение с постоянной частотой
make load PROFILE=mixed # профиль сервиса
make load PROFILE=mixed SCALE=40 NAME=overload # поиск пределаЦель пишет отчёт с условиями опыта в reports/ и сохраняет сводку k6 рядом в JSON. Сценарий запускается контейнером, поэтому k6 на машину ставить не нужно.
SQL-примеры уроков можно выполнять в учебной базе без стенда.
createdb taxi_development
psql -d taxi_development -v ON_ERROR_STOP=1 -f monolith/db/schema.sql
psql -d taxi_development -v ON_ERROR_STOP=1 -f monolith/db/seed.sqlДля примеров с геопоиском понадобится расширение PostGIS.