Чёрт возьми, Google, я не хотел снова писать в блог. У меня так много дел. Ведение блога требует времени, энергии и креатива, которые я мог бы использовать с пользой: мои книги, музыка, моя игра и так далее. Но ты меня достаточно разозлил, и придётся это написать.
Так что давай покончим с этим.
Начну с небольшой, но поучительной истории из тех времён, когда я только начал работать в Google. Знаю, что в последнее время я наговорил много плохого о Google, но меня расстраивает, когда родная компания регулярно принимает некомпетентные бизнес-решения. При этом нужно отдать должное: внутренняя инфраструктура Google действительно экстраординарная, можно смело утверждать, что сегодня нет ничего лучше. Основатели Google были гораздо лучшими инженерами, чем я когда-либо стану, и эта история только подтверждает данный факт.
Сначала немного предыстории: у Google есть технология хранения данных под названием Bigtable. Это было замечательное техническое достижение, одно из первых (если не первое) «бесконечно масштабируемое» хранилище пар «ключ-значение» (key-value store, K/V): по сути, начало NoSQL. В наши дни Bigtable всё ещё хорошо чувствует себя в довольно переполненном пространстве хранилищ K/V, но в то время (2005 год) оно было потрясающе крутое.
Одна забавная деталь Bigtable заключается в том, что у них были внутренние объекты плоскости управления (как часть реализации) под названием tablet-серверы, с большими индексами, и в какой-то момент они стали узким местом при масштабировании системы. Инженеры Bigtable ломали голову, как реализовать масштабируемость, и вдруг поняли, что могут заменить tablet-серверы другими хранилищами Bigtable. Так что Bigtable — это часть реализации Bigtable. Эти хранилища там на всех уровнях.
Еще одна интересная деталь заключается в том, что на какое-то время Bigtable стали популярными и вездесущими внутри Google, и у каждой команды было своё хранилище. Поэтому на одном из пятничных собраний Ларри Пейдж небрежно спросил мимоходом: «А почему у нас больше одного Bigtable? Почему не обойтись только одним?» Теоретически, одного хранилища должно было хватить для всех потребностей хранения Google. Конечно, они никогда не переходили только на одно по практическим причинам разработки (например, последствия потенциального сбоя), но теория была интересной. Одно хранилище для всей Вселенной (кстати, кто-нибудь знает, Amazon такое сделала со своим Sable?)
Так или иначе, вот моя история.
В то время я работал в Google чуть более двух лет, и однажды мне пришло письмо от инженерной команды Bigtable примерно такого содержания:
В Google вам приходит много почты, поэтому с первого взгляда я прочитал примерно так:
Я почти удалил его сразу же, но на границе сознания ощутил тягостное, ноющее чувство, что это не совсем похоже на формальное письмо, хотя очевидно, что с адресатом ошиблись, потому что я не использовал Bigtable.
Но это было странно.
Остаток дня я попеременно думал о работе и о том, какой вид акульего мяса попробовать в микро-кухне, из которых по крайней мере три были достаточно близко, чтобы попасть с моего места метким броском бисквита, но мысль о письме не покидала меня с растущим чувством лёгкой тревоги.
Они явно назвали моё имя. И письмо отправлено на мой адрес электронной почты, а не на чей-то ещё, и это не cc: или bcc:. Тон очень личный и чёткий. Может, это какая-то ошибка?
Наконец, любопытство взяло верх и я пошёл взглянуть на консоль Borg в дата-центре, который они упомянули.
И конечно, у меня в управлении было хранилище BigTable. Что-что? Я взглянул на его содержимое, и — надо же! Оно было из инкубатора Codelab, в котором я сидел первую неделю работы в Google в июне 2005 года. Codelab заставлял вас запустить Bigtable, чтобы вы записали туда некоторые значения, и я, видимо, так и не закрыл хранилище после этого. Оно всё ещё работало, хотя прошло более двух лет.
В этой истории есть несколько примечательных аспектов. Во-первых, работа Bigtable был настолько несущественна в масштабе Google, что только через два года лишнее хранилище кто-то заметил, да и то лишь потому, что версия бинарника устарела. Для сравнения, я когда-то рассматривал возможность использования Bigtable в Google Cloud для моей онлайн-игры. В то время эта услуга стоила примерно $16 000 в год за пустую Bigtable на GCP. Я не говорю, что они вас обманывают, но, по моему личному мнению, это большие деньги за пустую грёбаную базу данных.
Ещё один примечательный аспект заключается в том, что хранилище по-прежнему работало через два года. WTF? Дата-центры приходят и уходят; они испытывают перебои, они проходят плановое техническое обслуживание, они всё время меняются. Железо обновляется, коммутаторы меняются местами, всё постоянно совершенствуется. Как, чёрт возьми, они смогли сохранить мою программу запущенной в течение двух лет с учётом всех этих изменений? Это может показаться скромным достижением в 2020 году, но в 2005-2007 годах оно было весьма впечатляющим.
И самый замечательный аспект заключается в том, что посторонняя инженерная команда в каком-то другом штате обращается ко мне, владельцу какого-то крошечного, практически пустого экземпляра Bigtable, у которого нулевой трафик в течение последних двух лет — и предлагают помощь, чтобы обновить его.
Я поблагодарил их, удалил хранилище, и жизнь пошла своим чередом. Но тринадцать лет спустя я всё ещё думаю об этом письме. Потому что иногда мне приходят подобные письма от Google Cloud. Они выглядят так:
Но я почти не читаю такие письма, потому что на самом деле в них говорится следующее:
И дело в том, что я получаю такие письма примерно раз в месяц. Это происходит так часто и так постоянно, что они неизбежно оттолкнули меня от GCP в лагерь противников облаков. Я больше не согласен зависеть от их проприетарных разработок, потому что на самом деле девопсу легче поддерживать систему с открытым исходным кодом на голой виртуалке, чем пытаться угнаться за Google с её политикой закрытия «устаревших» продуктов.
Прежде чем вернуться к Google Cloud, потому что я даже близко не закончил их критиковать, давайте посмотрим на работу компании в некоторых других областях. Инженеры Google гордятся своей дисциплиной разработки программного обеспечения, и именно это на самом деле вызывает проблемы. Гордость — это ловушка для неосторожных, она заставила многих сотрудников Google думать, что их решения всегда правильны и что правильность (по какому-то неопределённому нечёткому определению) важнее, чем забота о клиентах.
Приведу несколько произвольных примеров из других больших проектов за пределами Google, но надеюсь, что вы увидите этот шаблон везде. Он заключается в следующем: обратная совместимость поддерживает живучесть и актуальность систем в течение десятилетий.
Обратная совместимость — это цель проектирования всех успешных систем, предназначенных для открытого использования, то есть реализованных с открытым исходным кодом и/или на открытых стандартах. Я чувствую, что говорю что-то слишком очевидное, что всем даже неудобно, но нет. Это политический вопрос, поэтому нужны примеры.
Первая система, которую я выберу, самая старая: GNU Emacs, это своего рода гибрид между Блокнотом Windows, ядром ОС и Международной космической станцией. Это немного сложно объяснить, но в двух словах Emacs — это платформа, созданная в 1976 году (да, почти полвека назад) для программирования, чтобы повысить вашу продуктивность, но маскируется под текстовый редактор.
Я использую Emacs каждый божий день. Да, я также использую IntelliJ каждый день, она уже сама превратилась в мощную инструментальную платформу. Но написание расширений для IntelliJ — гораздо более амбициозная и сложная задача, чем написание расширений для Emacs. И что ещё более важно, всё написанное для Emacs сохраняется вечно.
Я по-прежнему использую программное обеспечение, которое написал для Emacs ещё в 1995 году. И уверен, что кто-то использует модули, написанные для Emacs в середине 80-х, если не раньше. Время от времени они могут потребовать незначительной настройки, но это действительно довольно редко. Я не знаю ничего из того, что я когда-либо писал для Emacs (а я написал много), в чём пришлось бы перестроить архитектуру.
В Emacs есть функция под названием make-obsolete для устаревших сущностей. Терминология Emacs для фундаментальных компьютерных концепций (например, что такое «окно») часто отличается от отраслевых конвенций, потому что Emacs ввёл их очень давно. Это типичная опасность для тех, кто опередил своё время: все ваши термины некорректны. Но в Emacs действительно есть концепция устаревания, которая на их жаргоне называется obsolescence.
Но в мире Emacs, похоже, другое рабочее определение. Другая основополагающая философия, если хотите.
В мире Emacs (и во многих других областях, которые мы рассмотрим ниже) статус устаревших API в основном означает: «Вы действительно не должны использовать этот подход, потому что, хотя он и работает, он страдает от различных недостатков, которые мы перечислим здесь. Но, в конце концов, это ваш выбор».
В мире Google статус устаревшего продукта означает: «Мы нарушаем свои обязательства перед вами». Это действительно так. Вот что это по сути означает. Это означает, что они заставят вас регулярно проделывать некоторую работу, возможно, большую работу, в наказание за то, что вы поверили в их красочную рекламу: у нас лучшее программное обеспечение. Самое быстрое! Вы делаете всё по инструкции, запускаете своё приложение или сервис, а затем — бац, через год или два оно ломается.
Это всё равно что продавать подержанный автомобиль, который точно сломается через 1500 км.
Это два совершенно разных философских определения «устаревания». Определение Google пахнет запланированным устареванием. Я не верю, что это на самом деле запланированное устаревание в том же смысле, как у Apple. Но Google определённо планирует сломать ваши программы, окольным путём. Я знаю это, потому что проработал там инженером-программистом более 12 лет. У них есть расплывчатые внутренние рекомендации, в какой мере следует соблюдать обратную совместимость, но в конечном итоге это зависит от каждой отдельной команды или службы. Нет никаких рекомендаций корпоративного или инженерного уровня, и самая смелая рекомендация с точки зрения циклов устаревания — это «попробуйте дать клиентам 6-12 месяцев на обновление, прежде чем сломать им всю систему».
Проблема гораздо серьёзнее, чем они думают, и она сохранится ещё долгие годы, потому что забота о клиентах не входит в их ДНК. Подробнее об этом ниже.
На данный момент я собираюсь сделать смелое утверждение, что Emacs успешен в значительной степени и даже в основном потому, что они так серьёзно относятся к обратной совместимости. Собственно, это и есть тезис нашей статьи. Успешные долгоживущие открытые системы обязаны своим успехом микросообществам, которые десятилетиями живут вокруг расширений/плагинов. Это и есть экосистема. Я уже рассуждал о сути платформ и о том, насколько они важны, и о том, что Google никогда за всю свою корпоративную историю не понимала, что входит в создание успешной открытой платформы, не считая Android или Chrome.
Вообще-то я должен вкратце упомянуть Android, потому что вы наверняка подумали о нём.
Во-первых, Android — это не Google. Они не имеют почти ничего общего друг с другом. Android — это компания, которая была куплена Google в июле 2005 года, этой компании было разрешено работать более или менее автономно и фактически она осталась в значительной степени нетронутой в течение прошедших лет. Android — это печально известный технический стек и столь же печально известная колючая организация. Как выразился один гуглер, «нельзя просто так взять и войти в Android».
В одной из прошлых статей я уже рассуждал, насколько плохими были некоторые из ранних дизайнерских решений Android. Чёрт возьми, когда я писал ту статью, они занимались развёртыванием дерьма под названием «мгновенные приложения», которые теперь (сюрприз!) устарели, и сочувствую, если вы были достаточно глупы, чтобы послушаться Google и перенести свой контент в эти мгновенные приложения.
Но здесь есть разница, существенная разница, которая заключается в том, что люди из Android действительно понимают, насколько важны платформы, они изо всех сил стараются сохранить работоспособность старых приложений Android. На самом деле, их усилия сохранить обратную совместимость настолько экстремальны, что даже я, во время своего краткого пребывания в подразделении Android несколько лет назад, обнаружил, что пытаюсь убедить их отказаться от поддержки некоторых из самых старых устройств и API (я ошибался, как и во многих других вещах прошлого и настоящего. Извините, ребята из Android! Теперь, когда я побывал в Индонезии, я понимаю, зачем они нам нужны).
Люди из Android поддерживают обратную совместимость до почти невообразимых крайностей, что нагромождает огромное количество устаревших технических долгов в их системах и цепочках инструментов. О боже, вы бы видели некоторые сумасшедшие вещи, которые им приходится делать в своей системе сборки, и всё это во имя совместимости.
За это я присуждаю Android заветную награду «Ты не Google». Они действительно не хотят становится Google, которая не умеет создавать долговечные платформы, а вот Android знает, как это делать. И поэтому Google ведёт себя очень мудро в одном отношении: позволяет людям в Android делать всё по-своему.
Однако мгновенные приложения для Android были довольно глупой идеей. И знаете, почему? Потому что они требовали переписать и перепроектировать ваше приложение! Как будто люди просто так возьмут и перепишут два миллиона приложений. Предполагаю, что мгновенные приложения были идеей какого-то гуглера.
Но здесь есть разница. Обратная совместимость сопряжена с большими затратами. Android сам несёт бремя этих затрат, в то время как Google настаивает на том, чтобы это бремя несли вы, платный клиент.
Вы можете увидеть приверженность Android обратной совместимости в её API-интерфейсах. Когда у вас четыре или пять различных подсистем для выполнения буквально одного и того же, это верный признак, что в основе лежит приверженность обратной совместимости. Что в мире платформ является синонимом приверженности вашим клиентам и вашему рынку.
Главная проблема Google здесь — их гордость своей инженерной гигиеной. Им не нравится, когда есть много разных способов делать одно и то же, причем старые, менее желательные способы сидят рядом с новыми, более причудливыми способами. Это увеличивает кривую обучения для новичков в системе, это увеличивает бремя поддержки устаревших API, это замедляет скорость новых функций, и главный грех — это некрасиво. Google — как Леди Эскот из «Алисы в Стране чудес» Тима Бертона:
Леди Эскот:
— Алиса, знаешь, чего я боюсь больше всего?
— Упадка аристократии?
— Я опасалась, что у меня будут некрасивые внуки.
Чтобы понять компромисс между красивым и практичным, давайте взглянем на третью успешную платформу (после Emacs и Android) и посмотрим, как она работает: сама Java.
В Java масса устаревших API. Устаревание очень популярно среди Java-программистов, даже популярнее, чем в большинстве языков программирования. В самой Java, основном языке и библиотеках постоянно происходит устаревание API.
Если взять только один из тысяч примеров, закрытие потоков считается устаревшим. Оно устарело с момента выпуска Java 1.2 в декабре 1998 года. Прошло 22 года с тех пор, как это устарело.
Но мой реальный код в продакшне по-прежнему убивает потоки каждый день. Разве это хорошо? Абсолютно! Я имею в виду, конечно, если бы я переписал код сегодня, я бы реализовал это по-другому. Но код моей игры, которая за последние два десятилетия сделала счастливыми сотни тысяч людей, написана с функцией закрытия потоков, которые висят слишком долго, и мне никогда не приходилось его менять. Я знаю свою систему лучше всех, у меня буквально 25-летний опыт работы с ней в продакшне, и я могу точно сказать: в моём случае закрытие этих конкретных рабочих потоков совершенно безвредно. Не стоит тратить время и силы на переписывание этого кода, и хвала Ларри Эллисону (наверное), что Oracle не заставила меня переписывать его.
Наверное, Oracle тоже разбирается в платформах. Кто его знает.
Доказательства вы можете встретить по всем ключевым Java API, которые пронизаны волнами устаревания, подобно линиям ледника в каньоне. В библиотеке Java Swing можно легко найти пять или шесть различных менеджеров навигации с клавиатуры (KeyboardFocusManager). На самом деле трудно найти Java API, который не является устаревшим. Но они всё ещё работают! Думаю, команда Java по-настоящему удалит API только в том случае, если интерфейс вызовет вопиющую проблему безопасности.
Вот в чём дело, ребята: мы, разработчики программного обеспечения, все очень заняты, и в каждой области программного обеспечения мы сталкиваемся с конкурирующими альтернативами. В любой момент времени программисты на языке X рассматривают язык Y как возможную замену. О, вы мне не верите? Вы хотите назвать Swift? Мол, все мигрируют на Swift и никто от него не отказывается, верно? Ого, как мало вы знаете. Компании считают расходы на двойные команды мобильной разработки (iOS и Android) — и они начинают понимать, что эти кросс-платформенные системы разработки со смешными названиями, такие как Flutter и React Native, действительно работают, и с их помощью можно сократить размеры своих мобильных команд вдвое или, наоборот, сделать их вдвое продуктивнее. На кону реальные деньги. Да, есть компромиссы, но, с другой стороны, де-е-еньги.
Предположим гипотетически, что Apple по глупости взяла пример с Гвидо ван Россума и объявила, что Swift 6.0 обратно несовместим со Swift 5.0, во многом как Python 3 несовместим с Python 2.
Наверное, я рассказывал эту историю лет десять назад, но лет пятнадцать назад я ездил в лагерь O’Reilly’s Foo Camp с Гвидо, сидел в палатке с Полом Грэмом и кучей больших шишек. Мы сидели в изнуряющей жаре и ждали, когда Ларри Пейдж вылетит на своём личном вертолете, а Гвидо монотонно бубнил о «Питоне 3000», который он назвал по количеству лет, которое потребуется всем, чтобы туда мигрировать. Мы всё время спрашивали его, почему он нарушает совместимость, и он отвечал: “Unicode”. И мы спрашивали, если нам придется переписать наш код, то какие еще преимущества мы увидим? И он отвечал “Yoooooooooooooouuuuuuuniiiiiiicoooooooode”.
Если установить Google Cloud Platform SDK (“gcloud”), то вы получите следующее уведомление:
… и так далее. Круг жизни.
Но дело в том, что у каждого разработчика есть выбор. И если заставить их переписывать код достаточно часто, то они могут подумать и о других вариантах. Они не ваши заложники, как бы вам этого ни хотелось. Они — ваши гости. Python по-прежнему очень популярный язык программирования, но, чёрт побери, Python 3(000) создал такой бардак у себя, в своих сообществах и у пользователей своих сообществ, что последствия не могут разгрести уже пятнадцать лет.
Сколько программ Python было переписано на Go (или Ruby, или какой-то другой альтернативе) из-за этой обратной несовместимости? Сколько нового программного обеспечения было написано на чём-то другом, кроме Python, хотя оно могло быть написано на Python, если бы Гвидо не сжёг всю деревню? Трудно сказать, но Python явно пострадал. Это огромный бардак, и все в проигрыше.
Итак, допустим, Apple берёт пример с Гвидо и нарушает совместимость. Как думаете, что будет дальше? Ну, может, 80-90% разработчиков перепишут своё программное обеспечение, если получится. Другими словами, 10-20% пользовательской базы автоматически уходят на какой-то конкурирующий язык, например, Flutter.
Сделайте это несколько раз — и вы потеряете половину своей пользовательской базы. Как и в спорте, в мире программирования текущая форма тоже значит всё. Любой, кто потеряет половину пользователей за пять лет, будет считаться Большим Жирным Неудачником. Вы же должны быть в тренде в мире платформ. Но именно здесь отказ от поддержки старых версий со временем вас погубит. Потому что каждый раз, когда вы избавляетесь от части разработчиков, вы (а) теряете их навсегда, потому что они сердятся на вас за нарушение контракта, и (б) отдаёте их своим конкурентам.
По иронии судьбы, я тоже помог Google превратиться в такую примадонну, которая игнорирует обратную совместимость, когда создал Grok, систему анализа и понимания исходного кода, которая облегчает автоматизацию и оснастку инструментарием на основе самого кода — похоже на IDE, но здесь облачный сервис хранит материализованные представления всех миллиардов строк исходного кода Google в большом хранилище данных.
Grok предоставил гуглерам мощную основу для проведения автоматизированного рефакторинга по всей кодовой базе (буквально по всему Google). Система вычисляет не только ваши восходящие зависимости (от которых вы зависите), но и нисходящие (которые зависят от вас), поэтому при смене API вы знаете всех, кого ломаете! Таким образом, при внесении изменений вы можете проверить, что каждый потребитель вашего API обновился до новой версии, а в реальности часто с помощью инструмента Rosie, который они написали, вы можете полностью автоматизировать процесс.
Это позволяет кодовой базе Google внутренне быть почти сверхъестественно «чистой», так как у них эти роботизированные слуги снуют по всему дому и автоматически всё подчищают, если они переименовали SomeDespicablyLongFunctionName в SomeDespicablyLongMethodName, потому что кто-то решил, что это некрасивый внук, и его нужно усыпить.
И, честно говоря, это довольно хорошо работает для Google… внутренне. Я имею в виду, да, сообщество Go в Google действительно по-доброму посмеивается с сообщества Java в Google из-за их привычки к непрерывному рефакторингу. Если вы что-то перезапускаете N раз, то это означает, что вы не только испортили это N-1 раз, но и через некоторое время становится совершенно ясно, что вы, вероятно, испортили это и с N-ой попытки. Но, по большому счету, они остаются выше этой суеты и сохраняют код «чистым».
Проблемы начинаются, когда они пытаются навязать такое отношение своим облачным клиентам и пользователям других API.
Я немного познакомил вас с Emacs, Android и Java; давайте посмотрим на последнюю успешную долгоживущую платформу: сам Веб. Можете представить, через сколько итераций прошёл HTTP с 1995 года, когда мы использовали мигающие теги <blink> и значки «В разработке» на веб-страницах.
Но это всё ещё работает! И эти страницы всё ещё работают! Да, ребята, браузеры — мировые чемпионы по обратной совместимости. Chrome — это ещё один пример редкой платформы Google, у которой головы привинчены правильно, и, как вы уже догадались, Chrome эффективно действует как изолированная компания отдельно от остального Google.
Я также хочу поблагодарить наших друзей среди разработчиков операционных систем: Windows, Linux, НЕ APPLE ПОШЛА ТЫ APPLE, FreeBSD и так далее, за то, что они проделали такую большую работу по обратной совместимости на своих успешных платформах (Apple получает в лучшем случае тройку с минусом, так как они постоянно всё ломают без всякой уважительной причины, но каким-то образом сообщество справляется с этим в каждом релизе, и до сих пор контейнеры с OS X ещё не полностью устарели… пока).
Но подождите, скажете вы. Разве мы не сравниваем яблоки с апельсинами — автономные программные системы на одной машине, такие как Emacs/JDK/Android/Chrome, с многосерверными системами и API, как в облачных сервисах?
Ну, я написал об этом вчера в твиттере, но в стиле Ларри Уолла (создатель языка программирования Perl — прим. пер.) по принципу «отстой/рулез» я поискал слово deprecated на сайтах для разработчиков Google и Amazon. И хотя у AWS в сотни раз больше предложений услуг, чем у GCP, документация разработчиков Google упоминает устаревание примерно в семь раз чаще.
Если кто-то из Google читает это, то наверняка они готовы вытащить диаграммы в стиле Дональда Трампа, что на самом деле делают всё правильно, и что я не должен делать несправедливые сравнения, такие как «количество упоминаний слова deprecated в зависимости от количества сервисов».
Но спустя столько лет Google Cloud по-прежнему остается сервисом № 3 (я так и не написал статью о неудачной попытке стать № 2), но если верить инсайдерам, есть некоторые опасения, что они могут скоро опуститься до № 4.
У меня нет веских аргументов, чтобы «доказать» свой тезис. Всё, что у меня есть, — это красочные примеры, которые я накопил за 30 лет работы в качестве разработчика. Я уже упоминал о глубоко философской природе этой проблемы; в некотором смысле она политизирована в сообществах разработчиков. Некоторые считают, что создатели платформ должны заботиться о совместимости, а другие считают, что это забота пользователей (самих разработчиков). Одно из двух. И в самом деле, разве это не политический вопрос, когда мы решаем, кто должен нести расходы за общие проблемы?
Так что это политика. И наверняка будут гневные ответы на моё выступление.
Как пользователь облачной платформы Google, а также как пользователь AWS в течение двух лет (работая в компании Grab), могу сказать, что существует огромная разница между философиями Amazon и Google, когда речь заходит о приоритетах. Я не веду активную разработку на AWS, поэтому не очень хорошо знаю, насколько часто они убирают старые API. Но есть подозрение, что это происходит далеко не так часто, как в Google. И я искренне верю, что этот источник постоянных споров и разочарований в GCP является одним из самых больших факторов, сдерживающих развитие платформы.
Знаю, что не назвал конкретные примеры систем GCP, поддержка которых прекращена. Могу сказать, что практически всё, что я использовал, от сетей (от самых старых до VPC) до хранилищ (Cloud SQL v1-v2), Firebase (теперь Firestore с совершенно другим API), App Engine (давайте даже не будем начинать), облачных конечных точек Cloud Endpoint и до… я не знаю — абсолютно всё это заставляло переписывать код максимум через 2-3 года, и они никогда не автоматизировали для вас миграцию, а часто не было никакого документированного пути миграции вообще. Словно так и положено.
И каждый раз, когда я смотрю на AWS, я спрашиваю себя, какого чёрта я до сих пор сижу на GCP. Им явно не нужны клиенты. Им нужны покупатели. Понимаете разницу? Давайте объясню.
У Google Cloud есть Marketplace, на котором люди предлагают свои программные решения, а чтобы избежать эффекта пустого ресторана, нужно было заполнить его некоторыми предложениями, поэтому они заключили контракт с компанией Bitnami, чтобы создать кучу решений, которые развёртываются «одним щелчком мыши», или я сам должен написать «решения», потому что эти ни черта не решают. Они просто существуют как флажки, как маркетинговый наполнитель, и Google никогда не заботило, работает ли какой-то из инструментов в реальности. Я знаю менеджеров по продукту, которые были за рулём, и могу вас заверить, что этим людям наплевать.
Возьмём, к примеру, решение с развёртыванием якобы «одним щелчком мыши» Percona. Мне до смерти надоели проделки Google Cloud SQL, так что я начал рассматривать в качестве альтернативы создание собственного кластера Percona. И на этот раз Google вроде сделала хорошее дело, они собирались сэкономить мне немного времени и усилий одним нажатием кнопки!
Ну отлично, поехали. Перейдём по ссылке и нажмём эту кнопку. Выбираем «Да», чтобы согласиться на все параметры по умолчанию и развернуть кластер в своём облачном проекте Google. Ха-ха, не работает. Ничего из этого дерьма не работает. Инструмент никогда не тестировался, и он начал подгнивать с первой минуты, и меня не удивит, если более половины «решений» для развёртывания одним щелчком мыши (теперь мы понимаем, почему кавычки) вообще не работают. Это абсолютно беспросветная тьма, куда лучше не входить.
Но Google прямо призывает вас использовать их. Они хотят, чтобы ты их купил. Для них это транзакция. Они не хотят ничего поддерживать. Это не часть ДНК Google. Да, инженеры поддерживают друг друга, о чём свидетельствует моя история с Bigtable. Но в продуктах и услугах для обычных людей они всегда были безжалостны в закрытии любого сервиса, который не соответствует планке прибыльности, даже если у него миллионы пользователей.
И это представляет реальную проблему для GCP, потому что эта ДНК стоит за всеми облачными предложениями. Они не стремятся что-либо поддерживать; хорошо известно, что они отказываются размещать (как управляемый сервис) любое стороннее программное обеспечение до тех пор, пока AWS не сделает то же самое и не построит вокруг успешный бизнес, и когда клиенты буквально потребуют то же самое. Однако нужно приложить определённые усилия, чтобы заставить Google что-то поддерживать.
Это отсутствие культуры поддержки, в сочетании с принципом «давайте сломаем, чтобы сделать красивее», отчуждает от них разработчиков.
И это не очень хорошо, если вы хотите построить долгоживущую платформу.
Google, просыпайся, чёрт побери. Сейчас 2020 год. Ты всё ещё проигрываешь. Пришло время пристально посмотреть в зеркало и ответить, действительно ли ты хочешь остаться в облачном бизнесе.
Если хочешь остаться, то прекрати всё ломать. Ребята, вы же богатые. Мы, разработчики — нет. Поэтому, когда дело доходит до того, кто взвалит на себя бремя совместимости, вам нужно взять это на себя. Не нам.
Потому что есть ещё по крайней мере три действительно хороших облака. Они манят к себе.
А теперь я пойду дальше чинить все свои сломанные системы. Эх.
До следующего раза!
P. S. Обновление после прочтения некоторых обсуждений этой статьи (обсуждения великолепны, кстати). Поддержка Firebase не прекращена, и нет никаких планов, о которых я знаю. Тем не менее, у них есть неприятная ошибка потоковой передачи, которая заставляет Java-клиент останавливаться в App Engine. Один из их инженеров помог мне справиться с этой проблемой, когда я работал в Google, но они никогда реально не исправили баг, поэтому у меня есть паршивенький обходной путь, приходится каждый день перезапускать приложение GAE. И так уже четыре года! Теперь у них есть Firestore. Потребуется много работы, чтобы мигрировать на него, так как это совершенно другая система, а ошибка Firebase никогда не будет исправлена. Какой вывод можно сделать? Вы можете получить помощь, если работаете в компании. Наверное, я единственный, кто использует Firebase на GAE, потому что я записываю менее 100 ключей в родном на 100% приложении, и оно перестаёт работать каждые пару дней из-за известной ошибки. Что тут можно сказать, кроме как использовать его на свой страх и риск. Я перехожу на Redis.
Я также видел, как некоторые более опытные пользователи AWS говорили, что AWS обычно никогда не прекращает поддержки никаких сервисов, и SimpleDB — отличный пример. Мои предположения, что в AWS нет такой болезни с прекращением поддержки, как у Google, похоже, оправданы.
Кроме того, я заметил, что 20 дней назад команда Google App Engine сломала хостинг критической библиотеки Go, закрыв приложение GAE от одного из основных разработчиков Go. Действительно, глупо получилось.
Наконец, я слышал, что гуглеры уже обсуждают этот вопрос и в целом согласны со мной (люблю вас, ребята!). Но похоже, что они считают проблему нерешаемой, потому что в культуре Google никогда не было правильной структуры стимулов. Думаю, хорошо бы выкроить немного времени, чтобы обсудить абсолютно удивительный опыт работы с инженерами AWS, когда я работал в компании Grab. Как-нибудь в будущем, надеюсь!
И да, в 2005 году у них действительно были разные виды акульего мяса на гигантском шведском столе в здании 43, и мне больше всего нравилось мясо молотоголовых акул. Однако к 2006 году Ларри и Сергей избавились от всех нездоровых закусок. Так что во время истории с Bigtable в 2007 году действительно не было никаких акул и я вас подло обманул.
Когда я смотрел на облачную Bigtable четыре года назад (плюс-минус), стоимость была именно такой. Кажется, сейчас она немного снизилось, но это всё ещё ужасно много для пустого хранилища данных, особенно учитывая, что моя первая история показывает, насколько несущественна пустая большая таблица в их масштабе.
Извините, что обидел сообщество Apple и что не сказал ничего хорошего о Microsoft и т. д. Вы все правы, я очень ценю все дискуссии, которую вызвала эта статья! Но иногда нужно немного пустить волну, чтобы начать обсуждение, вы же понимаете?
Спасибо за чтение.
Апдейт 2, 19.08.2020. Stripe правильно выполняет обновление API!
Апдейт 3, 31.08.2020. Со мной связался инженер Google в Cloud Marketplace, который оказался моим старым другом. Он хотел выяснить, почему не работает C2D, и в конце концов мы выяснили: причина в том, что я создал свою сеть несколько лет назад, а C2D не срабатывает в устаревших сетях из-за отсутствующего параметра подсети в их шаблонах. Думаю, что потенциальным пользователям GCP лучше убедиться, что у них достаточно знакомых инженеров в Google…
Так что давай покончим с этим.
Начну с небольшой, но поучительной истории из тех времён, когда я только начал работать в Google. Знаю, что в последнее время я наговорил много плохого о Google, но меня расстраивает, когда родная компания регулярно принимает некомпетентные бизнес-решения. При этом нужно отдать должное: внутренняя инфраструктура Google действительно экстраординарная, можно смело утверждать, что сегодня нет ничего лучше. Основатели Google были гораздо лучшими инженерами, чем я когда-либо стану, и эта история только подтверждает данный факт.
Сначала немного предыстории: у Google есть технология хранения данных под названием Bigtable. Это было замечательное техническое достижение, одно из первых (если не первое) «бесконечно масштабируемое» хранилище пар «ключ-значение» (key-value store, K/V): по сути, начало NoSQL. В наши дни Bigtable всё ещё хорошо чувствует себя в довольно переполненном пространстве хранилищ K/V, но в то время (2005 год) оно было потрясающе крутое.
Одна забавная деталь Bigtable заключается в том, что у них были внутренние объекты плоскости управления (как часть реализации) под названием tablet-серверы, с большими индексами, и в какой-то момент они стали узким местом при масштабировании системы. Инженеры Bigtable ломали голову, как реализовать масштабируемость, и вдруг поняли, что могут заменить tablet-серверы другими хранилищами Bigtable. Так что Bigtable — это часть реализации Bigtable. Эти хранилища там на всех уровнях.
Еще одна интересная деталь заключается в том, что на какое-то время Bigtable стали популярными и вездесущими внутри Google, и у каждой команды было своё хранилище. Поэтому на одном из пятничных собраний Ларри Пейдж небрежно спросил мимоходом: «А почему у нас больше одного Bigtable? Почему не обойтись только одним?» Теоретически, одного хранилища должно было хватить для всех потребностей хранения Google. Конечно, они никогда не переходили только на одно по практическим причинам разработки (например, последствия потенциального сбоя), но теория была интересной. Одно хранилище для всей Вселенной (кстати, кто-нибудь знает, Amazon такое сделала со своим Sable?)
Так или иначе, вот моя история.
В то время я работал в Google чуть более двух лет, и однажды мне пришло письмо от инженерной команды Bigtable примерно такого содержания:
Уважаемый Стив,
Привет от команды Bigtable. Мы хотим сообщить, что в дата-центре [название дата-центра] вы используете очень, очень старый бинарный файл Bigtable. Эта версия больше не поддерживается, и мы хотим помочь вам перейти на последнюю версию.
Пожалуйста, дайте знать, если вы можете запланировать некоторое время для совместной работы над этим вопросом.
Всего наилучшего,
Команда Bigtable
В Google вам приходит много почты, поэтому с первого взгляда я прочитал примерно так:
Уважаемый получатель,
Привет от какой-то команды. Мы хотим сообщить, что бла-бла-бла-бла-бла. Бла-бла-бла-бла-бла-бла, и бла-бла-бла немедленно.
Пожалуйста, дайте нам знать, если вы можете запланировать часть своего драгоценного времени на бла-бла-бла.
Всего наилучшего,
Какая-то команда
Я почти удалил его сразу же, но на границе сознания ощутил тягостное, ноющее чувство, что это не совсем похоже на формальное письмо, хотя очевидно, что с адресатом ошиблись, потому что я не использовал Bigtable.
Но это было странно.
Остаток дня я попеременно думал о работе и о том, какой вид акульего мяса попробовать в микро-кухне, из которых по крайней мере три были достаточно близко, чтобы попасть с моего места метким броском бисквита, но мысль о письме не покидала меня с растущим чувством лёгкой тревоги.
Они явно назвали моё имя. И письмо отправлено на мой адрес электронной почты, а не на чей-то ещё, и это не cc: или bcc:. Тон очень личный и чёткий. Может, это какая-то ошибка?
Наконец, любопытство взяло верх и я пошёл взглянуть на консоль Borg в дата-центре, который они упомянули.
И конечно, у меня в управлении было хранилище BigTable. Что-что? Я взглянул на его содержимое, и — надо же! Оно было из инкубатора Codelab, в котором я сидел первую неделю работы в Google в июне 2005 года. Codelab заставлял вас запустить Bigtable, чтобы вы записали туда некоторые значения, и я, видимо, так и не закрыл хранилище после этого. Оно всё ещё работало, хотя прошло более двух лет.
В этой истории есть несколько примечательных аспектов. Во-первых, работа Bigtable был настолько несущественна в масштабе Google, что только через два года лишнее хранилище кто-то заметил, да и то лишь потому, что версия бинарника устарела. Для сравнения, я когда-то рассматривал возможность использования Bigtable в Google Cloud для моей онлайн-игры. В то время эта услуга стоила примерно $16 000 в год за пустую Bigtable на GCP. Я не говорю, что они вас обманывают, но, по моему личному мнению, это большие деньги за пустую грёбаную базу данных.
Ещё один примечательный аспект заключается в том, что хранилище по-прежнему работало через два года. WTF? Дата-центры приходят и уходят; они испытывают перебои, они проходят плановое техническое обслуживание, они всё время меняются. Железо обновляется, коммутаторы меняются местами, всё постоянно совершенствуется. Как, чёрт возьми, они смогли сохранить мою программу запущенной в течение двух лет с учётом всех этих изменений? Это может показаться скромным достижением в 2020 году, но в 2005-2007 годах оно было весьма впечатляющим.
И самый замечательный аспект заключается в том, что посторонняя инженерная команда в каком-то другом штате обращается ко мне, владельцу какого-то крошечного, практически пустого экземпляра Bigtable, у которого нулевой трафик в течение последних двух лет — и предлагают помощь, чтобы обновить его.
Я поблагодарил их, удалил хранилище, и жизнь пошла своим чередом. Но тринадцать лет спустя я всё ещё думаю об этом письме. Потому что иногда мне приходят подобные письма от Google Cloud. Они выглядят так:
Уважаемый пользователь Google Cloud,
Напоминаем, что мы прекращаем обслуживание сервиса [важный сервис, который вы используете] с августа 2020 года, после чего вы не сможете обновить свои инстансы. Рекомендуем перейти на последнюю версию, которая проходит бета-тестирование, не имеет никакой документации, никакого пути миграции и которая заранее устарела с нашей любезной помощью.
Мы стремимся к тому, чтобы это изменение минимально повлияло на всех пользователей платформы Google Cloud.
Лучшие друзья навсегда,
Облачная платформа Google
Но я почти не читаю такие письма, потому что на самом деле в них говорится следующее:
Уважаемый получатель,
Пошёл ты к чёрту. Пошёл ты, пошёл ты, пошёл ты. Отбрось всё, что ты делаешь, потому что это не важно. Что важно, так это наше время. Мы тратим время и деньги, чтобы поддерживать наше дерьмо, и мы устали от этого, поэтому больше не будем его поддерживать. Так что бросай свои грёбаные планы и начинай копаться в нашей дерьмовой документации, выпрашивая объедки на форумах, и, кстати, наше новое дерьмо полностью отличается от старого дерьма, потому что мы довольно сильно испортили этот дизайн, хех, но это твоя проблема, а не наша.
Мы по-прежнему прикладываем усилия, чтобы все твои разработки стали непригодны для использования в течение одного года.
Пожалуйста иди нах,
Облачная платформа Google
И дело в том, что я получаю такие письма примерно раз в месяц. Это происходит так часто и так постоянно, что они неизбежно оттолкнули меня от GCP в лагерь противников облаков. Я больше не согласен зависеть от их проприетарных разработок, потому что на самом деле девопсу легче поддерживать систему с открытым исходным кодом на голой виртуалке, чем пытаться угнаться за Google с её политикой закрытия «устаревших» продуктов.
Прежде чем вернуться к Google Cloud, потому что я даже близко не закончил их критиковать, давайте посмотрим на работу компании в некоторых других областях. Инженеры Google гордятся своей дисциплиной разработки программного обеспечения, и именно это на самом деле вызывает проблемы. Гордость — это ловушка для неосторожных, она заставила многих сотрудников Google думать, что их решения всегда правильны и что правильность (по какому-то неопределённому нечёткому определению) важнее, чем забота о клиентах.
Приведу несколько произвольных примеров из других больших проектов за пределами Google, но надеюсь, что вы увидите этот шаблон везде. Он заключается в следующем: обратная совместимость поддерживает живучесть и актуальность систем в течение десятилетий.
Обратная совместимость — это цель проектирования всех успешных систем, предназначенных для открытого использования, то есть реализованных с открытым исходным кодом и/или на открытых стандартах. Я чувствую, что говорю что-то слишком очевидное, что всем даже неудобно, но нет. Это политический вопрос, поэтому нужны примеры.
Первая система, которую я выберу, самая старая: GNU Emacs, это своего рода гибрид между Блокнотом Windows, ядром ОС и Международной космической станцией. Это немного сложно объяснить, но в двух словах Emacs — это платформа, созданная в 1976 году (да, почти полвека назад) для программирования, чтобы повысить вашу продуктивность, но маскируется под текстовый редактор.
Я использую Emacs каждый божий день. Да, я также использую IntelliJ каждый день, она уже сама превратилась в мощную инструментальную платформу. Но написание расширений для IntelliJ — гораздо более амбициозная и сложная задача, чем написание расширений для Emacs. И что ещё более важно, всё написанное для Emacs сохраняется вечно.
Я по-прежнему использую программное обеспечение, которое написал для Emacs ещё в 1995 году. И уверен, что кто-то использует модули, написанные для Emacs в середине 80-х, если не раньше. Время от времени они могут потребовать незначительной настройки, но это действительно довольно редко. Я не знаю ничего из того, что я когда-либо писал для Emacs (а я написал много), в чём пришлось бы перестроить архитектуру.
В Emacs есть функция под названием make-obsolete для устаревших сущностей. Терминология Emacs для фундаментальных компьютерных концепций (например, что такое «окно») часто отличается от отраслевых конвенций, потому что Emacs ввёл их очень давно. Это типичная опасность для тех, кто опередил своё время: все ваши термины некорректны. Но в Emacs действительно есть концепция устаревания, которая на их жаргоне называется obsolescence.
Но в мире Emacs, похоже, другое рабочее определение. Другая основополагающая философия, если хотите.
В мире Emacs (и во многих других областях, которые мы рассмотрим ниже) статус устаревших API в основном означает: «Вы действительно не должны использовать этот подход, потому что, хотя он и работает, он страдает от различных недостатков, которые мы перечислим здесь. Но, в конце концов, это ваш выбор».
В мире Google статус устаревшего продукта означает: «Мы нарушаем свои обязательства перед вами». Это действительно так. Вот что это по сути означает. Это означает, что они заставят вас регулярно проделывать некоторую работу, возможно, большую работу, в наказание за то, что вы поверили в их красочную рекламу: у нас лучшее программное обеспечение. Самое быстрое! Вы делаете всё по инструкции, запускаете своё приложение или сервис, а затем — бац, через год или два оно ломается.
Это всё равно что продавать подержанный автомобиль, который точно сломается через 1500 км.
Это два совершенно разных философских определения «устаревания». Определение Google пахнет запланированным устареванием. Я не верю, что это на самом деле запланированное устаревание в том же смысле, как у Apple. Но Google определённо планирует сломать ваши программы, окольным путём. Я знаю это, потому что проработал там инженером-программистом более 12 лет. У них есть расплывчатые внутренние рекомендации, в какой мере следует соблюдать обратную совместимость, но в конечном итоге это зависит от каждой отдельной команды или службы. Нет никаких рекомендаций корпоративного или инженерного уровня, и самая смелая рекомендация с точки зрения циклов устаревания — это «попробуйте дать клиентам 6-12 месяцев на обновление, прежде чем сломать им всю систему».
Проблема гораздо серьёзнее, чем они думают, и она сохранится ещё долгие годы, потому что забота о клиентах не входит в их ДНК. Подробнее об этом ниже.
На данный момент я собираюсь сделать смелое утверждение, что Emacs успешен в значительной степени и даже в основном потому, что они так серьёзно относятся к обратной совместимости. Собственно, это и есть тезис нашей статьи. Успешные долгоживущие открытые системы обязаны своим успехом микросообществам, которые десятилетиями живут вокруг расширений/плагинов. Это и есть экосистема. Я уже рассуждал о сути платформ и о том, насколько они важны, и о том, что Google никогда за всю свою корпоративную историю не понимала, что входит в создание успешной открытой платформы, не считая Android или Chrome.
Вообще-то я должен вкратце упомянуть Android, потому что вы наверняка подумали о нём.
Во-первых, Android — это не Google. Они не имеют почти ничего общего друг с другом. Android — это компания, которая была куплена Google в июле 2005 года, этой компании было разрешено работать более или менее автономно и фактически она осталась в значительной степени нетронутой в течение прошедших лет. Android — это печально известный технический стек и столь же печально известная колючая организация. Как выразился один гуглер, «нельзя просто так взять и войти в Android».
В одной из прошлых статей я уже рассуждал, насколько плохими были некоторые из ранних дизайнерских решений Android. Чёрт возьми, когда я писал ту статью, они занимались развёртыванием дерьма под названием «мгновенные приложения», которые теперь (сюрприз!) устарели, и сочувствую, если вы были достаточно глупы, чтобы послушаться Google и перенести свой контент в эти мгновенные приложения.
Но здесь есть разница, существенная разница, которая заключается в том, что люди из Android действительно понимают, насколько важны платформы, они изо всех сил стараются сохранить работоспособность старых приложений Android. На самом деле, их усилия сохранить обратную совместимость настолько экстремальны, что даже я, во время своего краткого пребывания в подразделении Android несколько лет назад, обнаружил, что пытаюсь убедить их отказаться от поддержки некоторых из самых старых устройств и API (я ошибался, как и во многих других вещах прошлого и настоящего. Извините, ребята из Android! Теперь, когда я побывал в Индонезии, я понимаю, зачем они нам нужны).
Люди из Android поддерживают обратную совместимость до почти невообразимых крайностей, что нагромождает огромное количество устаревших технических долгов в их системах и цепочках инструментов. О боже, вы бы видели некоторые сумасшедшие вещи, которые им приходится делать в своей системе сборки, и всё это во имя совместимости.
За это я присуждаю Android заветную награду «Ты не Google». Они действительно не хотят становится Google, которая не умеет создавать долговечные платформы, а вот Android знает, как это делать. И поэтому Google ведёт себя очень мудро в одном отношении: позволяет людям в Android делать всё по-своему.
Однако мгновенные приложения для Android были довольно глупой идеей. И знаете, почему? Потому что они требовали переписать и перепроектировать ваше приложение! Как будто люди просто так возьмут и перепишут два миллиона приложений. Предполагаю, что мгновенные приложения были идеей какого-то гуглера.
Но здесь есть разница. Обратная совместимость сопряжена с большими затратами. Android сам несёт бремя этих затрат, в то время как Google настаивает на том, чтобы это бремя несли вы, платный клиент.
Вы можете увидеть приверженность Android обратной совместимости в её API-интерфейсах. Когда у вас четыре или пять различных подсистем для выполнения буквально одного и того же, это верный признак, что в основе лежит приверженность обратной совместимости. Что в мире платформ является синонимом приверженности вашим клиентам и вашему рынку.
Главная проблема Google здесь — их гордость своей инженерной гигиеной. Им не нравится, когда есть много разных способов делать одно и то же, причем старые, менее желательные способы сидят рядом с новыми, более причудливыми способами. Это увеличивает кривую обучения для новичков в системе, это увеличивает бремя поддержки устаревших API, это замедляет скорость новых функций, и главный грех — это некрасиво. Google — как Леди Эскот из «Алисы в Стране чудес» Тима Бертона:
Леди Эскот:
— Алиса, знаешь, чего я боюсь больше всего?
— Упадка аристократии?
— Я опасалась, что у меня будут некрасивые внуки.
Чтобы понять компромисс между красивым и практичным, давайте взглянем на третью успешную платформу (после Emacs и Android) и посмотрим, как она работает: сама Java.
В Java масса устаревших API. Устаревание очень популярно среди Java-программистов, даже популярнее, чем в большинстве языков программирования. В самой Java, основном языке и библиотеках постоянно происходит устаревание API.
Если взять только один из тысяч примеров, закрытие потоков считается устаревшим. Оно устарело с момента выпуска Java 1.2 в декабре 1998 года. Прошло 22 года с тех пор, как это устарело.
Но мой реальный код в продакшне по-прежнему убивает потоки каждый день. Разве это хорошо? Абсолютно! Я имею в виду, конечно, если бы я переписал код сегодня, я бы реализовал это по-другому. Но код моей игры, которая за последние два десятилетия сделала счастливыми сотни тысяч людей, написана с функцией закрытия потоков, которые висят слишком долго, и мне никогда не приходилось его менять. Я знаю свою систему лучше всех, у меня буквально 25-летний опыт работы с ней в продакшне, и я могу точно сказать: в моём случае закрытие этих конкретных рабочих потоков совершенно безвредно. Не стоит тратить время и силы на переписывание этого кода, и хвала Ларри Эллисону (наверное), что Oracle не заставила меня переписывать его.
Наверное, Oracle тоже разбирается в платформах. Кто его знает.
Доказательства вы можете встретить по всем ключевым Java API, которые пронизаны волнами устаревания, подобно линиям ледника в каньоне. В библиотеке Java Swing можно легко найти пять или шесть различных менеджеров навигации с клавиатуры (KeyboardFocusManager). На самом деле трудно найти Java API, который не является устаревшим. Но они всё ещё работают! Думаю, команда Java по-настоящему удалит API только в том случае, если интерфейс вызовет вопиющую проблему безопасности.
Вот в чём дело, ребята: мы, разработчики программного обеспечения, все очень заняты, и в каждой области программного обеспечения мы сталкиваемся с конкурирующими альтернативами. В любой момент времени программисты на языке X рассматривают язык Y как возможную замену. О, вы мне не верите? Вы хотите назвать Swift? Мол, все мигрируют на Swift и никто от него не отказывается, верно? Ого, как мало вы знаете. Компании считают расходы на двойные команды мобильной разработки (iOS и Android) — и они начинают понимать, что эти кросс-платформенные системы разработки со смешными названиями, такие как Flutter и React Native, действительно работают, и с их помощью можно сократить размеры своих мобильных команд вдвое или, наоборот, сделать их вдвое продуктивнее. На кону реальные деньги. Да, есть компромиссы, но, с другой стороны, де-е-еньги.
Предположим гипотетически, что Apple по глупости взяла пример с Гвидо ван Россума и объявила, что Swift 6.0 обратно несовместим со Swift 5.0, во многом как Python 3 несовместим с Python 2.
Наверное, я рассказывал эту историю лет десять назад, но лет пятнадцать назад я ездил в лагерь O’Reilly’s Foo Camp с Гвидо, сидел в палатке с Полом Грэмом и кучей больших шишек. Мы сидели в изнуряющей жаре и ждали, когда Ларри Пейдж вылетит на своём личном вертолете, а Гвидо монотонно бубнил о «Питоне 3000», который он назвал по количеству лет, которое потребуется всем, чтобы туда мигрировать. Мы всё время спрашивали его, почему он нарушает совместимость, и он отвечал: “Unicode”. И мы спрашивали, если нам придется переписать наш код, то какие еще преимущества мы увидим? И он отвечал “Yoooooooooooooouuuuuuuniiiiiiicoooooooode”.
Если установить Google Cloud Platform SDK (“gcloud”), то вы получите следующее уведомление:
Уважаемый получатель,
Мы хотели бы вам напомнить, что поддержка Python 2 устарела, так что пошёёёёёёёёл тыыыыыыы
… и так далее. Круг жизни.
Но дело в том, что у каждого разработчика есть выбор. И если заставить их переписывать код достаточно часто, то они могут подумать и о других вариантах. Они не ваши заложники, как бы вам этого ни хотелось. Они — ваши гости. Python по-прежнему очень популярный язык программирования, но, чёрт побери, Python 3(000) создал такой бардак у себя, в своих сообществах и у пользователей своих сообществ, что последствия не могут разгрести уже пятнадцать лет.
Сколько программ Python было переписано на Go (или Ruby, или какой-то другой альтернативе) из-за этой обратной несовместимости? Сколько нового программного обеспечения было написано на чём-то другом, кроме Python, хотя оно могло быть написано на Python, если бы Гвидо не сжёг всю деревню? Трудно сказать, но Python явно пострадал. Это огромный бардак, и все в проигрыше.
Итак, допустим, Apple берёт пример с Гвидо и нарушает совместимость. Как думаете, что будет дальше? Ну, может, 80-90% разработчиков перепишут своё программное обеспечение, если получится. Другими словами, 10-20% пользовательской базы автоматически уходят на какой-то конкурирующий язык, например, Flutter.
Сделайте это несколько раз — и вы потеряете половину своей пользовательской базы. Как и в спорте, в мире программирования текущая форма тоже значит всё. Любой, кто потеряет половину пользователей за пять лет, будет считаться Большим Жирным Неудачником. Вы же должны быть в тренде в мире платформ. Но именно здесь отказ от поддержки старых версий со временем вас погубит. Потому что каждый раз, когда вы избавляетесь от части разработчиков, вы (а) теряете их навсегда, потому что они сердятся на вас за нарушение контракта, и (б) отдаёте их своим конкурентам.
По иронии судьбы, я тоже помог Google превратиться в такую примадонну, которая игнорирует обратную совместимость, когда создал Grok, систему анализа и понимания исходного кода, которая облегчает автоматизацию и оснастку инструментарием на основе самого кода — похоже на IDE, но здесь облачный сервис хранит материализованные представления всех миллиардов строк исходного кода Google в большом хранилище данных.
Grok предоставил гуглерам мощную основу для проведения автоматизированного рефакторинга по всей кодовой базе (буквально по всему Google). Система вычисляет не только ваши восходящие зависимости (от которых вы зависите), но и нисходящие (которые зависят от вас), поэтому при смене API вы знаете всех, кого ломаете! Таким образом, при внесении изменений вы можете проверить, что каждый потребитель вашего API обновился до новой версии, а в реальности часто с помощью инструмента Rosie, который они написали, вы можете полностью автоматизировать процесс.
Это позволяет кодовой базе Google внутренне быть почти сверхъестественно «чистой», так как у них эти роботизированные слуги снуют по всему дому и автоматически всё подчищают, если они переименовали SomeDespicablyLongFunctionName в SomeDespicablyLongMethodName, потому что кто-то решил, что это некрасивый внук, и его нужно усыпить.
И, честно говоря, это довольно хорошо работает для Google… внутренне. Я имею в виду, да, сообщество Go в Google действительно по-доброму посмеивается с сообщества Java в Google из-за их привычки к непрерывному рефакторингу. Если вы что-то перезапускаете N раз, то это означает, что вы не только испортили это N-1 раз, но и через некоторое время становится совершенно ясно, что вы, вероятно, испортили это и с N-ой попытки. Но, по большому счету, они остаются выше этой суеты и сохраняют код «чистым».
Проблемы начинаются, когда они пытаются навязать такое отношение своим облачным клиентам и пользователям других API.
Я немного познакомил вас с Emacs, Android и Java; давайте посмотрим на последнюю успешную долгоживущую платформу: сам Веб. Можете представить, через сколько итераций прошёл HTTP с 1995 года, когда мы использовали мигающие теги <blink> и значки «В разработке» на веб-страницах.
Но это всё ещё работает! И эти страницы всё ещё работают! Да, ребята, браузеры — мировые чемпионы по обратной совместимости. Chrome — это ещё один пример редкой платформы Google, у которой головы привинчены правильно, и, как вы уже догадались, Chrome эффективно действует как изолированная компания отдельно от остального Google.
Я также хочу поблагодарить наших друзей среди разработчиков операционных систем: Windows, Linux, НЕ APPLE ПОШЛА ТЫ APPLE, FreeBSD и так далее, за то, что они проделали такую большую работу по обратной совместимости на своих успешных платформах (Apple получает в лучшем случае тройку с минусом, так как они постоянно всё ломают без всякой уважительной причины, но каким-то образом сообщество справляется с этим в каждом релизе, и до сих пор контейнеры с OS X ещё не полностью устарели… пока).
Но подождите, скажете вы. Разве мы не сравниваем яблоки с апельсинами — автономные программные системы на одной машине, такие как Emacs/JDK/Android/Chrome, с многосерверными системами и API, как в облачных сервисах?
Ну, я написал об этом вчера в твиттере, но в стиле Ларри Уолла (создатель языка программирования Perl — прим. пер.) по принципу «отстой/рулез» я поискал слово deprecated на сайтах для разработчиков Google и Amazon. И хотя у AWS в сотни раз больше предложений услуг, чем у GCP, документация разработчиков Google упоминает устаревание примерно в семь раз чаще.
Если кто-то из Google читает это, то наверняка они готовы вытащить диаграммы в стиле Дональда Трампа, что на самом деле делают всё правильно, и что я не должен делать несправедливые сравнения, такие как «количество упоминаний слова deprecated в зависимости от количества сервисов».
Но спустя столько лет Google Cloud по-прежнему остается сервисом № 3 (я так и не написал статью о неудачной попытке стать № 2), но если верить инсайдерам, есть некоторые опасения, что они могут скоро опуститься до № 4.
У меня нет веских аргументов, чтобы «доказать» свой тезис. Всё, что у меня есть, — это красочные примеры, которые я накопил за 30 лет работы в качестве разработчика. Я уже упоминал о глубоко философской природе этой проблемы; в некотором смысле она политизирована в сообществах разработчиков. Некоторые считают, что создатели платформ должны заботиться о совместимости, а другие считают, что это забота пользователей (самих разработчиков). Одно из двух. И в самом деле, разве это не политический вопрос, когда мы решаем, кто должен нести расходы за общие проблемы?
Так что это политика. И наверняка будут гневные ответы на моё выступление.
Как пользователь облачной платформы Google, а также как пользователь AWS в течение двух лет (работая в компании Grab), могу сказать, что существует огромная разница между философиями Amazon и Google, когда речь заходит о приоритетах. Я не веду активную разработку на AWS, поэтому не очень хорошо знаю, насколько часто они убирают старые API. Но есть подозрение, что это происходит далеко не так часто, как в Google. И я искренне верю, что этот источник постоянных споров и разочарований в GCP является одним из самых больших факторов, сдерживающих развитие платформы.
Знаю, что не назвал конкретные примеры систем GCP, поддержка которых прекращена. Могу сказать, что практически всё, что я использовал, от сетей (от самых старых до VPC) до хранилищ (Cloud SQL v1-v2), Firebase (теперь Firestore с совершенно другим API), App Engine (давайте даже не будем начинать), облачных конечных точек Cloud Endpoint и до… я не знаю — абсолютно всё это заставляло переписывать код максимум через 2-3 года, и они никогда не автоматизировали для вас миграцию, а часто не было никакого документированного пути миграции вообще. Словно так и положено.
И каждый раз, когда я смотрю на AWS, я спрашиваю себя, какого чёрта я до сих пор сижу на GCP. Им явно не нужны клиенты. Им нужны покупатели. Понимаете разницу? Давайте объясню.
У Google Cloud есть Marketplace, на котором люди предлагают свои программные решения, а чтобы избежать эффекта пустого ресторана, нужно было заполнить его некоторыми предложениями, поэтому они заключили контракт с компанией Bitnami, чтобы создать кучу решений, которые развёртываются «одним щелчком мыши», или я сам должен написать «решения», потому что эти ни черта не решают. Они просто существуют как флажки, как маркетинговый наполнитель, и Google никогда не заботило, работает ли какой-то из инструментов в реальности. Я знаю менеджеров по продукту, которые были за рулём, и могу вас заверить, что этим людям наплевать.
Возьмём, к примеру, решение с развёртыванием якобы «одним щелчком мыши» Percona. Мне до смерти надоели проделки Google Cloud SQL, так что я начал рассматривать в качестве альтернативы создание собственного кластера Percona. И на этот раз Google вроде сделала хорошее дело, они собирались сэкономить мне немного времени и усилий одним нажатием кнопки!
Ну отлично, поехали. Перейдём по ссылке и нажмём эту кнопку. Выбираем «Да», чтобы согласиться на все параметры по умолчанию и развернуть кластер в своём облачном проекте Google. Ха-ха, не работает. Ничего из этого дерьма не работает. Инструмент никогда не тестировался, и он начал подгнивать с первой минуты, и меня не удивит, если более половины «решений» для развёртывания одним щелчком мыши (теперь мы понимаем, почему кавычки) вообще не работают. Это абсолютно беспросветная тьма, куда лучше не входить.
Но Google прямо призывает вас использовать их. Они хотят, чтобы ты их купил. Для них это транзакция. Они не хотят ничего поддерживать. Это не часть ДНК Google. Да, инженеры поддерживают друг друга, о чём свидетельствует моя история с Bigtable. Но в продуктах и услугах для обычных людей они всегда были безжалостны в закрытии любого сервиса, который не соответствует планке прибыльности, даже если у него миллионы пользователей.
И это представляет реальную проблему для GCP, потому что эта ДНК стоит за всеми облачными предложениями. Они не стремятся что-либо поддерживать; хорошо известно, что они отказываются размещать (как управляемый сервис) любое стороннее программное обеспечение до тех пор, пока AWS не сделает то же самое и не построит вокруг успешный бизнес, и когда клиенты буквально потребуют то же самое. Однако нужно приложить определённые усилия, чтобы заставить Google что-то поддерживать.
Это отсутствие культуры поддержки, в сочетании с принципом «давайте сломаем, чтобы сделать красивее», отчуждает от них разработчиков.
И это не очень хорошо, если вы хотите построить долгоживущую платформу.
Google, просыпайся, чёрт побери. Сейчас 2020 год. Ты всё ещё проигрываешь. Пришло время пристально посмотреть в зеркало и ответить, действительно ли ты хочешь остаться в облачном бизнесе.
Если хочешь остаться, то прекрати всё ломать. Ребята, вы же богатые. Мы, разработчики — нет. Поэтому, когда дело доходит до того, кто взвалит на себя бремя совместимости, вам нужно взять это на себя. Не нам.
Потому что есть ещё по крайней мере три действительно хороших облака. Они манят к себе.
А теперь я пойду дальше чинить все свои сломанные системы. Эх.
До следующего раза!
P. S. Обновление после прочтения некоторых обсуждений этой статьи (обсуждения великолепны, кстати). Поддержка Firebase не прекращена, и нет никаких планов, о которых я знаю. Тем не менее, у них есть неприятная ошибка потоковой передачи, которая заставляет Java-клиент останавливаться в App Engine. Один из их инженеров помог мне справиться с этой проблемой, когда я работал в Google, но они никогда реально не исправили баг, поэтому у меня есть паршивенький обходной путь, приходится каждый день перезапускать приложение GAE. И так уже четыре года! Теперь у них есть Firestore. Потребуется много работы, чтобы мигрировать на него, так как это совершенно другая система, а ошибка Firebase никогда не будет исправлена. Какой вывод можно сделать? Вы можете получить помощь, если работаете в компании. Наверное, я единственный, кто использует Firebase на GAE, потому что я записываю менее 100 ключей в родном на 100% приложении, и оно перестаёт работать каждые пару дней из-за известной ошибки. Что тут можно сказать, кроме как использовать его на свой страх и риск. Я перехожу на Redis.
Я также видел, как некоторые более опытные пользователи AWS говорили, что AWS обычно никогда не прекращает поддержки никаких сервисов, и SimpleDB — отличный пример. Мои предположения, что в AWS нет такой болезни с прекращением поддержки, как у Google, похоже, оправданы.
Кроме того, я заметил, что 20 дней назад команда Google App Engine сломала хостинг критической библиотеки Go, закрыв приложение GAE от одного из основных разработчиков Go. Действительно, глупо получилось.
Наконец, я слышал, что гуглеры уже обсуждают этот вопрос и в целом согласны со мной (люблю вас, ребята!). Но похоже, что они считают проблему нерешаемой, потому что в культуре Google никогда не было правильной структуры стимулов. Думаю, хорошо бы выкроить немного времени, чтобы обсудить абсолютно удивительный опыт работы с инженерами AWS, когда я работал в компании Grab. Как-нибудь в будущем, надеюсь!
И да, в 2005 году у них действительно были разные виды акульего мяса на гигантском шведском столе в здании 43, и мне больше всего нравилось мясо молотоголовых акул. Однако к 2006 году Ларри и Сергей избавились от всех нездоровых закусок. Так что во время истории с Bigtable в 2007 году действительно не было никаких акул и я вас подло обманул.
Когда я смотрел на облачную Bigtable четыре года назад (плюс-минус), стоимость была именно такой. Кажется, сейчас она немного снизилось, но это всё ещё ужасно много для пустого хранилища данных, особенно учитывая, что моя первая история показывает, насколько несущественна пустая большая таблица в их масштабе.
Извините, что обидел сообщество Apple и что не сказал ничего хорошего о Microsoft и т. д. Вы все правы, я очень ценю все дискуссии, которую вызвала эта статья! Но иногда нужно немного пустить волну, чтобы начать обсуждение, вы же понимаете?
Спасибо за чтение.
Апдейт 2, 19.08.2020. Stripe правильно выполняет обновление API!
Апдейт 3, 31.08.2020. Со мной связался инженер Google в Cloud Marketplace, который оказался моим старым другом. Он хотел выяснить, почему не работает C2D, и в конце концов мы выяснили: причина в том, что я создал свою сеть несколько лет назад, а C2D не срабатывает в устаревших сетях из-за отсутствующего параметра подсети в их шаблонах. Думаю, что потенциальным пользователям GCP лучше убедиться, что у них достаточно знакомых инженеров в Google…