База знаний
Статья

Как создать новую WMS-систему?

Для начала стоит сказать, кто же мы такие, что делаем, и зачем все это нужно. Мы – компания AXELOT, мы пишем логистические системы, пишем их давно и достаточно неплохо. Казалось бы, наши дела идут хорошо, но, как говорила Алиса: «Нужно бежать со всех ног, чтобы только оставаться на месте, а чтобы куда-то попасть, надо бежать как минимум вдвое быстрее!». И вот мы задумались: как бы нам побежать еще быстрее, чем сейчас. Очевидно, чтобы быстрее бежать, необходимо постоянно создавать что-то новенькое, а значит нужно искать новый взгляд на старые вопросы. Эта история о том, как мы создавали новую WMS-систему.

Что же такое WMS, и зачем она нужна? Те, кто знаком с логистикой, могут пропустить эту часть, но, возможно, вам будет интересен наш взгляд. WMS – Warehouse Management System, система управления складскими процессами. Весь современный мир покрыт логистическими цепочками, давайте взглянем на мир глазами логиста:

Не правда ли, что-то напоминает? Так это же всемирная паутина! Здесь производители генерируют товарный поток (контент), распределительные центры/склады маршрутизируют потоки, а потребители-пользователи получают это товары (контент). И пользователи должны получить то, что нужно, когда нужно, в нужном виде и в нужном объеме.

Давайте теперь рассмотрим узел этой сети – склад – более детально.

И снова мы увидим множество аналогий. Есть входные порты (ворота), есть буферы ввода и вывода (зоны Приёмки и Отгрузки), есть Хранение – это не что иное, как «память» нашего склада, наш RAM, сюда мы помещаем на время то, что потом будет отдано наружу. Есть всевозможные кэши, например, зоны Отбора и Подпитки, куда товар помещается заранее, чтобы не таскать его из хранения каждый раз. Есть внутренние маршруты движения и множество дополнительных механизмов, зависящих от организации конкретного склада. Пред нами настоящий маршрутизатор, не хватает только одного – Операционной Системы. Без нее любой маршрутизатор – бесполезная железяка, а склад –мертвое строение. И тут на сцену выходит WMS – операционная система склада. Я пишу «Операционная система», потому что спектр функций WMS намного шире, чем просто заставлять двигаться товары.

Помимо этого, очень часто вокруг WMS живет целая экосистема, в которую могут входить: система управления двором YMS (Yard management system), системы управления роботизированным оборудованием WCS (Warehouse control system), BI и т.д. Это крайне важно, и это обязательно отразится на архитектуре нашей WMS.

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

Приведу простой пример: предположим, что вы должны были отгрузить товар А в количестве N единиц, но этих N единиц у вас еще нет, но вы запланировали отгрузку, так как ждете поступления А в достаточном количестве. Но тут поставка товара А отменяется, зато сняли заказ, под который вы держали М единиц товара В, который по условиям поставки может заменить А, но на него претендует еще один заказ, хоть и с меньшим приоритетом. Тут еще и кладовщик уронил палету с частью товара, и надо срочно понять, можно оттуда что-то планировать или нет. Есть еще подходящий заменитель С, но он может не пройти по сроку годности и стоит где-то третьим рядом, и нужно найти свободный погрузчик, чтобы его достать. При этом у вас в процессе сборки находятся 200 крупных заказов, еще пара десятков в приемке, ваш справочник SKU составляет 300 000 позиций, а по складу ходят и ездят 200 не самых старательных и трудолюбивых сотрудников. И все это должно работать как часы, ваш заказ на N единиц товара А должен уйти точно в срок, как и все остальные 199 заказов.

А ведь существуют еще автоматизированные склады, где работают конвейеры, роботы-палетайзеры и очень быстрые сортеры, которые не готовы ждать, пока наша WMS выполнит очень красивый, но медленный SQL-запрос.

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

Разобравшись с тем, что делает WMS, перейдём к архитектуре. Большинство существующих сегодня «классических» WMS – это системы, развивавшиеся десятилетиями и обросшие таким количеством легаси, что проще написать все заново, чем капитально изменить имеющуюся архитектуру. Чаще всего эта архитектура сводится к данным в БД, бизнес логике, построенной на SQL-запросах или, о ужас, на хранимых процедурах и некоторому фреймворку для построения фронт-энда. Доработка такой системы под проект ведется в худшем случае путем «допиливания» хранимых процедур, доработки прикладного кода или, в хорошем случае, надстройкой плагинами, причем худших случаев будет гораздо больше. Обработка данных часто построена на регламентном вызове обработчиков, а не на реакции на событие. Что же касается архитектуры решения, то чаще всего это монолиты. И вот все это делать мы не хотим!

А что же мы хотим? Чтобы это понять, мы определили для себя требования верхнего уровня, и они получились следующие:

  • Возможность масштабироваться горизонтально.
  • «Данные всегда под рукой».
  • Событийная модель. Система должна быть реактивной.
  • Расширяемость. Легкое добавление новых функциональностей и поведения как для системы в целом, так и для отдельных ее компонентов.
  • Гибкость. Легкая модернизация существующих алгоритмов, подмена стандартного функционала.
  • Адаптивность пользовательского интерфейса. Пользовательский интерфейс должен легко кастомизироваться.

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

