Когда заходит речь о модных и передовых технологиях, ритейл, особенно строительный, — последнее место, где их станут искать. Ну что там может быть интересного: сайт на битриксе и мобильное приложение с программой лояльности? И в каких-то случаях этот стереотип не врёт, но «Леруа Мерлен» — совсем другая история. Наша IT‑инфраструктура мощна, как лапищи мемного волка, а команда разработки столь же хороша.

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

React

Илья Антонов
фронтенд-разработчик
Я использую React уже пять лет. До этого был фронтенд на кондовом jQuery, но в какой‑то момент стало понятно: так дальше нельзя. Для написания UI нужен UI‑фреймворк, а не костыль для браузеров десятилетней давности.
На момент перехода у нас был выбор из трёх технологий. Angular отпугнул своей сложностью. Vue.js тогда считался молодым фреймворком и вызывал определённый скепсис. Сейчас в «Леруа Мерлен» некоторые части фронтенда пишутся на Vue, но всё равно React кажется более зрелой технологией: больше комьюнити, готовых решений, вспомогательных модулей.
В React подкупает простота основной концепции. Думаю, каждый фронтенд‑разработчик, впервые с ней познакомившись, испытал небольшое «вау». UI как функция пропсов: меняешь аргументы — немедленно меняется вёрстка? Вау!
Конечно, любая простая концепция, сталкиваясь с реальной жизнью, неизбежно обрастает нюансами, оговорками, дополнениями, становясь в конце концов не такой уж простой. К React понадобился Redux, а к нему, в свою очередь, — Redux-Saga. Добавим, что у нас микрофронтендная архитектура, — и получится уже достаточно сложная вещь, которая если и вызовет «вау», то совсем в другой тональности.
Новые технологии создаются для того, чтобы играючи решать проблемы, стоявшие перед старыми
Саги, микрофронтенд, единое хранилище данных — каждая из этих концепций хороша, но в сочетании иногда вылезают непредвиденные побочные эффекты. Например, усложняются интеграционные тесты. Чтобы достоверно воссоздать окружение, в котором работает сага, нужно инициализировать хранилище целиком. Также не получается в полной мере воспользоваться преимуществами ленивой загрузки в Webpack Module Federation: приходится сразу запускать саги отдельных модулей. Впрочем, это уже проблемы не React самого по себе, а нашей архитектуры. Возможно, в будущем мы откажемся от саг в пользу чего-то другого.
Вернёмся к React. В чём ещё он доставляет неудобства? Мне не очень нравится переход на хуки. Конечно, у хуков есть свои преимущества: они упрощают решение многих задач, но при этом делают код концептуально более сложным. Среднестатистический разработчик лучше понимает ООП-парадигму, чем ФП. А хуки — это не только ФП, но ещё и некоторая «магия» на грани хака. Формально, конечно, никто не заставляет на них переходить: можно продолжать писать в ООП-стиле. Но по факту всем понятно, что раз такова «генеральная линия партии», то, чтобы пользоваться новейшими фичами React, в какой-то момент перейти придётся. И чем дольше тянуть, тем будет больнее.
Помните, выше я говорил о простоте и прозрачности основной концепции и о том, как она сталкивается с реальностью? То место, где удар о реальность оказался особенно жёстким, — это рендеринг. Facebook потратил немало усилий, чтобы оптимизировать рендеринг, но в результате его механизм перестал быть прозрачным. Теперь его профилирование иногда напоминает гадание на кофейной гуще. Надеюсь, в будущем появятся более удобные инструменты для этого.
Тем не менее, несмотря на озвученные проблемы, я считаю, что React — это лучший UI‑фреймворк для построения интерфейсов среднего масштаба. Vue близок по удобству, но он всё же лучше подходит для приложений поменьше. И небольшой, но приятный бонус — React Native. У нас есть пара мобильных приложений на нём, и это неплохой опыт. Но здесь, конечно, боль — производительность. Поэтому в основном мы пишем нативные приложения.

Compose Multiplatform

