об авторе
Хэ Юань
Классические интернет-практики
Он присоединился к Liulishuo в конце 2014 года и в настоящее время возглавляет команду платформы. До прихода в Люлишо я работал на заводе в Ханчжоу.
Внутри
Позволять
Большой
Тсуна
1. Управление пакетами
2. Управление кодом (управление кодом на нескольких языках)
3.bazel build //:go
4.Demo
1. Управление пакетами
VendorБытьБыть
Go представил поставщика с версии 1.5. В версии 1.7 код загружался от поставщика по умолчанию. Если установленная версия библиотеки Go, которую вы используете, несовместима, размещение ее под поставщиком является хорошим выбором. Например, это Роб Пайк — это проект с открытым исходным кодом upspin, upspin — это проект по обмену файлами, используйте дерево, чтобы посмотреть его каталог Vendor:
БытьБыть
Потому что upspin использует фьюзы, естественно, все фьюзы берутся, как и протобуфы, крипто... В принципе, все, что используется, копируется один раз, это самый распространенный у всех способ использования вендора.
Но подумайте об этом внимательно, код под вендором изначально является открытым исходным кодом, почему вы должны отправлять его в свою собственную библиотеку? Как обновить версию библиотеки под Vendor? Как решить проблему зависимостей?
В феврале этого года Рассу Коксу было что сказать, говоря, что мы столько лет усердно работали с вендором, и Golang действительно нуждается в инструменте управления зависимостями и версиями, поэтому он опубликовал статью и сказал три вещи
1. Rust's Cargo проделал хорошую работу, поэтому мы
2. Восемь лет установки и установки удачны для всех, перейдите к модулю, чтобы понять
3. модуль go уничтожит большую часть каталога поставщика
Vgo
Тогда есть Вго
БытьБыть
Написал 7 блогов, объясняющих, зачем делать vgo и зачем использовать модуль Go. Но когда для ясного объяснения технологии или управления версиями требуется так много блогов, я полагаю, что пользователи могут не понять ее за короткий промежуток времени.
Вернемся к началу. У управления пакетами есть три проблемы, которые нужно решить:
1. Версии пакетов. Я не хочу, чтобы V1, V2, V3 появлялись в пакетах,
2. Я надеюсь, что каждый код сборки, результат будет одинаковым
3. Work outside of $GOPATH
БытьБыть
Расс поднял вопрос, чтобы проиллюстрировать эту проблему.В настоящее время у Golang на Github около 40 000 звезд.Этот вопрос нравится 141 человеку, а 4 человека уменьшили 1. Конечно, это ничего не значит.
Глядя на вещь, обычно гораздо лучше понять ее с помощью вопросов, чем пассивно принять.В беглой речи это называется любопытством.Здесь наши вопросы:
Golang Столько лет в Google, столько лет в Googleкак этоbuild Goкодиз ?
С этим вопросом переходим к следующей теме
2. Управление кодом
Управление кодом довольно сложно.Помимо написания кода на работе,это управление кодом.Если вы хотите его организовать,уместно ли его здесь ставить,и когда ваш бизнес разрастется,нужно спросить нужен ли код быть абстрагированным или нет, и нужно ли в нем разобраться.Используют ли другие команды.
Liulishuo быстро росла и столкнулась со многими техническими проблемами. Например, когда компания быстро растет, как поддержать свой бизнес? Другой пример: в кодовой базе есть C++, а некоторые библиотеки машинного обучения написаны на Python, кодовая база — это не только код Golang, так как же нам ее построить?
Возвращаясь к этой теме, бизнес Liulishuo действительно быстро вырос в последнее время. Прежде чем я пришел сюда, я подсчитывал службы, работающие в Интернете.Сейчас работает около 213 служб, но это завышенное число, которое включает в себя некоторые собственные службы k8s. таких сервисов, как kube-proxy, поэтому в сети насчитывается около 160+ или 180+ отдельных проектов.В принципе, для разработки нормально управлять несколькими проектами одновременно.
БытьБыть
Кроме того, у нас на самом деле есть некоторые очень сложные системы, которые развиваются и постепенно меняются. Например, у нас есть участие алгоритма в адаптивном обучении, участие данных и участие в бэкэнде. При таком количестве типов совместной работы возникнут проблемы в сотрудничестве. и тесная связь. Она становится компанией, работающей с большими данными. Большие данные означают, что становится все более и более необходимым указывать нам, что делать дальше, посредством обратной связи с данными. Этот цикл обратной связи очень важен, и он должен быть своевременным. взаимодействие между разными данными делать?как взаимодействовать с разными языками,как компилировать разнородные проекты,ты не можешь сказать что я тебе дам makefile Перейдите к компиляции, тогда этот make-файл может быть вонючим и длинным, и нет возможности его поддерживать.
2.1 Проблемы управления кодом
Каковы проблемы управления кодом во время быстрого роста? Например, мы используем protobuf для определения крупномасштабных структур данных в Liulishuo Как мне сообщить вам, что я отбрасываю поле? Есть надежда, что все сборки CI репо, которые зависят от этого прототипа, потерпят неудачу.
БытьБыть
Мы можем посмотреть на примере:
БытьБыть
Если вы понимаете свой английский, вы знаете, что на самом деле существует много типов вопросов (деятельность). Мы определяем перечисление для типа этих действий. По историческим причинам каждый написал разные перечисления в разных системах. Тег представляет разные значения в разных системах. Проблема, возникающая в процессе последующего использования, заключается в том, что разные системы получают один и тот же тег, но представляют разные значения. Например, 0 представляет PRESENTATION_TYPE в некоторых системах, но внутри других систем НЕИЗВЕСТНО.
2.2 Как повторно использовать код и решения
Например, вы написали библиотеку и make-файл, как сообщить об этом другим после того, как вы, наконец, запустите его локально? Например, в Liulishuo есть функция отпечатка пальца. У нас есть некоторый контент темы, и нам нужно генерировать идентификаторы в соответствии с содержанием. Функция отпечатка пальца имеет разные реализации, включая JAVA и C++. Как мы можем гарантировать, что после изменения функции отпечатка пальца? языки тоже меняются вместе, а как вы их в разные репо ставили можно забыть.
2.3 Как делиться знаниями
Надеемся, что для решения системы достаточно сделать это один раз. В 2017 году Liulishuo начал использовать Bazel после того, как переманил двух докторов наук из Google.Bazel в основном решил вышеуказанные проблемы.Bazel — это Google.Blaze Версия системы с открытым исходным кодом, bazel все еще находится в стадии бета-тестирования и официально не выпустила 1.0.rules_go Golang на самом деле все еще альфа-версия, которая еще не достигла бета-версии, поэтому я наступил на некоторые ямы, но, к счастью, это в принципе не проблема использовать сейчас.
Первый взгляд на данные об использовании Google Blaze
БытьБыть
Весь код Google находится в репозитории, 45 000 коммитов в день, 800 000 сборок в день, и, конечно же, у них есть специальная команда для Blaze.
Bazel отличается от Makefile, давайте взглянем на сравнение файла BUILD (это фрагмент сборки leveldb)
БытьБыть
Bazel BUILD справа, Makefile слева, очевидно, вы можете видеть, что ясно, а что нет.
БытьБыть
Это очень простой протобуф нашего репозитория, который содержит четыре прототипа ABCD и ABCD, которые ссылаются друг на друга Это скрипт оболочки protoc, сгенерированный bazel
БытьБыть
Это пример только что: мы поместили четыре прототипа ABCD в deps, а gRPC, verbose напечатает команду protoc и использует go_proto_library для создания службы, около 24 строк, первая — это утверждение, ссылающееся на нас. common/bazel, посмотрите на предыдущую картинку и почувствуйте.Если мы используем makefile для записи, это соответствует только двум нижним частям.Когда код большой, нет возможности его поддерживать.
2.4 Как использовать Базель
Запишите файл WORKSPACE в корень проекта
Первый — написать файл WORKSPACE, объявив, что корневой каталог — это ваш WORKSPACE, а все правила сборки основаны на абсолютном пути к WORKSPACE.Вам не нужно знать, что такое верхний уровень. выглядеть, если вы знаете корневой каталог.
Давайте рассмотрим пример файла WORKSPACE.
БытьБыть
Делится на три части, первая часть имеет имя, а имя пишется наоборот. Следующим является bazel, который состоит из множества правил.Мы ссылаемся на правила Go здесь, указываем версию, а затем представляем gazelle, инструмент для Go, позволяющий автоматически генерировать файлы BUILD. После вышеуказанной инициализации поместите все зависимости и выполните инициализацию. Весь языковой скрипт похож на Python. У них есть имя, называемое жаворонком, которое является инициализацией этого проекта. Мы требуем, чтобы все зависимости были явно объявлены в WORKSPACE.Преимущество в том, что мы знаем, какой код используется в нем, даже если это косвенная зависимость. вот поддержка Для ветки и фиксации мы не рекомендуем использовать основную ветку внутри, потому что у мастера есть кеш, если есть предыдущий кеш локально, новый мастер не будет подключен к сети. Мы рекомендуем писать коммит напрямую.
Напишите BUILD в каждом каталоге
Напишите файл BUILD в каждом каталоге. BUILD явно указывает, как должен быть построен код. Это имеет два преимущества. Во-первых, мы знаем, какие модули взаимозависимы, через файл BUILD, а другое — через BUILD. Файлы размещаются в разных пакеты в одном каталоге.
Вот пример СТРОЙКИ
БытьБыть
На это объявление видимости пакета, если оно приватное, нельзя ссылаться, доступен только текущий каталог, а затем вводится bazel_essentials с открытым исходным кодом свободного разговора, Фактически, некоторые правила были изменены, и здесь должен быть объявлен go_prefix, потому что это используется в сборке для указания предыдущего префикса. Ниже приведены два объявления: одно — go_binary, другое — go_library, go_binary — создание исполняемого файла, а go_library — выпуск исходного файла go в виде библиотеки.
Ниже приведен более сложный пример
БытьВБыть
Здесь явно указано, какие из них являются тестами, и вы можете поместить туда все файлы тестовых суффиксов, но я не рекомендую этого делать, мы очень надеемся, что, когда ваш репозиторий окажется недостаточно большим, тестовые файлы можно будет подсчитать. Здесь есть тайм-аут, который может установить максимальное время выполнения этого теста.Если он не может завершить выполнение, он напрямую сообщит об ошибке.
Поясним, что означают эти предыдущие правила.
БытьБыть
Тот, что с @ впереди, является внешним, а следующий протокол — это имя цели.
Кратко скажу несколько скриптов сборки
1. build //...
Первая сборка bazel //... представляет все цели в сборке WORKSPACE и будет сканировать все каталоги.
2. build //:demo
Целью отдельной сборки является непосредственно // :demo, где :demo — имя цели
3. run //:demo
Выполнить: демо
4. test //:demo_ test
запустить тест demo_test
Ниже приведены несколько часто используемых команд bazel.
БытьБыть
Первая команда для компиляции linux amd64 на других платформах (таких как macOS), вы можете открыть Experiment_platforms, эта функция относительно новая, или во время внутреннего тестирования.
Запрос bbazel распечатает ваши текущие зависимости.Вы можете перечислить все цели в пакете с помощью запроса bazel.
Последнее: если вы хотите игнорировать определенную цель или каталог, просто добавьте после него знак минус.
БытьБыть
Другая ситуация — какие-то пакеты были скачаны, и если вы хотите запустить таргет отдельно, как показано в первом пункте, то после каждого -(тире) вы сами передаете параметры, что также является распространенной практикой.
Вы можете запустить одну цель (второй элемент), а можете проверить все зависимости (последний элемент). Преимущество этого в том, что вам не нужно полагаться на языки или другие инструменты, вы можете явно рассказать, как код строится через bazel, или вы можете проверить это через запрос bazel и нарисовать картинку.
3.bazel build //:go
Мы официально говорим о сборке bazel//:Go. Ранее мы упоминали «мы должны задать вопрос, как идет сборка Google?» На самом деле используется blazel.
Прежде чем использовать bazel, первым делом нужно удалить вендора: cd
(Но делать это немного агрессивно и нестабильно. Как разработчик, мы знаем, что должны быть стабильными, и вам следует дважды подумать, когда вы используете rm -rf).
Кроме того, поговорим о rules_go, который пока находится в разработке и сейчас поддерживает эти типы.
БытьБыть
Не поддерживается
БытьБыть
3.1 bazel build //:gazelle
Это инструмент для автоматического создания BUILD. С помощью Gazelle пакет сообщества может генерировать все файлы BUILD через Gazelle. Итак, как вы можете создать свой собственный проект, поддерживающий сборку bazel? В три шага:
БытьБыть
Сначала создайте файл WORKSPACE в корне проекта, WORKSPACE объявляет, какие правила и зависимые пакеты требуются. Второй шаг — запуск bazel run //:gazelle для создания файла BUILD, а третий шаг — обновление еще не существующих зависимостей.
DEMO
Изначально это была живая демонстрация, но из-за сети и других факторов я записал видео, мы создали beego Xie Da и сначала клонировали его на Github. Файла сейчас нет, нам нужно в WORKSPACE файл, открыть его напрямую для редактирования, некоторые правила мы можем скопировать с гитхаба rules_go, где четко объясняется, какие правила должны быть, и какая версия. Если у вас есть новая РАБОЧАЯ ОБЛАСТЬ, вы можете увидеть отображаемое имя. Нам нужно поставить в него газель, она может автоматически генерировать все BUILD, а затем инициализируйте его. На самом деле, вы хотите, чтобы все правила были собраны вместе.Преимущество этого в том, что вам не нужно записывать все коды, вам нужно только обновить текущий файл.
Вернемся к трем вопросам, упомянутым ранее.
1. [X] Packages Versioned
bazel решает эту проблему, вы указываете коммит для пакета
2. [X] Verifiable and verified build
Это тоже нормально.При любом изменении или обновлении, даже если оно зависимо, результат каждый раз будет один и тот же.
3. [X] Work outside $GOPATH
Хотя принято помещать код в $GOPATH, время сборки не задается и не зависит от какого-либо GOPATH.
3.2 Выбор минимальной версии
Мы можем сделать это проще, нам нужно только рассмотреть 2 версии, одна из которых заключается в том, нужно ли обновлять наш код до последней версии, а затем напрямую использовать master/HEAD. Во-вторых, я знаю, какой коммит может работать до и после, просто укажите коммит. Потому что, хотя основная версия, описываемая сематической версией, может иметь разрывные изменения, на самом деле ей следуют немногие.
Удаленное кэширование
Используйте Bazel, чтобы загрузить всю библиотеку Go. Удаленное кэширование позволяет избежать ненужных загрузок. Все файлы сборки помогут вам выполнить кэширование. Это очень просто. Используйте хэш md5, переместите текущий каталог Bazel WORKSPACE и сделайте только кластеры.
Удаленное выполнение
Локальная сборка запускается в песочнице, и для запуска открыто несколько потоков. Если вы хотите, чтобы сборка выполнялась быстрее, вы можете использовать удаленное выполнение.
Bazel также может строить другие. Например, вы также можете создать докер, который мы всегда хотели попробовать, и создать Android, iOS и веб. Когда все нарезано на bazel, кросс-языковая и кросс-платформенная сборка не проблема, нам нужно только знать, что bazel строит.
3.3 Проблемы, возникающие при использовании bazel в Liulishuo
Во-первых, вам нужно вытащить последний код из master/head
Google находится в том же репо, поэтому этой проблемы не существует. Чтобы решить эту проблему, доктор написал правило в Skylark.
БытьБыть
Этот код имеет открытый исходный код и должен использоваться вместе с переменной среды BAZEL_RUNID.Если значение BAZEL_RUNID изменится, кэш будет обновлен.
БытьБыть
Как правило, для BAZEL_RUNID будет установлено случайное значение или текущее время, так что каждый раз, когда вы запускаете CI, извлекается последний код.
БытьБыть
Во-вторых, Bazel медленно запускается
Мы обнаружили, что идея с bazel хороша, но если она используется впервые или просто перенесена из других инструментов, она медленно заводится, и мы решаем ее через Codelab.
БытьБыть
В-третьих, проблема сторонних зависимостей
Недавно я столкнулся с проблемой
БытьБыть
Когда qiniu_x добавит go_repository, он сообщит об ошибке и не сможет построить, в чем причина этого?
БытьБыть
Сообщение об ошибке заключается в том, что требуется `com_qiniupkg_x`. На самом деле код находится под @com github qiniu_x//. Зачем нужен пакет?
БытьБыть
Оказалось, что при qiniu_x config.v7 использовалось другое имя пакета, с go build проблем нет, т.к. путь импорта доступен, но плохо то, что этот код бывает в том же репо, а нужен чтобы перейти к другому Путь импорта log.v7, решение состоит в том, чтобы повторно использовать репо. Это на самом деле qiniu_x Github. Код такой же, как и он, и он копируется напрямую. Теперь вы можете сделать это, только если вы столкнулись сторонние проблемы.