Разработка и инженерия

страница 4 из 44
пост №1863Разработка и инженерия

Как перезапустить проект технически?

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

Они пользуются уже третьей версией своей платформы. Фронтенд на low-code платформе Bubble, бэкенд частично на flask и частично n8n. Всё работает, приносит пользу, проект поднял больше миллиона долларов инвестиций.

Как навести порядок, радикально увеличить скорость доставки фич и гарантировать масштабируемость?

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

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

В результате, в момент включения новой платформы в продакшен, точно возникнут проблемы, которые придется героически исправлять «прямо сейчас», в стрессе. Мало предсказуемости, о реальном объеме работы мы узнаем только в самом конце проекта, при попытке переключения. Мы такое не любим.

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

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

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

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

К сожалению, кажется, что каждый молодой программист обречен пытаться всё переписать правильно с нуля. Технарь, предлагающий strangler fig pattern, не лучше, просто за его обучение уже заплатил другой заказчик.

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

пост №1861Разработка и инженерия

Только что опубликовали новое мобильное приложение в AppStore. Сделали его наши веб-разработчики на кросс-платформенной технологии CapacitorJS, так что не потребовалась отдельная команда мобильной разработки, сэкономили месяцы и миллионы рублей.

Два месяца переписывались с Apple по поводу in-app purchases и прочих коммерческих моментов. В результате всё решилось одним коротким звонком с Купертино. По телефону нам на хорошем русском объяснили, что «правила AppStore — это направляющие принципы, каждую ситуацию не распишешь формально, конкретно вам нужно сделать 1, 2, 3». Не стесняйтесь пользоваться опцией заказа звонка!

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

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

Такой кайф, когда единая команда отвечает за продукт на всех платформах! Нет этого: «веб уже запрогал, андроид сделал не совсем как нужно, но сойдёт, а iOS-команда пока занята, ждём...»

Ура!

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

пост №1857Разработка и инженерия

По интернету гуляет история про 16 миллиардов утёкших паролей. В заголовке фигурируют Facebook, Google, Apple.

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

Что же было?

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

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

Сама эта новость — странная. Первоисточник — вот эта статья на малоизвестном «новостном» сайте. Выглядит этот сайт как классический SEO-PR проект. Автор — литовец, якобы замглавреда, с 21 твитом и с довольно чистым Линкедином. В общем, я пока не уверен, что за этим проектом не стоит один опытный SEO-шник.

Дальше это выкладывается на Forbes.com под страшным заголовком «16 миллиардов паролей Apple, Facebook и Google утекли — успей поменять пароль сейчас!». Чтобы вы понимали, это не журналист Форбса написал, а «колонка», то есть блогер, который публикует там примерно что захочет. Через Форбс обычно «прокачивают» SEO-трафик и делают статьи для виз талантов за деньги, но это отдельная история.

Единственный, кто выглядит как живой человек во всей этой истории, — это украинский безопасник Владимир Дьяченко, который в своём Линкедин-посте утверждает, что «всё в этой статье прошло через его руки».

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

Из приятного — 15 минут назад главный исследователь утечек Трой Хант затвитил, что посмотрит, про что весь шум-гам. Моя ставка: всё это — прекрасная виральная кампания по сбору трафика на ИИ-сгенерированный «новостной сайт». А может, даже пиар того самого безопасника Владимира. Надеюсь, хоть он существует на самом деле.

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

пост №1852Разработка и инженерия

Гугл опубликовал пост-мортем по позавчерашнему падению. Обычные ошибки, только на инфраструктуре планетарного масштаба.

У них есть внутренний сервис, который проверяет доступы (бабки, квоты и т. д.) перед тем, как API запрос доходит до любого продукта.

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

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

Экземпляр этой программы работает в каждом регионе Гугла. Так как это серьезный, ключевой сервис, его выкатывают не во все регионы сразу, а по одному, внимательно отслеживая, не внесли ли программисты новые ошибки.

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

К сожалению, программист забыл настроить фича-флаги для этого кода. Кусочек программы с ошибкой запустился на всех пользователей сразу. Удивительно, что это не заметили на этапе code review!

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

Тут в дело вступает, на мой взгляд, первая ошибка (а не просто человеческая небрежность) инженеров — система контроля доступа настроена так, что при отсутствии ответа от программы проверок она отклоняет запрос. Так называемый fail closed. Хорошо для замков на банковских сейфах, плохо для пожарных выходов.
В нашем случае система не пропускает ни один запрос.

