В Neighborhoods.com Engineering у нас есть технический долг, как и у любой другой организации, которая когда-либо писала какой-либо код. Одним из наиболее проблемных технических детей является наша устаревшая система «диспетчера задач» под названием Looper.

Looper назван удачно. Он зацикливается и использует pcntl для отделения дочернего процесса для управления рабочими процессами. Он более или менее слепо запускает фоновые задачи, не понимая, что на самом деле делает. Иногда Looper спит. Иногда Looper вылетает. Иногда бомбит вилка Looper.

Looper не приносит большого удовольствия в продакшене.

Looper начал жизнь с довольно простых задач, связанных с управлением несколькими потоками данных и работниками очереди SQS. По мере того как мы росли, он рос, но не обязательно был построен для того, чтобы расти так, как нам было нужно. Однако, несмотря на то, что Looper сейчас является проблемой, он многому нас научил, и в этом есть большая ценность.

Ранее в этом году мы решили решить нашу проблему с лупером. Перечисляя наши цели дизайна, мы хотели, чтобы он устранил все болевые точки, с которыми мы столкнулись с Looper.

Мы хотели следующие

  • Быстро - низкие накладные расходы на оборудование. Мы хотели, чтобы сервис выполнял бизнес-логику как можно быстрее.
  • Прозрачный - дает понятное представление о том, какие рабочие места выполняются и как они себя ведут.
  • Изолированный - если воркер ведет себя плохо, это не должно влиять на его соседей.
  • Масштабируемость - выполняйте ровно столько работы, сколько необходимо. Если нечего делать, молчи и бездельничай. Если есть над чем поработать, масштабируйте немедленно и надлежащим образом, а затем уменьшайте масштаб после завершения работы.
  • Устойчивый - мир полон ужасов.
  • Принятие - возможность переноса существующих рабочих нагрузок без значительного рефакторинга, если таковой имеется. Уметь переносить существующие циклы и т. Д. к массовому параллелизму, сделав его простым по умолчанию. Легко развертывать и запускать.
  • Стабильный - используйте широко распространенные и отработанные технологии.
  • Распределенный - все компоненты должны работать автоматически в любом произвольном количестве сред выполнения, которые появляются и исчезают динамически.

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

Для этого нам пришлось построить несколько разных частей. Нам нужно

  • Кооперативная распределенная мьютексная система, осведомленная об акторах.
  • Модель процесса.
  • Система управления задачами.
  • Система динамического и статического расписания.

Кооперативный распределенный мьютекс, осведомленный об акторах

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

Модель процесса

Мы хотим изолировать рабочие процессы и на 100% управлять запросами на прерывания, то есть наши процессы реагируют на события, а не на опрос. Управление поведением продукта превратилось в простую асинхронную модель коммуникации между публикациями и подписками.

Управление задачами

У рабочих мест есть состояние, и мы хотим понять, на каком этапе их жизни находится любая произвольная работа, над которой мы работаем.

Кроме того, мы хотим иметь метрики о том, как ведет себя конкретная работа. Мы хотим знать, сколько раз он работал, падал, повторялся или задерживался. Кроме того, мы хотим иметь возможность передавать в реальном времени рабочие процессы и их поведение бизнес-логики в ELK и CloudWatch.

Динамическое и статическое планирование

Мы хотим иметь возможность динамически планировать задания для работы как с PHP, так и с REST API. Кроме того, мы хотим иметь возможность планировать выполнение заданий из любого выражения cron. Потому что, как ни странно, какой-то поставщик должен иметь что-то, отправленное им ровно в 2:26 утра в последний четверг ноября, только в високосные годы и ориентировано на восточноафриканское время. Но не волнуйтесь, Кодзё вас поддержит.

Рождение Кодзё

В итоге мы назвали продукт Kōj (工場), что в переводе с японского означает «фабрика». Вероятно, на то, чтобы назвать его, были потеряны недели; одна из двух самых сложных вещей.

Это даже включало добавление псевдонима консольной команды для запуска службы.

$ vendor/bin/kojo gō-gō

Нам здесь весело (извините).

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

В настоящее время мы находимся в процессе переноса наших существующих задач Looper на рабочие места Kj, и это идет отлично. У нас просто кружится голова от того, что мы видим в производстве.

Git (посмотри, что я там делал) начал с Кодзё сегодня!

Фактически, мы настолько довольны его поведением, что я очень рад сообщить, что у нас есть открытый исходный код, и в настоящее время он доступен на GitHub и Packagist !

В Neighborhoods.com Engineering мы не только находимся на постоянной стадии развития, но и очень ценим раннюю поставку. Кодзё будет абсолютно обновлен к следующему разу, когда я напишу об этом (что будет очень скоро).

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

Мы очень счастливы и взволнованы возможностью поделиться с вами этим первым выпуском сегодня, и мы очень ждем ваших отзывов и PR. Мы твердо верим в проекты с открытым исходным кодом и являемся потребителями многих из них. Сегодня мы надеемся немного отдать и многое вернем, подвергнув Кодзё огромному океану умных умов для изучения и использования.

Пожалуйста, следите за обновлениями, чтобы узнать о более глубоких погружениях и многом другом от Кодзё!