Skip to content

Adverax/demo_billing

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

7 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Тестовое задание Billing

Микросервис баланса пользователей.

Приложение хранит в себе идентификаторы пользователей и их баланс. Взаимодействие с ним осуществляется исключительно с помощью брокера очередей.

По требованию внешней системы, микросервис может выполнить одну из следующих операций со счетом пользователя:

  • Списание
  • Зачисление
  • Перевод от пользователя к пользователю (будет плюсом, но не обязательно)

Блокирование с последующим списанием или разблокированием. Заблокированные средства недоступны для использования. Блокировка означает что некая операция находится на авторизации и ждет какого-то внешнего подтверждения, ее можно впоследствии подтвердить или отклонить

После проведения любой из этих операций генерируется событие-ответ в одну из очередей.

Основные требования к воркерам:

  • Код воркеров должен безопасно выполняться параллельно в разных процессах
  • Воркеры могут запускаться одновременно в любом числе экземпляров и выполняться произвольное время
  • Все операции должны обрабатываться корректно, без двойных списаний, отрицательный баланс не допускается

В пояснительной записке к выполненному заданию необходимо указать перечень используемых инструментов и технологий, способ развертки приложения, общий механизм работы (интерфейсы ввода/вывода)

Будет плюсом покрытие кода юнит-тестами.

Требования к окружению: Язык программирования: PHP 7 (PSR-2) либо Go 1.10+ Можно использовать: любые фреймворки, реляционные БД для хранения баланса, брокеры очередей, key-value хранилища.

Реализация

Особенности

  • Сервис поддерживает обработку паники.
  • Сервис поддерживает создание и хранение журнала выполненных операций.
  • Сервис поддерживает полную консистентность данных
  • Сервис поддерживает graceful shutdown.
  • Сервис НЕ поддерживает Heartbeat для базы данных.
  • На момент старта сервиса, должен быть уже запущен NATS.

Используемые компоненты

  • MySQL - для хранения данных
  • NATS - брокер сообщений

Используемые библиотеки

  • github.com/adverax/echo - легковесный фреймворк. Как таковой он здесь не используется. Нужен просто его пакет database/sql для работы с базой данных.
  • github.com/nats-io/go-nats - клиентский пакет подключения брокера сообщений NATS.
  • github.com/BurntSushi/toml - пакет для загрузки файла конфигурации.

API

Ответ на каждый запрос включает статус его выполнения: 0. Операция прошла успешно

  1. Неизвестная ошибка
  2. Операция устарела
  3. Для выполнения операции недостаточно средств
  4. Аккаунт не найден

Credit

Списание средств со счета.

  • Subject/Queue - bank.credit
  • Request: {"uid":1,"account":1,"amount":10}
  • Response: {"status":1}

Debit

Зачисление средств на счет.

  • Subject/Queue - bank.debit
  • Request: {"uid":1,"account":1,"amount":10}
  • Response: {"status":1}

Transfer

Перевод средст с одного счета на другой.

  • Subject/Queue - bank.transfer
  • Request: {"uid":1,"src":1,"dst":2,"amount":10}
  • Response: {"status":1}

Acquire

Блокировка средств.

  • Subject/Queue - bank.acquire
  • Request: {"uid":1,"account":1,"amount":10}
  • Response: {"status":1}

Commit

Подтверждение блокированных средств.

  • Subject/Queue - bank.commit
  • Request: {"uid":1,"account":1}
  • Response: {"status":1}

Rollback

Возврат блокированных средств.

  • Subject/Queue - bank.rollback
  • Request: {"uid":1,"account":1}
  • Response: {"status":1}

Принцип работы

Для достижения идемпотентности, в каждой операции должен присутствовать ее уникальный номер uid. Каждая операция, при записи в базу данных, регистрирует действие в таблице истории. При существовании одинакового ключа (work_index) происходит ошибка базы данных, которую мы трактуем, как устаревание операции (идемпотентный случай). Аналогчно работает и таблица активов.

В сервисе используется пакет доступа к базе данных github.com/adverax/echo/database/sql, который позволяет эмулировать вложенные транзакции, а также хранить область видимости в контексте. Это позволяет нам осуществлять декомпозицию функционала работы с базой на отдельные функции, не заботясь о контексте выполнения запросов.

Для каждой таблицы используется собственный менеджер.

База данных

База содержит следующие таблицы:

  • account - текущее состояние счета пользователя
  • asset - зарезервированные средства. Для удовлетворения требования идемпотентности, таблица содержит уникальный индекс work_index (account, uid).
  • history - журнал выполненных операций. Для удовлетворения требования идемпотентности, таблица содержит уникальный индекс work_index (account, uid, op).

Брокер

В качестве брокера сообщений используется NATS (без гарантированной доставки сообщений). Для упрощения реализации каждый тип операции имеет собственный Subject и Queue. Множество воркеров подключаются к одной и той же очереди, что позволяет нам организовать конкурентный захват сообщения. Полученное сообщение брокер делегирует банку для дальнейшей обработки, после чего формирует ответ, который возвращается брокеру. Таким образом, каждый endpoint брокера по существу является простым адаптером со следующей логикой работы:

  • Декодировать данные
  • Вызвать метод банка
  • Кодировать данные и вернуть их брокеру.

Комментарии

Для достижения максимальной производительности можно было перенести логику операций в хранимые процедуры.

Установка

  • Установить требуемые библиотеки
  • Скомпилировать сервис
  • Создать базу данных (перейти в каталог database и выполнить команду: mysql -uMyName -pMyPassword < create.sql).
  • Настроить файл конфигурации
  • Запустить NATS.
  • Запустить сервис на выполнение Развертывания как такового не требуется - достаточно просто использовать выполнимый файл.

Тесты

Для основных методов менеджеров написаны модульные тесты. Эти тесты были написаны на скорую руку, поэтому качество их кода оставляет желать лучшего. Однако, они позволяют проверить работоспособность sql кода.

Для запуска тестирования необходимо сделать клон базы данных под именем billing_test.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published