Алексей Гладков
технический архитектор
Прежде всего нужно сказать, что это очень молодая технология. Релиз Compose Multiplatform 1.0.0 состоялся совсем недавно — в декабре 2021 года. JetPack Compose, на котором он основан, релизнулся в июле. Однако для меня эти технологии уже старые знакомые: в «Леруа Мерлен» начинали пользоваться ими ещё с альфа-версий, принимали участие в тестировании. И, я бы сказал, мы гордимся этим.
Думаю, что Compose скоро станет индустриальным стандартом в мобильной разработке. Для этого есть все предпосылки. Google, судя по пресс-релизам, будет активно продвигать JetPack Compose как основное средство создания Android-приложений, так что игнорировать его в любом случае станет тяжело. А если так — почему бы не попробовать использовать мультиплатформенную версию фреймворка? За которой, между прочим, стоит JetBrains, а это уже кое-что говорит о качестве и перспективах.
Кроме того, у Compose нет действительно достойных конкурентов. Самый близкий — это Flutter от того же Google. Но у него есть один огромный недостаток — Dart. Не то чтобы это был плохой язык, но он так и не смог стать популярным за пределами своей ниши. И поиск Dart-разработчиков — квест не из простых. Видимо, люди в Google сами это поняли, раз выпустили конкурирующий фреймворк и начали его продвигать. Можно ожидать, что в будущем Flutter станет потихоньку отмирать.
Впрочем, справедливости ради нужно отметить, что Kotlin, на котором основан Compose, — также не самый распространённый язык. И всё же это JVM-совместимый язык общего назначения, и на него достаточно легко и приятно перейти с Java. Его перспективы видятся мне более радужными.
«Одно кольцо, чтобы править всеми»
Какие ещё есть конкуренты? Electron и React Native занимают несколько другую нишу. Приложение на них, вероятно, обойдётся дешевле, потому что проще и дешевле найти JS-разработчика, да и скорость разработки на JS выше (до момента, когда придёт пора выплачивать технический долг). Но есть одно огромное но — производительность. Скажем так, когда пишешь приложение на Compose, нужно специально приложить усилия, чтобы оно тормозило. Сделать какую-нибудь вьюху с таблицей на десятки тысяч ячеек или что-то подобное. В случае Electron нужно прилагать усилия, чтобы приложение не тормозило. React Native находится где-то посередине, но для оптимального UX всё равно лучше использовать что-то другое.
Если отвлечься от анализа рынка и поговорить о субъективных ощущениях, то Compose очень приятно использовать. Код получается лаконичным, выразительным. Одна из целей, заявленных Google при создании JetPack Compose, — уменьшение количества кода, избавление от многословия. С этой задачей Compose справляется прекрасно и при этом не теряет в гибкости.
Разумеется, есть и ложка дёгтя. Главная проблема заключается в том, что это молодая технология. Конечно, многое для неё уже сделано. Есть поддержка IDE, импорт макетов из Figma. Но при этом часто бывает, что сталкиваешься с проблемой, гуглишь её и получаешь два результата. Не в смысле «несколько ссылок на две разных страницы». Просто — два. Две строчки поисковой выдачи. Так что для StackOverflow‑ориентированного программирования это не лучший выбор.
Ну и, как говорил мой коллега выше, изящество концепций часто разбивается о суровую реальность. Что касается кроссплатформенности, то какие-то специфичные вещи всё равно приходится реализовывать нативно. Но это неизбежная проблема: нельзя создать кроссплатформенный фреймворк, не продырявив парочку абстракций.

Kotlin

Дмитрий Терехов
разработчик
В последние годы Kotlin быстро набирает популярность. В основном это происходит в мобильной разработке. Алексей уже рассказал о Compose, но Kotlin стал популярен ещё до него. Я читал данные, что 80 % кода 1000 топовых приложений в Google Play написано на Kotlin. Не знаю, правда или нет и как это считалось, но в принципе звучит правдоподобно.
Нельзя сказать, что Kotlin — нишевый язык для мобильной разработки: с серверной стороны он также хорош. Собственно, я и познакомился с ним в бэкенд-разработке, и там язык показал себя прекрасно. Всё начиналось с отдельных сервисов, а после решили все новые сервисы писать на Kotlin. Что отдельно приятно — интероперабельность с Java, возможность постепенно переводить проект с одного языка на другой либо использовать их параллельно на постоянной основе.
Чем не устроила чистая Java? Да не то чтобы совсем не устроила: это прекрасный язык, но местами слишком консервативный и многословный, c большим количеством ненужного boilerplate-кода. Разработка на Kotlin быстрее и приятнее. Также в нём много интересных фич. Если говорить о моих любимых — на первом месте однозначно корутины. Это оптимальный способ писать асинхронный код, намного более удобный, чем джавовские Future и @Async. На втором месте — пожалуй, Sequence. Ленивая коллекция — абстракция, которая позволяет работать с потоком данных как с обычной коллекцией. Ну и на третьем месте — удобство построения DSL. Очень просто и лаконично можно сделать свой язык описания данных на базе функций-билдеров. В официальной документации есть пример, как средствами Kotlin «реализовать» HTML. Всем интересующимся рекомендую ознакомиться. И это не случайная возможность языка, так и задумано, и возможности DSL-строительства в нём целенаправленно поддерживаются.
Логотип языка Kotlin по форме похож на остров Котлин в Финском заливе… Шутка: это просто стилизованная буква К
Kotlin — кроссплатформенный. Java создавалась с таким расчётом, чтобы «работать в каждой микроволновке». Но по факту она оказалась ограничена сервером и мобильными устройствами. Java-апплеты давно вымерли, Java на десктопе прославилась отвратительным UI (привет, Swing). Kotlin же компилируется в JS, и благодаря Compose Multiplatform можно писать на ней приложения для десктопа с вполне приятным интерфейсом.
Некоторые фичи Kotlin вызывают у меня двойственное отношение. Теоретически они должны упрощать жизнь, но на практике выходит по-всякому. Например, иммутабельность — спору нет, она сейчас в тренде, как и всякая прочая функциональщина. Но это требует особого выверта сознания, который есть не у каждого разработчика. И, несмотря на теоретические преимущества иммутабельности (безопасность, чистота кода и т. д.), на практике код становится сложнее и в неумелых руках может привести к большим потерям по памяти. Конечно, Kotlin не запрещает писать код с использованием привычных изменяемых структуры данных. Но концептуально язык заточен под иммутабельные коллекции, их возвращают все основные методы обработки коллекций (map, filter и прочие), и, разумеется, не хочется без необходимости плыть против течения.
Одной из главных фич языка считается null safety. Но знаете, иногда хочется поменьше null safety. В Kotlin переменные бывают nullable и не nullable. На практике же нередко случается третий вариант: теоретически nullable, но вот прямо сейчас бизнес-логика гарантирует, что не nullable. В Java в этом случае можно просто пренебречь проверками на null: если возникнет NPE, значит, с бизнес-логикой в любом случае что-то не так и надо дебажить. В Kotlin такой третьей опции нет, нужно городить частокол из двойных восклицательных знаков, заниматься прочими синтаксическими формальностями — и в итоге прийти к тому же отлавливанию NPE, только более многословному.
Наконец, реализация статических членов класса через сопутствующие объекты кажется мне излишне громоздкой. Но это уже мелочи.

