Этот проект представляет собой демонстрационный микросервис на Go, который получает данные о заказах из очереди сообщений (Kafka), сохраняет их в базу данных (PostgreSQL), кэширует в памяти и предоставляет через HTTP API с простым веб-интерфейсом.
Для запуска проекта вам понадобится установленный Docker
-
Клонируйте репозиторий:
git clone <URL вашего репозитория> cd <имя папки проекта>
-
Запустите все сервисы с помощью Docker Compose: Эта команда соберет Go-приложение, запустит контейнеры с PostgreSQL, Zookeeper и Kafka, а также сам сервис.
docker-compose up --build
После выполнения команды будут доступны:
- Веб-интерфейс сервиса: http://localhost:8081/ (порт можно изменить переменной
HTTP_ADDR) - База данных PostgreSQL:localhost:5432- Kafka:localhost:9092
Проект состоит из нескольких ключевых компонентов, работающих вместе.
.
├── cmd/
│ └── main.go # Главная точка входа в приложение
├── internal/
│ ├── cache/
│ │ └── cache.go # Реализация LRU-кэша
│ ├── db/
│ │ └── postgres.go # Подключение к PostgreSQL
│ ├── handlers/
│ │ └── handlers.go # HTTP-обработчики (API)
│ ├── kafka/
│ │ └── kafka.go # Подписчик на Kafka
│ ├── model/
│ │ └── model.go # Структуры данных (модели)
│ ├── repository/
│ │ └── requests.go # Логика работы с БД (SQL-запросы)
│ └── service/
│ └── service.go # Бизнес-логика сервиса
├── web/
│ ├── index.html # Веб-интерфейс
│ └── script.js # JS для веб-интерфейса
├── publisher/
│ └── main.go # Скрипт для отправки тестовых сообщений
├── docker-compose.yml # Файл для оркестрации контейнеров
├── Dockerfile # Файл для сборки Go-приложения
├── go.mod
├── go.sum
└── init.sql # SQL-скрипт для инициализации БД
- Запуск:
docker-composeзапускает четыре сервиса:pgdb(PostgreSQL),zookeeper,kafkaиgo(наш сервис). - Инициализация БД: Контейнер
pgdbпри первом запуске выполняет скриптinit.sql, создавая необходимую структуру таблиц. - Старт Go-сервиса:
- Приложение подключается к PostgreSQL.
- Загружает последние заказы из БД в LRU-кэш для быстрого доступа.
- Подключается к Kafka и подписывается на топик
orders. - Запускает HTTP-сервер на порту
8081.
- Получение нового заказа:
- Сообщение с данными заказа публикуется в топик
ordersв Kafka. - Go-сервис получает сообщение, парсит JSON.
- Сохраняет заказ в PostgreSQL через транзакцию.
- Если сохранение успешно, заказ добавляется в кэш.
- Сообщение с данными заказа публикуется в топик
- Запрос данных через API:
- Пользователь вводит ID заказа в веб-интерфейсе и нажимает "Найти".
- Frontend отправляет
GETзапрос на относительный путь/order/{order_uid}(базовый хост/порт берется из текущего окна). - Сервис сначала ищет заказ в кэше. Если находит — мгновенно возвращает. - Если в кэше нет — делает запрос в БД, сохраняет найденный результат в кэш и возвращает его.
Чтобы проверить систему, нужно опубликовать тестовое сообщение в Kafka.
-
У вас есть файл
publisher/main.go:package main import ( "context" "encoding/json" "io/ioutil" "log" "github.com/segmentio/kafka-go" ) const ( topic = "orders" broker = "localhost:9092" ) func main() { data, err := ioutil.ReadFile("model.json") if err != nil { log.Fatalf("Failed to read model file: %v", err) } w := &kafka.Writer{ Addr: kafka.TCP(broker), Topic: topic, Balancer: &kafka.LeastBytes{}, } err = w.WriteMessages(context.Background(), kafka.Message{Value: data}) if err != nil { log.Fatalf("failed to write messages: %v", err) } log.Println("Message published to Kafka successfully!") }
-
Добавьте
model.jsonв корень проекта с тестовыми данными. -
Запустите паблишер (настраивается через
PUB_BROKER,PUB_TOPIC,PUB_COUNT): Выполните команду в терминале в корне проекта:go run publisher/main.go
-
Проверьте результат:
- В логах
docker-composeвы должны увидеть, что сервис получил и обработал заказ. - Откройте http://localhost:8081/, введите
order_uidиз вашегоmodel.json(например,b563feb7b2b84b6test) и нажмите "Найти". Вы должны увидеть полную информацию о заказе.
- В логах