Хабрахабр

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Под капотом

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

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

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

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

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

Путь заказа

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

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

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

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

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

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

Теги
Показать больше

Похожие статьи

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

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

Кнопка «Наверх»
Закрыть