Kubernetes

Павел Клюев
инженер по доступности сервисов
О Kubernetes сложно что-то рассказать. В смысле — сложно, например, ответить на вопрос «почему вы выбрали Kubernetes?» Может, потому, что это индустриальный стандарт? Нет, конечно, есть OpenShift и некоторые другие решения, но там под капотом всё равно Kubernetes. Если в вашем продукте в принципе требуется оркестрация контейнеров, вы будете использовать Kubernetes либо напрямую, либо в какой-то обёртке. Обёртки нужны либо мелкому клиенту, который не может сам разобраться в нюансах, либо крупному, который хочет быстро и без лишнего головняка.
Поэтому буду говорить не о самом Kubernetes, а о его использовании. На прошлой работе мы пришли к нему от архитектуры «одно приложение — один физический сервер». У нас были приложения с более-менее константной нагрузкой, а были «тяжёлые» вычисления, которые запускались раз в неделю, а в остальное время отведённые для них мощности простаивали. С помощью Kubernetes мы реализовали балансировку нагрузки: теперь неиспользуемые мощности доставались другим приложениям. Но, разумеется, Kubernetes — это не просто балансёр, а намного больше.
Без Kubernetes сложно представить себе микросервисную архитектуру. А без микросервисной архитектуры — современное высоконагруженное… да даже средненагруженное приложение. Но не все хорошо умеют в микросервисы. Был смешной случай, когда «распиливали» монолит на PHP, написанный таким образом, что всё оказалось связанным со всем. Модули были настолько плохо абстрагированы друг от друга, что для запуска любого из них требовалось приложение целиком. И промежуточная архитектура выглядела так: приложение разбили на микросервисы, но при этом каждый микросервис содержал приложение целиком. В каждом контейнере активен был только один какой-то компонент, остальное приложение тянулось за ним в нагрузку. Но, конечно, это проблема не Kubernetes, а разработчиков, не умеющих в decoupling.
Kubernetes в переводе с греческого значит «кормчий»
Если говорить о недостатках — ну, обёртки не существовали бы, если бы в них не было необходимости. Kubernetes требует некоторой культуры работы с ним, хорошего понимания его абстракций. Без этого понимания можно часами сидеть, уставившись в доки, и не понимать, откуда начинать делать то, что хочешь сделать. В этом плане OpenShift, например, намного дружелюбнее к новичку. Там отличный UI, в котором быстро понимаешь, что делаешь и зачем.
Есть две вещи, которые раздражают меня лично. Первая — когда только начал использовать какую-то фичу, а в следующей версии она уже deprecated. Нужно внимательно следить за развитием технологии, чтобы такого не было. И второе — писать Custom Resource Definitions. Трудоёмкая работа, которую не автоматизируешь: кто, кроме нас, напишет определения наших ресурсов? Хотя сами по себе CRD — отличная штука, в сочетании с Kubernetes API позволяют очень гибко автоматизировать управление ресурсами.

Airflow

