Как устроен оркестратор роботов, управляющий коллекцией роботов?
Что проверяют
Умеете ли вы спроектировать систему координации: кто хранит состояние роботов, как задача попадает к исполнителю и что происходит, когда робот пропал посреди работы. Следом обычно спрашивают, как не выполнить одну задачу дважды и что будет, если упадёт сам оркестратор.
Как отвечать
Сначала уточните, о каких роботах речь: программные RPA-боты или физические устройства на складе. Каркас от этого почти не меняется, меняются задержки и цена ошибки. Дальше компоненты:
- реестр роботов: у каждого конечный автомат состояний
IDLE,BUSY,OFFLINE,ERRORи набор возможностей. В одном процессе этоConcurrentHashMap, в кластере таблица в базе или Redis; - очередь задач: приоритеты, дедлайны, требования к исполнителю. В памяти
PriorityBlockingQueue, в распределённом варианте RabbitMQ или таблица с выборкой черезSELECT ... FOR UPDATE SKIP LOCKED; - диспетчер: сопоставляет задачу и свободного робота по возможностям и нагрузке. Удобна модель pull, когда робот сам забирает работу: так проще с обратным давлением;
- heartbeat и аренда: робот раз в N секунд подтверждает, что жив, задача выдаётся с таймаутом. Проверку ведёт
ScheduledExecutorService, просроченная аренда возвращает задачу в очередь; - ретраи и журнал: ограниченное число повторов с экспоненциальной задержкой, после них задача уходит в отдельную очередь на разбор оператором.
Отказоустойчивость самого оркестратора: несколько экземпляров и выбор лидера через ZooKeeper, etcd или блокировку в базе, чтобы задачи распределял ровно один. Состояние держите во внешнем хранилище, а не в памяти процесса, тогда перезапуск ничего не теряет. Метрики: длина очереди, время ожидания, доля ошибок по роботам.
Где спотыкаются
Не продумывают пропажу робота. Без heartbeat и таймаута аренды задача навсегда висит в статусе «выполняется».
Не делают выполнение идемпотентным. Робот выполнил задачу, но ответ потерялся, оркестратор выдаёт её повторно, и действие происходит дважды. Нужен ключ задачи, по которому исполнитель узнаёт повтор.
Держат всё состояние в памяти одного процесса под общим synchronized. Это и узкое место по производительности, и единая точка отказа.