Вооружившись этими требования, мы стали думать и придумали примерно следующее:

  • Наша система будет иметь сервис-ориентированную архитектуру. Не микросервисы, как это модно последнее время, для WMS это безумие, а достаточно крупные блоки, решающие спектр функциональных задач. Микросервисы тоже будут, но в тех случаях, когда необходимо решать отдельные задачи с четко определенными границами. Более того, мы позволим нашим инженерам внедрения и даже нашим заказчикам добавлять в систему свои собственные сервисы. Сервисы смогут подписываться на события системы (об этом смотри ниже), взаимодействовать с другими компонентами посредством REST API.
  • Память очень быстрая, она дешевая и ее много. Давайте всегда держать в памяти объектную модель склада и его окружения. Да, памяти потребуется действительно много, но сегодня это не проблема. Все наши алгоритмы будут работать с готовыми объектами в памяти, переходить по объектным ссылкам, искать по хэш-мэпам — это очень быстро. При этом БД будет играть роль лога, будем сохранять в нее актуальные состояния объектов. Избавим себя от необходимости создания сложных реляционных структур в БД и сложных запросов, будем писать в БД «плоские» данные. Тут, конечно, будут подводные камни, но мы их примерно знаем и знаем, как с ними бороться.
  • Вся система будет нанизана на очень быструю шину событий, это будет ее центральный нервный ствол. Любое изменение чего-либо в системе будет порождать событие, все заинтересованные компоненты подпишутся на интересные им события и будут реагировать на них мгновенно. При этом мы разрешим управлять подписками через файлы конфигурации. Если в данном бизнес-процессе не надо реагировать на какое-то событие, можно убрать его из подписки. Если же, наоборот, компонент должен реагировать на что-то, на что он ранее не реагировал, закинем в него плагин, добавим подписку и, вуаля, у нас появился новый тип реакции, новый обработчик события, при этом мы не трогали код системы, да вообще ее не перегружали!
  • Что до механизмов расширения и модернизации функциональности, то мы уже немного позаботились об этом, разрешив вводить в систему новые сервисы и управлять подписками. Добавим к этому механизм плагинов, разрешим плагинам не только подписываться на события, но и публиковать собственные REST API. И пусть все это они делают декларативно.
  • Добавим немного AOP, разрешим подменять бизнес-методы плагинами, вызывать плагины ДоМетода и ПослеМетода. Для полноты картины DI будет управляться через файлы конфигурации.
  • Не будем жестко верстать пользовательский интерфейс. Пусть пользовательский интерфейс будет описан декларативно в файлах, которые можно редактировать под отдельные проекты при помощи специального редактора или даже простого Notepad. Не забудем разрешить микрофронтэнды, пусть микросервисы смогут публиковать свои микрофронтэнды.

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

Бэтмен – это архитектор, который должен был все это выстроить.

В качестве основного языка разработки мы выбрали C# и среду исполнения Net Core. Вопрос достаточно дискуссионный, возможно кое-кто возразит, что разумнее использовать Java, мы рассмотрели даже Erlang. При выборе языка мы учли следующие факторы: в компании уже есть направления разработки на C#, а значит есть ресурсный центр. Наши заказчики очень любят допиливать систему самостоятельно, и программисты C# обойдутся им дешевле. Порог входа в C# несколько ниже, чем в Java, и у нашего заказчика больше шансов переучить своих программистов на C#. Победила коммерческая целесообразность.

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

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

Сейчас, когда мы стоим в конце пути и смотрим на объем проделанной работы, сложно представить, что мы сделали все это с чистого листа. Ведь когда все начиналось, у нас была идея и пустые рабочие столы для новой команды. Сейчас у нас есть принципиально новая система и команда с совершенно новыми компетенциями. При этом, оказалось, что часть подсистем, которые мы разработали для новой WMS отлично интегрируются с нашим основным классическим продуктом. И эти подсистемы увидели свет в связке с нашей классической WMS раньше, чем новый продукт. Гибкость и расширяемость проявила себя там, где мы совсем этого не ожидали.

Стоит отдельно сказать о роли тестирования. Без него реализовать проект такого масштаба и сложности невозможно, и отношение «один тестировщик на двух разработчиков» совсем не кажется чрезмерным. Очень эффективным оказалось тестирование в полевых условиях, когда мы запускаем систему на настоящем действующем складе параллельно «боевой» WMS, а группа тестировщиков работает 8 часов в день вместе с сотрудниками склада, но на своей WMS. Конечно, они физически не перемещают товары, но выполняют все те же самые операции, что и кладовщики. При этом «боевая» система выгружает данные в тестовый контур, и тестирование происходит на актуальны данных. Ни один, даже самый изощренный сценарий, написанный в офисе, не может так уверенно поставить систему в ступор, как какой-нибудь с виду безобидный заказ, выгруженный из «боевой» WMS. Ни один тест-кейс не сможет сделать с мобильным терминалом то, на что способен тестировщик в боевых условиях. Я уже не говорю о том, что зона с плохим покрытием WiFi в дальнем углу склада способна вызвать ошибки там, где их и не думали искать в стерильных условиях офиса.

Итог – мы это сделали! И это уже не MVP, а взрослый продукт, который готовится к пилотированию. Этот продукт получился совершенно необычным для консервативного рынка WMS. Если наша классическая WMS является результатом долгой и успешной эволюции и так или иначе несет в себе наследие многих поколений, то новая система родилась из переосмысления требований к WMS и проекции их на современные тенденции разработки.

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

Мы используем файлы cookie для улучшения работы сайта