Андрей Ларионов
руководитель практики инженеров данных
К необходимости использования Apache Airflow мы пришли не сразу. Конечно, запуск процессов преобразования данных — очень распространённая бизнес-задача. Но в самых простых случаях можно банально запускать запрос cron’ом. Когда этого перестаёт хватать? Когда становится не один запрос, а несколько, причём одни зависят от результатов других. И особенно — если мы хотим уметь прервать обработку данных, а затем корректно возобновить. Конечно, эта задача, в принципе, тоже решается на коленке: создаём в БД метатаблицу, куда складываем данные о ходе выполнения операций. Но это уже, как вы понимаете, намного более муторно. И всё сильнее искушение как-то эти вещи автоматизировать. Чем, собственно, Airflow и занимается.
Airflow — оркестратор процессов обработки данных. Или, в принципе, любых других процессов, но чаще всего его используют именно в области обработки данных. Его основная сущность — это DAG, направленный ациклический граф. Вершины этого графа — отдельные процессы, а стрелочки — то, какие процессы должны завершиться прежде, чем другие стартуют. У Airflow прекрасный UI, где эти DAG'и очень удобно смотреть.
Помимо этого, для описания процессов в Airflow есть коннекторы и операторы. Коннекторы отвечают за то, откуда данные брать (или куда класть), а операторы — за то, что с данными делать. И всё это описывается на языке Python, что приятно, поскольку он — один из самых лёгких и распространённых.
Пристегните ремни: сейчас ваши данные будут летать
Экосистема Airflow весьма развита. Готовые коннекторы и операторы покрывают примерно 90 % потребностей, редко приходится писать что-то своё. Из недавних случаев один был очень простым: надо было переопределить оператор, чтобы он кидал ошибку другого типа. Другой посложнее: периодически возникали ошибки при запуске задач на сервер Postgres в «Яндекс.Облаке». Стандартный Postgres-коннектор не умеет автоматически переключаться между master и slave.
Альтернативы у Airflow есть — например, Luigi или Argo. Luigi — модуль для Python, используемый для тех же задач, проще в эксплуатации, но менее гибкий. У Argo (и основанного на нём Kuberflow) упор больше на контейнеры, чем на процессы обработки данных. В общем-то, нельзя сказать, что кто-то из них лучше, а кто-то хуже: у каждого своя ниша.
Airflow невероятно гибкий. Как правило, весь потенциал этой гибкости не требуется конкретной организации с её конкретными задачами. Мы в какой-то момент обнаружили, что значительная часть DAG'ов имеет достаточно похожую, типовую структуру. И создали несколько инструментов, позволяющих такие DAG'и генерить из конфигурационных файлов. Об одном из этих инструментов я уже писал.
Я доволен Airflow практически полностью. С моей точки зрения, у него нет недостатков — только недочёты. Есть несколько запутывающих моментов в API, на которые регулярно напарываются новички. Во-первых, это параметр schedule_interval. Запланировал DAG, а он не выполняется? Это потому, что первое выполнение DAG'а планируется на start_date + schedule_interval. На выяснение этого нюанса я однажды убил целый рабочий день. Подозреваю, что это не рекорд.
Во-вторых, притча во языцех — execution_date. Все думают, что это момент начала выполнения DAG'а, пока не наткнутся на какое-нибудь непонятное поведение. Тогда лезут в документацию и узнают, что это начало текущего интервала. Тоже очень интуитивно. Впрочем, в грядущей версии Airflow разработчики обещали изменить название этого параметра. Так что вместо проблемы с его пониманием будут проблемы с миграцией.
Ну и наконец, возможно, и не минус, но особенность — время в UTC. У нас есть магазины в разных часовых поясах, соответственно надо следить, чтобы данные брались в правильных временных интервалах.

Расскажите в комментариях — каков ваш личный опыт работы с технологиями из статьи?
Когда заходит речь о модных и передовых технологиях, ритейл, особенно строительный, — последнее место, где их станут искать. Ну что там может быть интересного: сайт на битриксе и мобильное приложение с программой лояльности? И в каких-то случаях этот стереотип не врёт, но «Леруа Мерлен» — совсем другая история. Наша IT‑инфраструктура мощна, как лапищи мемного волка, а команда разработки столь же хороша.

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

React

Илья Антонов
фронтенд-разработчик
Я использую React уже пять лет. До этого был фронтенд на кондовом jQuery, но в какой‑то момент стало понятно: так дальше нельзя. Для написания UI нужен UI‑фреймворк, а не костыль для браузеров десятилетней давности.
На момент перехода у нас был выбор из трёх технологий. Angular отпугнул своей сложностью. Vue.js тогда считался молодым фреймворком и вызывал определённый скепсис. Сейчас в «Леруа Мерлен» некоторые части фронтенда пишутся на Vue, но всё равно React кажется более зрелой технологией: больше комьюнити, готовых решений, вспомогательных модулей.
В React подкупает простота основной концепции. Думаю, каждый фронтенд‑разработчик, впервые с ней познакомившись, испытал небольшое «вау». UI как функция пропсов: меняешь аргументы — немедленно меняется вёрстка? Вау!
Конечно, любая простая концепция, сталкиваясь с реальной жизнью, неизбежно обрастает нюансами, оговорками, дополнениями, становясь в конце концов не такой уж простой. К React понадобился Redux, а к нему, в свою очередь, — Redux-Saga. Добавим, что у нас микрофронтендная архитектура, — и получится уже достаточно сложная вещь, которая если и вызовет «вау», то совсем в другой тональности.
Новые технологии создаются для того, чтобы играючи решать проблемы, стоявшие перед старыми
Саги, микрофронтенд, единое хранилище данных — каждая из этих концепций хороша, но в сочетании иногда вылезают непредвиденные побочные эффекты. Например, усложняются интеграционные тесты. Чтобы достоверно воссоздать окружение, в котором работает сага, нужно инициализировать хранилище целиком. Также не получается в полной мере воспользоваться преимуществами ленивой загрузки в Webpack Module Federation: приходится сразу запускать саги отдельных модулей. Впрочем, это уже проблемы не React самого по себе, а нашей архитектуры. Возможно, в будущем мы откажемся от саг в пользу чего-то другого.
Вернёмся к React. В чём ещё он доставляет неудобства? Мне не очень нравится переход на хуки. Конечно, у хуков есть свои преимущества: они упрощают решение многих задач, но при этом делают код концептуально более сложным. Среднестатистический разработчик лучше понимает ООП-парадигму, чем ФП. А хуки — это не только ФП, но ещё и некоторая «магия» на грани хака. Формально, конечно, никто не заставляет на них переходить: можно продолжать писать в ООП-стиле. Но по факту всем понятно, что раз такова «генеральная линия партии», то, чтобы пользоваться новейшими фичами React, в какой-то момент перейти придётся. И чем дольше тянуть, тем будет больнее.
Помните, выше я говорил о простоте и прозрачности основной концепции и о том, как она сталкивается с реальностью? То место, где удар о реальность оказался особенно жёстким, — это рендеринг. Facebook потратил немало усилий, чтобы оптимизировать рендеринг, но в результате его механизм перестал быть прозрачным. Теперь его профилирование иногда напоминает гадание на кофейной гуще. Надеюсь, в будущем появятся более удобные инструменты для этого.
Тем не менее, несмотря на озвученные проблемы, я считаю, что React — это лучший UI‑фреймворк для построения интерфейсов среднего масштаба. Vue близок по удобству, но он всё же лучше подходит для приложений поменьше. И небольшой, но приятный бонус — React Native. У нас есть пара мобильных приложений на нём, и это неплохой опыт. Но здесь, конечно, боль — производительность. Поэтому в основном мы пишем нативные приложения.