Дежурные инженеры замечают проблему в течение 2 минут, за 10 минут находят причину (дежурная система и дежурные инженеры у Гугла достойны восхищения) и нажимают большую красную кнопку, которая должна выключить эту часть программы (ее программисты сделали). Ее включение занимает еще 30 минут. (Не понятно, почему этот механизм занимает 30 минут, а не 20 миллисекунд, но движемся дальше).

Система заработала, но из-за того, что она лежала 40 минут, накопилось много желающих отправить запрос еще раз, и они создали эффект толпы, которая набежала и перегрузила остальные соседние сервисы через наш сервис проверок. Оказалось, что он не ждет какое-то время, если нужный сервис отказывается ответить на запрос (для этого есть красивая схема exponential back off), а долбит до упаду, тем самым не давая системе возможности восстановиться. Пришлось руками ограничивать число запросов. На постепенную, ручную разгрузку очередей ушло еще 2 часа.

Ко всему прочему, Гугл час не мог опубликовать уведомление о проблеме, потому что сервис публикации статус-страниц зависит от системы, которая упала.

Как вывод, Гугл обещает пройтись по всем сервисам и убедиться, что они, во-первых, fail open, то есть пропускают запросы, когда падают, во-вторых, реализуют exponential back off, если на их запрос не отвечают, а не добивают лежачего, и, наконец, в-третьих, что даже глобальные добавления правил должны прилетать во все регионы не сразу, а с некоторыми задержками. Ещё обещают добавить эти проверки в свои статические анализаторы кода, завидую!

Первые два пункта можно и нужно использовать в каждом проекте, даже если ты не Гугл.

пост №1851Разработка и инженерия

В контексте падения облаков, чем они лучше/хуже собственного железа?

Можно подумать, что я буду сейчас писать про отказоустойчивость. На самом деле, если ваш проект будет лежать, когда лежит весь GCP или AWS, — то для 99% проектов это абсолютно нормально, такие события происходят раз в несколько лет и длятся не больше пары часов. Мы ведь не кислородными масками управляем, верно?

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

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

Главное преимущество облаков в сравнении с «реальными серверами» — возможность быстро масштабироваться, то есть сегодня у тебя один сервер обрабатывает 1000 пользователей, завтра проект завирусился на миллионы, и ты за пару минут запускаешь десятки, сотни серверов.

Минусы? За это удобство и возможность мгновенного масштабирования нужно платить, порой в десятки и сотни раз больше, чем за просто арендованные и уж тем более купленные серверы.

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

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

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

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

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

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

Пример: классно наблюдать, как последние 3 года создатель важного фреймворка Ruby on Rails и культовой системы управления проектами Basecamp Дэвид Хейнемейер Ханссон (DHH) планомерно перевозит свои продукты с миллионами пользователей из облаков на собственные серверы.

Они объявили о планах выхода из Амазоновского облака AWS ещё в октябре 2022. На тот момент, они платили за Амазону 1,5 млн долларов в год! Для начала, они купили себе физических серверов на полмиллиона долларов (всего треть годового чека за облака!)

В июне 2023 объявили об успешном перевозе всех вычислений, а недавно купили специализированное железо для хранения данных и мае наконец перевезли хранилище файлов из AWS S3.

Другой яркий пример, с которым я сталкивался лично, — это стоимость трафика для медиа-проектов. Трафик в облаках для популярного медиа может стоить десятки тысяч долларов, и такой же объем можно обработать десятком арендованных серверов по 40 баксов каждый. Экономия в 100 раз. Но это всё имеет смысл только на масштабе. Так выпьем же за то, чтобы было на чем экономить!

пост №1850Разработка и инженерия

В 21:46 мск отказала большая часть гугловского облака GCP. Ходят слухи, что всё из-за одного ключевого технического внутреннего сервиса, но в результате в разной степени поломались гугловские продукты, вроде Cloud, Drive, Meet, Gmail.

Предположительно, из-за этого начал глючить Cloudflare, один из самых популярных CDN-провайдеров.

Дальше по цепочке легла половина интернета — Spotify, Discord, Snapchat и тысячи других. Особенно тревожно, что для многих людей сломался RCS — это протокол, продвигаемый Гуглом, который должен заменить смски.

Предвкушаю увлекательные постмортемы от Гугла и Cloudflare, последние уж точно не упустят шанса рассказать, что это было.

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

P. S. Про одновременное падение Amazon Web Services — кажется дезинформация.

