Доставку заказывали? Как «Перекрёсток» доставляет 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, или о приложениях для водителя или складских рабочих, или о маршрутизации, тогда просто напишите об этом в комментариях, и я сделаю отдельный пост.

    Спасибо, что дочитали.
    X5 Retail Group
    Все о цифровой трансформации ритейла

    Комментарии 36

      +2

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

        +2
        Я думаю, что это просто малореально.
        Ocado, например, дает заранее за несколько месяцев забронировать слот доставки в неделю перед Рождеством. Думаю, это не спроста сделано, видимо повышенный спрос, а держать ресурсы в несколько раз больше ради одной недели никто не будет.
        +3
        Очень интересно было бы почитать про мобильное приложение, его возможности, необходимость содержания двух кодовых баз для разных платформ и способы одновременного релиза, где размещаются приложения (в общем маркете или в корпоративном), принципы обмена данными с сервером, способы борьбы с повышенным расходом аккумулятора в режиме постоянной телеметрии. Как спрятали телефон клиента от курьера: сделали звонок через sip или обычный gsm-звонок на шлюз c программным донабором добавочного? Кстати, а как это сделать правильно? Решение добавлять в номер символы паузы перед тональным набором добавочного номера мне кажутся прошлым веком, в истории звонков некрасиво смотрятся, но изящного решения я не нашел (а вот ЯТакси нашли).

        Отдельно хочется узнать, как решалась проблема с фоновой телеметрией (когда приложение свернуто) — я как начинающий разработчик так и не смог побороть это ограничение в ios.
          0
          Для курьеров используется парк промышленных устройств на Android, потому приложение выдачи заказов написано под Android,
          проблему с выключением фонового отслеживания GPS не требовалось решать для этой платформы.
          Вопрос потребления энергии решается повышенной емкостью батарей устройств и доступности зарядки в автомобиле :)
          Что же касается нашего приложения для клиентов, где можно заказать товары, то оно написано под две платформы.
          Приложения для внутреннего использования обновляются через собственный сервис, есть идеи посмотреть в сторону Android Enterprise для этого.

          Номер телефона прячется посредством вызова через дополнительный сервис.
          Сначала был обычный телефонный вызов на общий номер КЦ в котором через DTMF передавался айди, и дальше станция набирала номер клиента,
          затем перешли к схеме с вызовом через дополнительный сервис, т.е. после нажатия кнопки связи с клиентом в приложении, отправляется REST запрос на сервис,
          затем этот сервис совершает два исходящих звонка на номер курьера и клиента.
            0
            А почему используются именно промышленные устройства? Я правильно понимаю, что это Zebra? Всегда удивлял дикий ценник на них. Разве не проще набрать обычных Android-смартфонов и планшетов и в два раза сэкономить на железе?
              0
              Увидел ниже, что речь об Urovo. Но пока все так же непонятно, почему курьерам не подходит устройство B2C сегмента =(
                0
                Потому что надежность и отказоустойчивость девайсов В2С ниже. Когда у курьера на маршруте ломается терминал — это очень неприятно и эти риски проще устранить более надежным оборудованием.
          +4
          Отличная статья, спасибо, очень интересно про склады!

          Очень интересно, на какой нагрузке и какого размера базе postgre стал узким местом?

          Как переживаете ситуации, в которой датацентр, где всё это работает, вдруг перестал быть доступен?
            0
            Про нашу WMS систему мы обязательно напишем отдельный пост! Спасибо за ваш интерес.
            Как вы понимаете, размер базы данных не всегда единственный параметр, вызывающий проблемы с производительностью. Появление новых бизнес-требований заставляет задумывать об оптимизации. Например, когда необходимо сократить время ответа базы в несколько раз при формировании каких-то отчетов и выгрузок.
            Исторически WMS система работала на территории склада, но со временем это стало создавать проблемы с поддержкой, когда количество складов стало увеличиваться. Поэтому все переехало в единый ЦОД и сейчас идет процесс построения геораспределенной серверной площадки, которая позволит перестать бояться неработающего ЦОДа.
            +3
            Отличный сервис, перестали ходить в оффлайн ретейл благодаря вам.

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

            Прям хоть нанимайся к вам и реализуй)
              +1
              И то верно. Тут и развитие идеи предложили.
                0
                Я вам больше скажу, что эту идею услышали и уже внутри X5 пилят =)
              0
              Интересная статья, спасибо.
              Расскажете, как интегрировали сканеры складских сборщиков заказов?
                0
                По сканеру все просто.
                Он подключен по Bluetooth к ТСД на Android, который воспринимает его как устройство ввода.
                +1

                Пользуюсь постоянно, и могу сказать что 4 пункта "для стороннего наблюдателя" в 90% случаев можно дополнить еще двумя:
                1.5) во время оформления заказа получил оповещение что три-четыре товара уже недоступны, пошел менять, возврат в п.1
                2.5) в ночь после заказа магазин снимает еще пару позиций потому что их нет и, скорее всего, никогда и не было (например полумифический хлеб артикул 447392, который я уже точно с десяток раз добавлял в корзину но не получил ни разу, так как он отваливался либо до оформления либо до выезда :)
                Раньше практиковали замены, теперь что-то перестали.


                Хотелось бы видеть доп возможности, такие как оповещение о низком количестве товара в каталоге и "типовые" сборки которые можно быстро наполнять (например заранее создается список товаров, к каждому по желанию можно добавить несколько аналогов — потом при создании нового заказа по шаблону позиции заполняются максимально полно из доступного)

                  0
                  Спасибо за ваше постоянство!
                  Мы постоянно работаем над улучшением нашей механики замен. Но мы бы хотели добиться такого, чтобы замены вообще не требовались при комплектации заказов.
                  Спасибо за точное указание артикула товара, который вызывает постоянные проблемы. Мы уже передали эту информацию коллегам для исправления и проработки.
                  0
                  Отличный пост, сейчас как раз организую подобное на нашем предприятии, появилась пара вопросов:
                  1. Что за девайс у товарища на руке (картинка №2)?
                  2. на 1-й картинке на стеллаже №26 (Справа), на 4-й полке снизу, справа 2 ячейки на адресном складе. И коробка чая стоит ровно посередине между ними. Когда товарищ будет её брать он отсканит ячейку №1 или №2 (справа)? и как решается проблема с остатками в ячейках на этом примере?
                    +1
                    1. ТСД на Android от Urovo, модели разные, постоянно ищем и тестируем новые аппараты
                    2. При отборе сотрудник не сканирует ячейку, т.к. мы резервируем товар в конкретной ячейке и формируем задание на отбор из этой ячейки. Сотрудник выполняющий задание может отобрать товар из той ячейки где он зарезервирован либо отправить его в брак или утерю. В этом случае проблемы с остатками нет. Т.к. у ячеек нет физических границ товар может оказаться в соседней ячейке, но это не вызывает проблем у склада.
                      +1
                      Спасибо за ответ! по п.1 предлагал подобный девайс руководству, было отклонено под предлогом что он недостаточно «Антивандальный». Можете сказать из вашего опыта? насколько часто в среднем они выходят из строя по причине что «Его уронили», а потом «На него уронили ящик»?
                      по п.2: не совсем понял, «у ячеек нет физических границ», у вас довольно большой ассортимент. Сотрудники, которые занимаются сборкой заказов, не могут помнить все наименования наизусть… т.е., насколько я понимаю, сотруднику «Сборщику» на тсд должно прийти задание типа «Иди на такой-то ряд, и с того -то стеллажа, с такой-то ячейки собери 3 пачки»… а если вы говорите что товар может оказаться на соседней ячейке, тогда появляется высокая вероятность ошибки. или я ошибаюсь? он же соберет не тот товар?
                        0
                        Сотрудник видит на ТСД номер стелажа, полки и ячейки откуда необходимо взять товар, а так же наименование и фотографию товара. Задание отбора можно выполнить только сосканировав штрихкод товара, поэтому отобрать не тот товар не получится.
                    +1
                    Спасибо, за информацию.
                    Очень интересно узнать так же о WMS — как внедряли, с какими сложностями столкнулись, как синхронизируются остатки в WMS с учетной системой, как происходит инвентаризация, останавливаете ли склад и т.д., о приложениях для водителя и о приложении для складских рабочих.
                    Всегда интересно узнать как «это работает» во «взрослых» компаниях.
                      +1
                      Поддерживаю. Всю статью говорят о WMS, но даже непонятно, что за WMS. X5RetailGroup, или до сих пор EXCEED + NQ?
                        0
                        Синхронизация остатков: WMS получает из учетной системы документы поставки, на основании этих документов создаются партии товара, после чего товар размещается в ячейки. Товар из ячеек отбирается для заказов и уезжает клиентам. После продажи заказа WMS получает чеки из приложения курьера и отправляет их в учётную систему, там товар списывается на основании чеков. В WMS товар списывается после изменения статуса заказа на «выкуплен» или «выкуплен частично»

                        Приложение для складских рабочих: приложение на Android. В котором в webView крутится одностраничное веб-приложение на knockout.js и jQuery, которое по api стучится в WMS.
                        0
                        Можно подробнее о проблемах с Postgres и как планируете решать?
                          0
                          Обязательно напишем отдельный пост про это. Нам есть о чем рассказать и, возможно, помочь кому-то избежать множества грабель!
                          0
                          Отличная статья!!! Жду продолжения про работу складов, как всё устроено!!! Давно не читал что-либо с таким интересом! Молодцы!!!
                            +1

                            Сделайте книгу рецептов (где все ингредиенты есть в вашем магазине), и возможность прямо из книги рецептов добавления всех продуктов в корзину нажатием 2 кнопок — количество порций и добавить (список продуктов с чекбоксами с возможностью исключить имеющийся продукт из подборки)

                            +1
                            Я так понимаю, что пока все простое, потому что объемы маленькие. А так вручную будет не очень дешево собирать заказы на большом объеме. `
                            Вот последняя платформа Ocado: www.youtube.com/watch?v=4DKrcpa8Z_E
                            Возможно, у Перекрестка дойдет когда-нибудь до этого уровня. Хотя у Окадо эта итерация заняла несколько лет даже имея многолетний опыт.
                              0
                              Да, мы уже начинаем готовится к тому, чтобы автоматизировать максимально все ручные операции и, конечно же, сборку на складе. Сейчас на рынке есть несколько интересных решений, которые мы рассматриваем и готовимся к постепенной роботизации склада.
                              +2
                              Очень неполохой и даже полезной была бы опция заказа с самовывозом. Делаешь заказ, указываешь в каком магазине забирать и не паришься успеть домой к приезду курьера. Случаи ведь разные бывают: задержался на работе, пробки, мама просила заехать «никаких отговорок» и т. п. Мне вот очень не хватает, все равно магазин прямо по дороге домой — зашел, забрал и не ходишь по магазину и не стоишь в очереди на кассу. Я так в Мяснове и Отдохни (сеть магазинов такая) делаю.
                                0
                                А у нас есть такая функция и она так и называется: самовывоз. При оформлении заказа вы можете выбрать, что вам удобнее: получить заказ курьером (этот вариант выбран по умолчанию) или забрать заказ в магазине. Правда, далеко не все магазины доступны к выбору, но их количество постоянно увеличивается.
                                  0
                                  Это здорово, проверю на ближайшем магазине, но мне кажется, что там нет такой функции.
                                0

                                "… С витриной всё по классике — покупатель заходит на сайт, проводит какое-то время, выбирая товары и наполняя корзину, изучает карточки товаров..."
                                В поисковой части ведь целый мир. Что за движок используете?

                                  0
                                  Вопрос от коллег:
                                  а какой состав команды (роли, количество), которая занимается этим продуктом?
                                  Софт пишется внутри (приложение для курьеров) или заказная разработка?
                                    0
                                    А в сторону конвейерных систем pick-to-light не смотрели? Думаю будет куда как дешевле окадо )). Плюс практически не требуются сканеры. Плюс сборщиков учить не надо. Правда есть другие подводные камни: пластиковые кнопки световых модулей быстро протирались от нажатий пальцами в тряпичных перчатках. )))

                                    Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                                    Самое читаемое