Compose Multiplatform

Алексей Гладков
технический архитектор
Прежде всего нужно сказать, что это очень молодая технология. Релиз Compose Multiplatform 1.0.0 состоялся совсем недавно — в декабре 2021 года. JetPack Compose, на котором он основан, релизнулся в июле. Однако для меня эти технологии уже старые знакомые: в «Леруа Мерлен» начинали пользоваться ими ещё с альфа-версий, принимали участие в тестировании. И, я бы сказал, мы гордимся этим.
Думаю, что Compose скоро станет индустриальным стандартом в мобильной разработке. Для этого есть все предпосылки. Google, судя по пресс-релизам, будет активно продвигать JetPack Compose как основное средство создания Android-приложений, так что игнорировать его в любом случае станет тяжело. А если так — почему бы не попробовать использовать мультиплатформенную версию фреймворка? За которой, между прочим, стоит JetBrains, а это уже кое-что говорит о качестве и перспективах.
Кроме того, у Compose нет действительно достойных конкурентов. Самый близкий — это Flutter от того же Google. Но у него есть один огромный недостаток — Dart. Не то чтобы это был плохой язык, но он так и не смог стать популярным за пределами своей ниши. И поиск Dart-разработчиков — квест не из простых. Видимо, люди в Google сами это поняли, раз выпустили конкурирующий фреймворк и начали его продвигать. Можно ожидать, что в будущем Flutter станет потихоньку отмирать.
Впрочем, справедливости ради нужно отметить, что Kotlin, на котором основан Compose, — также не самый распространённый язык. И всё же это JVM-совместимый язык общего назначения, и на него достаточно легко и приятно перейти с Java. Его перспективы видятся мне более радужными.
«Одно кольцо, чтобы править всеми»
Какие ещё есть конкуренты? Electron и React Native занимают несколько другую нишу. Приложение на них, вероятно, обойдётся дешевле, потому что проще и дешевле найти JS-разработчика, да и скорость разработки на JS выше (до момента, когда придёт пора выплачивать технический долг). Но есть одно огромное но — производительность. Скажем так, когда пишешь приложение на Compose, нужно специально приложить усилия, чтобы оно тормозило. Сделать какую-нибудь вьюху с таблицей на десятки тысяч ячеек или что-то подобное. В случае Electron нужно прилагать усилия, чтобы приложение не тормозило. React Native находится где-то посередине, но для оптимального UX всё равно лучше использовать что-то другое.
Если отвлечься от анализа рынка и поговорить о субъективных ощущениях, то Compose очень приятно использовать. Код получается лаконичным, выразительным. Одна из целей, заявленных Google при создании JetPack Compose, — уменьшение количества кода, избавление от многословия. С этой задачей Compose справляется прекрасно и при этом не теряет в гибкости.
Разумеется, есть и ложка дёгтя. Главная проблема заключается в том, что это молодая технология. Конечно, многое для неё уже сделано. Есть поддержка IDE, импорт макетов из Figma. Но при этом часто бывает, что сталкиваешься с проблемой, гуглишь её и получаешь два результата. Не в смысле «несколько ссылок на две разных страницы». Просто — два. Две строчки поисковой выдачи. Так что для StackOverflow‑ориентированного программирования это не лучший выбор.
Ну и, как говорил мой коллега выше, изящество концепций часто разбивается о суровую реальность. Что касается кроссплатформенности, то какие-то специфичные вещи всё равно приходится реализовывать нативно. Но это неизбежная проблема: нельзя создать кроссплатформенный фреймворк, не продырявив парочку абстракций.

Kotlin