пост №1846Разработка и инженерия

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

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

Технически сейчас это программа на C#, которая в одну сторону торчит админкой для редакции, а в сторону читателей генерирует HTML-страницы сайта. Это популярный сетап из 2000-х. Техническую задачу я формулирую как облегчение процесса разработки без потери производительности сайта.

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

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

Но будет ли современное веб-приложение (SPA) так же производительно, как HTML-страницы из 90-х? Речь и о скорости первого открытия — можно ли загрузить JS после полной отрисовки страницы? — и о скорости перехода между страницами — быстрее ли JavaScript-логика, чем отдать готовый HTML с сервера?

Можно ли получить лучшее из обоих миров? На какие компромиссы придётся пойти?

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

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

P. S. Один из разработчиков McMaster пишет, что под капотом там VB.NET, хранимки и XSL-трансформации поверх XML для генерации веб-страниц. Хочется вот всё то же самое, только без VB, хранимок и XSLT. 🙈

пост №1836Разработка и инженерия

Тормозит приложение.

На днях написала топ-менеджер одной ритейл-сети. Тормозит мобильное приложение. Медленно работает поиск, добавление в корзину, оформление заказа. Нажимаешь на кнопку и ждешь…

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

Хорошие разработчики собирают аналитику по производительности своих приложений — какое время занимают ключевые действия типа «открытие главной», «поиск», «добавление в корзину», «оплата». Это называется Real User Monitoring.

Дальше мы кладем эту информацию на график: на оси Х — время, которое занимает действие, на оси Y — количество пользователей. Столбики слева — хорошо. Длинный хвост справа — это несчастные, у них, например, экран оплаты грузится минуту! Эти люди поменяют приложение, если у них будет выбор!

Но это средние значения. Что, если приложение хорошо работает 23 часа в сутки, а по вечерам, в час-пик, в самое важное время, начинает тормозить?

Тут поможет другой классический график: на оси Х — время (вчера, сегодня в течении дня, завтра), на оси Y — время ответа (задержка, latency). Три черты — среднее время, медиана и 95 персентиль. То есть за сколько миллисекунд происходит оплата в среднем, у медианы и за какое время происходит оплата у 95% быстрых пользователей? Он помогает отследить, нет ли тормозов в определенное время суток или в день недели.

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

Итак, шаг первый — замерить экраны и действия.

Теперь можно переходить к поиску первопричины. Приложение может тормозить само по себе или из-за медленного бэкенда.

Тут мы опираемся на те же два графика, но уже смотрим скорость ответа бэкенда.

Качественно настроить сбор данных и дэшборды — это дополнительная работа, но она с лихвой окупается при расследовании проблем.

Хотите заказать классную разработку или аудит? Обращайтесь! @samatg https://fansdev.ru

пост №1785Разработка и инженерия

Аналогичная штука для командной строки — Warp. Терминал с нормальной поддержкой AI.

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

По сути, ты получаешь в руки набор кубиков Lego и каждый раз собираешь именно ту программу, которую нужна тебе прямо сейчас. Безграничные возможности.

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

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

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

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

Warp возвращает мне эти знания, а порой подсказывает вещи, которых и я не знал никогда.

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

При этом у него есть контекст происходящего — что ты делал раньше и каким был результат. Можно прямо сказать «там че-то homebrew ругается, почини». И он чинит!

А ещё у него обычный ввод текста, не readline, так что можно наконец редактировать длинные многострочные команды прямо в нем.

Я сижу на бесплатном тарифе — 100 AI-запросов в месяц, дальше от 15$ в месяц. Пока только для Mac и Linux, Windows версию обещают скоро.

пост №1784Разработка и инженерия

Дорогие программисты (особенно кто кодит не профессионально и не часто), если не пользовались Cursor — рекомендую попробовать.

Это редактор кода на основе VS Code, в который встроили хорошую поддержку AI. Можно выбирать API из множества провайдеров, он сам корректно добавляет контекст, очень удобно подсвечивает добавления/изменения кода.

Я часто прошу накинуть прототип, который дальше довожу до ума. Можно выделить кусочек кода и попросить в нем что-то поменять.

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

Хорошие фул-тайм программисты говорят, что им полезно как мощный инструмент рефакторинга, который берет на себя рутину.

Я сижу на бесплатном тарифе, больше тяжелых запросов — за 20$ в месяц.

Upd. Коллеги напоминают, что совсем недавно Lex Fridman взял интервью у создателей — занимательный разговор!