Как-то раз мне пришлось разбираться с проблемой, которая поначалу выглядела как ошметок самой настоящей черной магии. Хотя по итогу это оказалось очень простым и логичным поведением системы, отловить его получилось далеко не сразу.
Для понимания контекста расскажу немного о проекте. На тот момент в команде было всего несколько разработчиков. Сам проект был написан на PHP с достаточно большой кодовой базой. Местами бизнес-логика была довольно сложной, поэтому активно использовались очереди. Драйвером очередей выступала база данных — то есть консьюмеры очередей работали прямо через БД (это один из стандартных драйверов). Очень простое решение «из коробки», которое обычно ставят на старте, чтобы не раздувать стек. Частенько оно так и остается надолго, если нет необходимости масштабировать проект.
И вот в какой-то момент в самом сердце проекта (воронке продаж) обнаружился неприятный баг. В некоторых случаях он ломал процесс оплаты, поэтому фиксить его нужно было максимально срочно.
Сам по себе баг был не особо сложным, так что проблему я решил быстро и задеплоил правки на тестовый стенд. Однако, к моему удивлению, прогнав несколько тестов, я заметил, что баг никуда не делся — хоть и стал проявляться немного реже. Это стало большим сюрпризом: локально проблема больше не воспроизводилась (да-да, «на моем компьютере все работает!»), а вот в тестовой среде все было далеко не так гладко.
Перепроверив все в деталях, я был на 100% уверен, что проблема решена. Убедился, что CI/CD прошел корректно, кодовая база и контейнеры на сервере актуальные… Но и баг тоже остался актуальным.
Тут можно сделать паузу и подумать, в чем же все-таки было дело. Или просто заглянуть под спойлер. У меня эта пауза затянулась примерно на четыре часа дебага и попыток понять, что вообще происходит.
Спойлер
Оказалось, что один из разработчиков подключил базу тестового стенда к своему локальному окружению. На его компьютере проект был запущен со старым кодом. В итоге его локальные консьюмеры время от времени перехватывали задачи из общей очереди и выполняли их по старой логике — без моих обновлений.
По итогу можно было бы просто забрать у всех прямой доступ к базе, но это сильно ударило бы по удобству разработки. Поэтому я перевел очереди на Redis (который не торчит наружу) — и проблема была решена.
Вот такая она, командная разработка…