Дмитрий Терехов
разработчик
В последние годы Kotlin быстро набирает популярность. В основном это происходит в мобильной разработке. Алексей уже рассказал о Compose, но Kotlin стал популярен ещё до него. Я читал данные, что 80 % кода 1000 топовых приложений в Google Play написано на Kotlin. Не знаю, правда или нет и как это считалось, но в принципе звучит правдоподобно.
Нельзя сказать, что Kotlin — нишевый язык для мобильной разработки: с серверной стороны он также хорош. Собственно, я и познакомился с ним в бэкенд-разработке, и там язык показал себя прекрасно. Всё начиналось с отдельных сервисов, а после решили все новые сервисы писать на Kotlin. Что отдельно приятно — интероперабельность с Java, возможность постепенно переводить проект с одного языка на другой либо использовать их параллельно на постоянной основе.
Чем не устроила чистая Java? Да не то чтобы совсем не устроила: это прекрасный язык, но местами слишком консервативный и многословный, c большим количеством ненужного boilerplate-кода. Разработка на Kotlin быстрее и приятнее. Также в нём много интересных фич. Если говорить о моих любимых — на первом месте однозначно корутины. Это оптимальный способ писать асинхронный код, намного более удобный, чем джавовские Future и @Async. На втором месте — пожалуй, Sequence. Ленивая коллекция — абстракция, которая позволяет работать с потоком данных как с обычной коллекцией. Ну и на третьем месте — удобство построения DSL. Очень просто и лаконично можно сделать свой язык описания данных на базе функций-билдеров. В официальной документации есть пример, как средствами Kotlin «реализовать» HTML. Всем интересующимся рекомендую ознакомиться. И это не случайная возможность языка, так и задумано, и возможности DSL-строительства в нём целенаправленно поддерживаются.
Логотип языка Kotlin по форме похож на остров Котлин в Финском заливе… Шутка: это просто стилизованная буква К
Kotlin — кроссплатформенный. Java создавалась с таким расчётом, чтобы «работать в каждой микроволновке». Но по факту она оказалась ограничена сервером и мобильными устройствами. Java-апплеты давно вымерли, Java на десктопе прославилась отвратительным UI (привет, Swing). Kotlin же компилируется в JS, и благодаря Compose Multiplatform можно писать на ней приложения для десктопа с вполне приятным интерфейсом.
Некоторые фичи Kotlin вызывают у меня двойственное отношение. Теоретически они должны упрощать жизнь, но на практике выходит по-всякому. Например, иммутабельность — спору нет, она сейчас в тренде, как и всякая прочая функциональщина. Но это требует особого выверта сознания, который есть не у каждого разработчика. И, несмотря на теоретические преимущества иммутабельности (безопасность, чистота кода и т. д.), на практике код становится сложнее и в неумелых руках может привести к большим потерям по памяти. Конечно, Kotlin не запрещает писать код с использованием привычных изменяемых структуры данных. Но концептуально язык заточен под иммутабельные коллекции, их возвращают все основные методы обработки коллекций (map, filter и прочие), и, разумеется, не хочется без необходимости плыть против течения.
Одной из главных фич языка считается null safety. Но знаете, иногда хочется поменьше null safety. В Kotlin переменные бывают nullable и не nullable. На практике же нередко случается третий вариант: теоретически nullable, но вот прямо сейчас бизнес-логика гарантирует, что не nullable. В Java в этом случае можно просто пренебречь проверками на null: если возникнет NPE, значит, с бизнес-логикой в любом случае что-то не так и надо дебажить. В Kotlin такой третьей опции нет, нужно городить частокол из двойных восклицательных знаков, заниматься прочими синтаксическими формальностями — и в итоге прийти к тому же отлавливанию NPE, только более многословному.
Наконец, реализация статических членов класса через сопутствующие объекты кажется мне излишне громоздкой. Но это уже мелочи.

Kubernetes

Павел Клюев
инженер по доступности сервисов
О Kubernetes сложно что-то рассказать. В смысле — сложно, например, ответить на вопрос «почему вы выбрали Kubernetes?» Может, потому, что это индустриальный стандарт? Нет, конечно, есть OpenShift и некоторые другие решения, но там под капотом всё равно Kubernetes. Если в вашем продукте в принципе требуется оркестрация контейнеров, вы будете использовать Kubernetes либо напрямую, либо в какой-то обёртке. Обёртки нужны либо мелкому клиенту, который не может сам разобраться в нюансах, либо крупному, который хочет быстро и без лишнего головняка.
Поэтому буду говорить не о самом Kubernetes, а о его использовании. На прошлой работе мы пришли к нему от архитектуры «одно приложение — один физический сервер». У нас были приложения с более-менее константной нагрузкой, а были «тяжёлые» вычисления, которые запускались раз в неделю, а в остальное время отведённые для них мощности простаивали. С помощью Kubernetes мы реализовали балансировку нагрузки: теперь неиспользуемые мощности доставались другим приложениям. Но, разумеется, Kubernetes — это не просто балансёр, а намного больше.
Без Kubernetes сложно представить себе микросервисную архитектуру. А без микросервисной архитектуры — современное высоконагруженное… да даже средненагруженное приложение. Но не все хорошо умеют в микросервисы. Был смешной случай, когда «распиливали» монолит на PHP, написанный таким образом, что всё оказалось связанным со всем. Модули были настолько плохо абстрагированы друг от друга, что для запуска любого из них требовалось приложение целиком. И промежуточная архитектура выглядела так: приложение разбили на микросервисы, но при этом каждый микросервис содержал приложение целиком. В каждом контейнере активен был только один какой-то компонент, остальное приложение тянулось за ним в нагрузку. Но, конечно, это проблема не Kubernetes, а разработчиков, не умеющих в decoupling.
Kubernetes в переводе с греческого значит «кормчий»
Если говорить о недостатках — ну, обёртки не существовали бы, если бы в них не было необходимости. Kubernetes требует некоторой культуры работы с ним, хорошего понимания его абстракций. Без этого понимания можно часами сидеть, уставившись в доки, и не понимать, откуда начинать делать то, что хочешь сделать. В этом плане OpenShift, например, намного дружелюбнее к новичку. Там отличный UI, в котором быстро понимаешь, что делаешь и зачем.
Есть две вещи, которые раздражают меня лично. Первая — когда только начал использовать какую-то фичу, а в следующей версии она уже deprecated. Нужно внимательно следить за развитием технологии, чтобы такого не было. И второе — писать Custom Resource Definitions. Трудоёмкая работа, которую не автоматизируешь: кто, кроме нас, напишет определения наших ресурсов? Хотя сами по себе CRD — отличная штука, в сочетании с Kubernetes API позволяют очень гибко автоматизировать управление ресурсами.

Airflow

Андрей Ларионов
руководитель практики инженеров данных
К необходимости использования Apache Airflow мы пришли не сразу. Конечно, запуск процессов преобразования данных — очень распространённая бизнес-задача. Но в самых простых случаях можно банально запускать запрос cron’ом. Когда этого перестаёт хватать? Когда становится не один запрос, а несколько, причём одни зависят от результатов других. И особенно — если мы хотим уметь прервать обработку данных, а затем корректно возобновить. Конечно, эта задача, в принципе, тоже решается на коленке: создаём в БД метатаблицу, куда складываем данные о ходе выполнения операций. Но это уже, как вы понимаете, намного более муторно. И всё сильнее искушение как-то эти вещи автоматизировать. Чем, собственно, Airflow и занимается.
Airflow — оркестратор процессов обработки данных. Или, в принципе, любых других процессов, но чаще всего его используют именно в области обработки данных. Его основная сущность — это DAG, направленный ациклический граф. Вершины этого графа — отдельные процессы, а стрелочки — то, какие процессы должны завершиться прежде, чем другие стартуют. У Airflow прекрасный UI, где эти DAG'и очень удобно смотреть.
Помимо этого, для описания процессов в Airflow есть коннекторы и операторы. Коннекторы отвечают за то, откуда данные брать (или куда класть), а операторы — за то, что с данными делать. И всё это описывается на языке Python, что приятно, поскольку он — один из самых лёгких и распространённых.
Пристегните ремни: сейчас ваши данные будут летать
Экосистема Airflow весьма развита. Готовые коннекторы и операторы покрывают примерно 90 % потребностей, редко приходится писать что-то своё. Из недавних случаев один был очень простым: надо было переопределить оператор, чтобы он кидал ошибку другого типа. Другой посложнее: периодически возникали ошибки при запуске задач на сервер Postgres в «Яндекс.Облаке». Стандартный Postgres-коннектор не умеет автоматически переключаться между master и slave.
Альтернативы у Airflow есть — например, Luigi или Argo. Luigi — модуль для Python, используемый для тех же задач, проще в эксплуатации, но менее гибкий. У Argo (и основанного на нём Kuberflow) упор больше на контейнеры, чем на процессы обработки данных. В общем-то, нельзя сказать, что кто-то из них лучше, а кто-то хуже: у каждого своя ниша.
Airflow невероятно гибкий. Как правило, весь потенциал этой гибкости не требуется конкретной организации с её конкретными задачами. Мы в какой-то момент обнаружили, что значительная часть DAG'ов имеет достаточно похожую, типовую структуру. И создали несколько инструментов, позволяющих такие DAG'и генерить из конфигурационных файлов. Об одном из этих инструментов я уже писал.
Я доволен Airflow практически полностью. С моей точки зрения, у него нет недостатков — только недочёты. Есть несколько запутывающих моментов в API, на которые регулярно напарываются новички. Во-первых, это параметр schedule_interval. Запланировал DAG, а он не выполняется? Это потому, что первое выполнение DAG'а планируется на start_date + schedule_interval. На выяснение этого нюанса я однажды убил целый рабочий день. Подозреваю, что это не рекорд.
Во-вторых, притча во языцех — execution_date. Все думают, что это момент начала выполнения DAG'а, пока не наткнутся на какое-нибудь непонятное поведение. Тогда лезут в документацию и узнают, что это начало текущего интервала. Тоже очень интуитивно. Впрочем, в грядущей версии Airflow разработчики обещали изменить название этого параметра. Так что вместо проблемы с его пониманием будут проблемы с миграцией.
Ну и наконец, возможно, и не минус, но особенность — время в UTC. У нас есть магазины в разных часовых поясах, соответственно надо следить, чтобы данные брались в правильных временных интервалах.

Расскажите в комментариях — каков ваш личный опыт работы с технологиями из статьи?

Комментарии (22)


  1. BigBeaver
    17.01.2022 19:09
    +5

    Извините, конечно, но сайта магазина хуже, чем у Леруа я еще не видел.


    1. RealPeha
      17.01.2022 19:12
      +3

      Таким сильным заявлением вы заставили меня глянуть на их сайт, а там...


      1. kokis
        17.01.2022 19:29

        Это не тот сайт. Речь про команду, которая занимается //leroymerlin.ru


        1. fkafka
          18.01.2022 05:01
          +1

          Речь про команду, которая занимается //leroymerlin.ru

          Это на котором логин уже второй день не работает?


    1. ivanovdev
      17.01.2022 20:27
      +1

      +1

      Еще пару лет назад сайт работал нормально, теперь невозможно искать товары. После того как ввел название товара в поиск нужно ждать 5-30 секунд, чтобы получить результаты.


      1. BigBeaver
        17.01.2022 20:38

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

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


  1. achekalin
    17.01.2022 22:20
    +2

    Беру гугл/яндекс, ищу любой строительный товар с припиской слова "леруа". Оп - нашел! Щелкаю по ссылке в выдаче, и попадаю на страницу нужного товара на московском сайте Леруа (а я не в нерезиновой), и сверху издевательская плашка "вы в Москве, правильно?" Выбираю "нет", появляется список городов, выбираю свой - и меня перекидывает на главную страницу сайта Леруа в моем городе. Ищи, дорогой юзер, тот же товар на сайте имени своего города, ищи!

    Такое повторяется каждый раз.

    Те сайт не умеет ни перейти на страницу того жн товара при выборе другого города (товар в нем есть; но даже если бы и не было - вывести сообщение об этом вместо кнопки "купить" несложно же?), ни в куках моего браузера запомнить выбор города, и перекинуть меня при заходе с поисковика... ну правда, тут не рокет-сайенс, просто желание поставить себя на место посетителя!

    Вопрос: у столь отличной команды с такими модными технологиями нет мозга тестеров иначе как в МСК?


    1. neura
      18.01.2022 09:21

      Стало любопытно и решил проверить. С компа и с телефона все Окей. Нашёл товар в Яндексе перешёл, изменил город, остался на товаре. Что я делаю не так?


      1. BigBeaver
        18.01.2022 09:28

        Видимо, недавно починили, но буквально с пол года назад действительно так работало, как пишут выше. Но остались другие фишки

        Заголовок спойлера
        Вот, например, такая выдача во внутреннем поиске Леруа

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


        1. neura
          18.01.2022 09:41
          +5

          Прикольно (спойлер: нет). Спрошу у нашей команды поиска. Если что, то я за мобильные приложения отвечаю, можно писать про них мне.

          Но вообще для меня очень странно, что в комментариях под статьей обсуждаются не сама статья (кроме одного комментария), а сайт/доставка/итд

          Вспоминается как нам в аппстор написали коммент с 1 звездой, что у человека на парковке перед магазином барсетку украли


          1. BigBeaver
            18.01.2022 09:55

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


            1. neura
              18.01.2022 10:16

              Я не нападаю и понимаю, что если что-то не работает это может раздражать, особенно если ты торопишься. Но не соглашусь про технологии. Я не знаю буквально ни одной компании, где все работает идеально. Ломается яндекс, ломается сбер, ломается авито (и не только они), но при этом это не значит, что нужно остановиться двигаться вперед и развиваться.

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

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

              Надеюсь удалось пролить свет на эту часть работы


              1. BigBeaver
                18.01.2022 10:23
                +1

                Так поиск это только вершинка) Разного рода косяки от архитектуры (или её реализации — хз) до контента годами висят. Уж не знаю, никто не жалуется или что, но факт есть факт. Проблема как раз в том, что речь не о технических сбоях формата «сломал — пофиксил».

                Но вас я тоже понимаю, конечно.


                1. neura
                  18.01.2022 10:31

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

                  А мы будем очень благодарны)


        1. ovvnglory
          18.01.2022 15:20

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

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


          1. BigBeaver
            18.01.2022 15:50

            Очень круто. А где эта форма, не подскажете?


            1. ovvnglory
              18.01.2022 18:49

              Либо через канал отзывов (справа), либо через канал обратной связи (справа внизу)


              1. BigBeaver
                18.01.2022 18:57

                О, интересно. Есть идеи, почему вон та кнопка внизу есть на странице товара но не на странице поиска? Кстати, если у кого-то стоит AliTools, то она перекрывается их какой-то штукой. А кнопку «оставить отзыв» убивает включение блокировки трекеров в Опере.


                1. ovvnglory
                  19.01.2022 10:03

                  Ответить на этот вопрос точно не смогу, а фантазировать не хочется. Передам эти замечания команде, которая занимается системой отзывов.


  1. antonarhipov
    17.01.2022 23:57
    +2

    можно просто пренебречь проверками на null: если возникнет NPE, значит, с бизнес-логикой в любом случае что-то не так

    Вы это серьёзно!? NPE - это в любом случае ошибка программиста, не надо сваливать на бизнес-логику. Так вот у сервисов пятисотки то и летят с таким подходом


    1. neura
      18.01.2022 09:42

      Согласен NPE нельзя игнорировать ни в коем случае. Возможно, неправильно передана идея, что в Котлине тебя к этому принуждает сам язык


    1. tuus-amicus
      18.01.2022 15:22

      Я немного не так передал мою основную мысль. 

      Я имел ввиду, что можно пропустить нуллабельное поле по ошибке. Невнимательность и все такое.

      В котлине это практически невозможно сделать, потому что тебя к этому подталкивает сам язык. Но может возникнуть ситуация, когда разработчик работает над чужим кодом и не уловил бизнес смысл null поля и использует небезопасный вызов, откуда и возникает NPE.