Skip to content

Subb98/BotHelp-Test-Task

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

13 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

BotHelp Test Task

Описание

Есть веб-api, непрерывно принимающее события (ограничимся 10000 событий) для группы аккаунтов (1000 аккаунтов) и складывающее их в очередь. Каждое событие связано с определённым аккаунтом и важно, чтобы события аккаунта обрабатывались в том же порядке, в котором поступили в очередь. Обработка события занимает 1 секунду (эмулировать с помощью sleep). Сделать обработку очереди событий максимально быстрой на данной конкретной машине. Код писать на PHP. Можно использовать фреймворки и инструменты такие как RabbitMQ, Redis, MySQL и т.д.

Концепция решения

Задача решена посредством шардирования очереди, при помощи обменника (exchanger) с типом Consistent Hash. Особенность его в том, что он всегда будет отправлять сообщение с одним и тем же routing_key (в контексте задачи - это client_id) в ту же самую очередь. Таким образом, гарантируется порядок обработки сообщений для каждого клиента, при наличии только одного получателя на каждой очереди. Вместе с этим, за счёт разделения всех сообщений на отдельные очереди, достигается приемлемая скорость выполнения, но с сохранением консистентности данных.

Установка

# Склонировать репозиторий
git clone git@github.com:Subb98/BotHelp-Test-Task.git

# Перейти в директорию проекта
cd BotHelp-Test-Task

# Выдать доступ на выполнение для файлов в директории bin
chmod -R a+x bin/

# Запустить сборку проекта
docker compose up --build -d
# Примечание: если у вас старая версия Docker Compose, используйте команду с разделителем '-', docker-compose

# Проверить, что сборка успешна и контейнеры запущены
docker compose ps

# Дальнейшие команды выполнять из контейнера, для удобства, можно просто войти в него
docker exec -it bothelp-test-task.php sh

Использование

# Запустить генерирование клиентских сообщений:
./bin/console app:generate-client-messages 'data/client_messages.csv'

# Запустить отправку сгенерированных сообщений на Websocket server:
./bin/console app:send-client-messages 'data/client_messages.csv' start

# Запустить супервизор, который, в свою очередь, запустит получателей сообщений:
./bin/supervisor

# Логи работы супервизора будут находиться в data/supervisor.log, по ним можно будет проверить,
# выполняется ли порядок обработки событий для каждого конкретного клиента

Примечание

В качестве Websocket-клиента для тестирования вручную можно использовать websocat. Для подключения к серверу с SSL и самоподписным сертификатом необходимо использовать опцию --insecure, пример:

websocat wss://0.0.0.0:8000 --insecure

Пример генерирования нового самоподписанного сертификата:

openssl req -newkey rsa:4096 \
            -x509 \
            -sha256 \
            -days 3650 \
            -nodes \
            -out localhost.crt \
            -keyout localhost.key \
            -subj "/C=RU/ST=Perm Krai/L=Perm/O=OpenSSL/OU=0.0.0.0/CN=localhost"