Доставку заказывали? Как «Перекрёсток» доставляет 6000 товаров в день

Люди любят доставку. За небольшую плату ты покупаешь возможность получить нужные товары, не выходя из дома: еду из любимого ресторана, крупногабаритную мебель, книгу, которую хотел давно прочитать, да и вообще — что угодно. И рост числа сервисов по быстрой доставке всего на свете только подтверждает этот тезис. Да и для магазинов это плюс — запартнёрился с любой доставкой товаров до двери и увеличил свой чек.
У нас в «Перекрёстке» есть собственная доставка. Для человека со стороны процесс доставки из магазина до дома выглядит примерно так:

  1. Выбрал что-то на сайте и положил в корзину.
  2. Ввёл адрес и оплатил заказ.
  3. Магазин быстро отдал заказ курьеру.
  4. Курьер доставил заказ.

На самом деле, всё немного сложнее. Меня зовут Виталий, я руководитель отдела разработки, и сегодня я расскажу, как у нас всё работает. И на чём.

За стабильность процесса отвечают сразу два приложения — витрина и пользовательское мобильное приложение. С витриной всё по классике — покупатель заходит на сайт, проводит какое-то время, выбирая товары и наполняя корзину, изучает карточки товаров. Финальный шаг здесь — оформление заказа. После этого заказ передаётся на дальнейшую обработку в бэк-офис.

Вообще, бэк-офис для интернет-магазина — это система, в которой над товарами проводится уйма действий: мы прописываем участие товаров в определенных акциях, подвязываем к этому баннеры, выделяем бренд-зоны и прочее. Само собой, заказы обрабатываются здесь же. Когда покупатель завершает оформление заказа и заказ поступает в бэк-офис, его надо подтвердить. Происходит это автоматически, если мы уже знаем этого покупателя, или оператором в ручном режиме по привычной всем схеме «Привет, вы тут заказали кое-что, подтверждаете, данные верны?» и прочее. И здесь уже кончается участие бэк-офиса в процессе формирования доставки, заказ подтверждается, статус меняют с «Обработано» на «Собирается». Заказ в WMS (где его резервируют, собирают, заказывают товары, которых нет и которые оформляются под заказ у поставщика) и в это же время он может начинать маршрутизироваться логистами. По большому счету, WMS и логистика — это независимые системы, работа с заказом в которых ведется параллельно.

Тем временем на складе

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

Последовательность важна, потому что мы доставляем нашим покупателям заказы в специальных ящиках «Перекрёстка». А с ящиком штука какая — он прямоугольный. Как и большинство ящиков.

Поэтому надо одновременно соблюсти два условия — и максимально заполнить сам ящик, чтобы клиенту не приехало два ящика, заполненных лишь наполовину (оно и неэкономично, и неэкологично, да и вообще как-то странно), и заполнить ящик по принципу «от тяжелого к легкому». Система учитывает размер товара и его упаковки. Зная это и параметры ящика, можно формировать заказы так, чтобы ящик наполнялся максимально. Это же позволяет избавиться от ситуаций, когда машина курьера вроде бы выехала на смену на все 100% загруженная ящиками, но полупустыми.

А ещё система пишет для складского рабочего, в каком именно порядке собирать заказ. Мало кому хочется получить ящик, в котором добрый сотрудник склада положил три десятка яиц на самое дно, заботливо уложив сверху 10 пакетов молока и пару килограммов овощей, например. С молоком-то точно всё будет ОК, чего не скажешь о яйцах. Всякие хрупкие печеньки — тоже всегда на самом верху.

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

Система все учитывает и строит маршрут, благодаря которому сотрудник собирает заказ в нужной последовательности — терминал ведет его к правильным стеллажам. Если утрировать, выглядит работа клиентской части приложения на самом деле так «Парень, идём к Б4, берем 5 вон тех пакетов с мукой, кладем на самый низ ящика. Потом с А2, захвати молочки. Нет, не этой, вон в той ячейке лежит».

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

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

Под капотом

Наши приложения мы пишем на Swift и Kotlin (iOS и Android соответственно). Весь бэкенд при этом крутится на PHP, базы данных мы решили делать на Postgres, за брокера у нас Rabbit mq.

Да, понятно, что в 2019 все всё делают, отталкиваясь от принципа mobile first, но у нас как-то сложилось, что сайт всё же ближе и роднее. Работает он на Lavarel. В сторону микросервисов тоже только начинаем двигаться, поэтому прямо сейчас и сайт, и приложение, это такой здоровенный монолит, который сидит и ждёт, чтобы его начали уже растаскивать на микросервисы.

Упомянутая Postgres, кстати, показывает себя как бутылочное горлышко время от времени, поэтому будем что-то менять. Активно используем балансировщики, потому что нагрузка на системы может принимать весьма разные значения.

Всё это добро уютно располагается на серверах в таком виде:
16 application-серверов с PHP-FPM и Postgres, у Postgres 1 master и 4 slave. Как видите, никаких велосипедов. Весь бэк-офис основательно проинтегрирован с внутренними системами — WMS, складскими, логистическими, учетными и маркетинговыми.

Мы запустили мобильное приложение и сайт в 2017-м. Сегодня средняя нагрузка на систему составляет около 6 000 заказов в сутки. С одной стороны, вроде как не очень много, с другой — всё же стоит учитывать, что это не размазано ровным слоем на 24 часа, люди не заказывают продукты круглосуточно, здесь тоже есть подвязка на стандартную активность в рабочее время. Самих запросов к PHP (включая API) порядка 70 000 за 5 минут.

Путь заказа

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

Приложение для курьеров мы сами делали под Android, как я уже писал, на Kotlin. Именно в него и вшита маршрутизация, возможность связи с клиентом (мы прячем номер клиента, у водителя только кнопка «Позвонить»), возможность отредактировать заказ и что-то убрать, печать чека, а также сама оплата заказа.

Отдельно про телеметрию: приложение считает всё: и время в пути, и время приезда к клиенту, и время отъезда, это сильно помогает строить множество аналитических отчетов и отслеживать логистику. Например, курьер какое-то время не двигается, а вообще-то должен —с ним связываются, уточняют, всё ли ОК. Связка с логистами в этом плане очень важна, потому что бывают ситуации, когда курьер, например, в 15.00 должен быть на одном адресе, а в 15.30 — на другом. Но на первом адресе случилась заминка из-за пропускного режима во дворе, шлагбаум или ворота, пришлось потратить дополнительно минут 10 на то, чтобы связаться с клиентом, чтобы клиент связался с охраной и прочее, вы знаете, как это бывает.

Но с точки зрения клиента на 15.30 это вообще ни разу не его проблемы, он ждет заказ к указанному времени. Поэтому водитель связывается с логистами, они внимательнее следят конкретно за его телеметрией, и сами связываются со следующим клиентом, уточняя временной интервал доставки из-за заминки на шлагбауме. Конечно, в любом случае грустно, когда курьер опаздывает. Но когда он опаздывает и не предупреждает об этом — это ещё хуже.

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

Спасибо, что дочитали.

FavoriteLoadingДобавить в избранное
Posted in Без рубрики

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *