Практика песочницы ByteDance с микроинтерфейсом

Микросервисы внешний интерфейс
Практика песочницы ByteDance с микроинтерфейсом

Эта статья начинается с задачи изоляции времени выполнения проекта микроинтерфейса ByteDance и подробно объясняет техническую реализацию песочницы (далее именуемой песочницей), а также некоторые проблемы, которые возникли в фактическом процессе реализации, упомянутом выше. Я полностью поделюсь некоторыми ключевыми деталями и многолетним опытом майнинга с читателями, надеясь оказать вам некоторую помощь и вдохновение. Что касается общего мышления микро-интерфейса, вы можете обратиться к:«Отработка и применение интерфейсных микросервисов в ByteDance», я надеюсь, что у читателей есть некоторое понимание, прежде чем читать эту статью.

1. Что должна делать песочница

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

древний iframe

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

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

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

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

древняя трудность

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

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

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

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

2. Как должна выглядеть песочница

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

Виртуализация, контейнеризация, Docker

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

Если говорить просто о концепции микросервисов, то давно была эта концепция, и была теория сервис-ориентированного программирования. Однако разработки очень мало, обналичить пока сложно, а разрабатывать виртуальные машины очень хлопотно. А также опыт разработки, образы, которые я упаковал — должны ли они включать всю ОС для последовательной доставки? Это плохо влияет на опыт разработки.

До того, как Docker получил широкое распространение, использование микросервисов на стороне сервера в основном основывалось на виртуальных машинах. Напротив, использование очень сложно, а стоимость обслуживания увеличивается. Не говоря уже о хлопотной виртуальной машине, это всем понятно. Ресурсы, которые он потребляет, не того порядка, что технология контейнеризации. Также есть пример, когда хочется сделать снимок и даже съесть диск. Более того, добиться координации и эффективного распределения ресурсов между несколькими службами чрезвычайно сложно.

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

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

3. Что должна делать песочница?

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

3.1 Однопроцессный и многопроцессный

Ссылаться наОдно ядро, процесс операционной системы, который имитирует стратегию переключения процессов.Наша песочница, по сути, позволяет браузеру запускать несколько «независимых» приложений, поэтому имитация и окончательная конвергенция операционной системы должны быть неизбежны. В этом отношении JavaScript использует уникальную функцию выполнения по сравнению с другими языками: он сам является однопоточным. То, что я делаю, по сути, находится в потоке. Это эквивалентно тому, что наша операционная система с самого начала ограничила одно ядро ​​только одним выходом.

Так как же операционная система реализует многопроцессорный параллелизм?Можно просто управлять одним процессом с помощью таких правил, как корневая маршрутизация, и одновременно активируется только один процесс.contextПросто переключение; многопроцессный параллелизм — это просто способ воспользоваться преимуществами функций JavaScript, и я могу инкапсулировать каждый отдельный цикл обработки событий. НапримерsetTimeout, различные обратные вызовы событийhandler, мы на самом делеfunctionСначала переключитесь снаружиcontext, а затем выполните то, что вы изначально хотели связатьfunction. Это потокобезопасно. Подводя итог, это будут следующие два:

  1. Он инкапсулирован с коммутацией маршрутизации для имитации одного ядра и одного процесса.
  2. Используйте общий пакет цикла событий для имитации одноядерного многопроцессорного процесса.

3.2 Переключение контекста

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

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

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

Это показывает, что удаление ключа должно быть пройдено дважды,Для того, чтобы гарантировать, что каждый объект проходится один раз. В этом разделе следует подчеркнуть один момент: когда вы получаете старые и новые объекты и сравниваете их, проходите ключи одного из них и находите их в другом, недостаточно просто сделать это, потому что есть вещи, которые могут быть удалены. . Его удаление приводит к исчезновению ключа, и, естественно, его нельзя пройти. Чтобы отразить это удаление, вы должны пройти дважды, как старые, так и новые объекты, чтобы узнать, у кого больше, а у кого меньше по сравнению. Особенно, когда все сравнивают «бездействие» с недавно открытыми песочницами, эту деталь легко забыть.

Хорошая ли производительность переключения контекста?Давайте сначала поговорим о космической производительности этого снимка. Если у вас есть N песочниц, сколько комбинаций переключателей вам нужно, нужно ли хранить полный текст контекста или различия контекста между любыми двумя песочницами? Вообще-то нет. Нам нужно только записать разницу, изменение контекста и только разницу в состоянии «ожидания». Например, A, B, C, D, E, F, G. Нам не нужно записывать переключение типа A→B A→C, а виртуальное состояние бездействия: O, оба A→O, B→O, сохраняется только разница между ними и O. Количество переменных, которые необходимо записывать и сравнивать, изменилось с умножения количества подприложений на добавление. Напишите цикл для быстрого сравнения изменений.

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

4. Решение, принятое песочницей ByteDance

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

4.1 CSS-песочница

Начнем с песочницы CSS.этот кусокwebComponentСделано много разработок. Не могу не сказать, что в веб-стандартах была одна вещь, которая в свое время меня очень привлекала и интересовала:scoped css- просто добавьAttributeЕго можно комбинировать с деревом DOM, чтобы ограничить возможности CSS. Позже этот стандарт был отменен. за то, что уступил дорогуShadowDOMсистема.

Я не совсем понимаю это: потому чтоscoped CSSЭто внешние правила, которые могут войти, внутренние правила не могут выйти, ноshadowDOMявляется полным расколом. Эта огромная разница делает их инженерное значение очень разным. Позже мы поговорим оcss module, который, по-видимому, ведет себя так же, как и стиль с областью действия, иShadowРазные.

Модуль CSS и CSS в JS записывают или компилируют стили в скрипты, и в то же время добавляют анонс к самому внешнему слою DOM, сгенерированному скриптом.attribute; а затем примените этот «атрибут» ко всем контролируемым правилам CSS. Недостатком является то, что он относительно громоздкий и требует полного контроля над всем созданием DOM. В интерфейсных фреймворках Angular делает это естественным образом.

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

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

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

Если речь идет о упомянутом выше случае многопроцессорности (то есть под ним понимается параллельная система с N песочницами, работающими вместе одновременно). Этот CSS, безусловно, не может делать то же самое, что однопоточная среда выполнения JavaScript, поэтому вы должны использовать модульный CSS. Это несложно сделать, и доступно множество библиотек с открытым исходным кодом. Даже если все ссылаются на разные версии одной и той же библиотеки компонентов, взломали друг друга и случайно создали каких-то «мотыльков», не пугайтесь, потому что все они скомпилированы и область действия ограничена.

Будьте осторожны при использовании пакета styled-component в NPM,Они будут оценивать среду на основе переменных среды, а затем включать режим под названием «быстрый» для рабочей среды, который не будет использоватьinnerTextнапишите правила стиля, вместо этого используйтеaddRulesВесь этот набор API. Но стандарт, похоже, не определяет четко поведение и поведение этого тега при его удалении из DOM-дерева документа, возможно, потому, что это очевидно.rulesтакже должны быть удалены вместе. Но когда мы снова включаем его, двусмысленность исчезает. Фактическое поведение браузера заключается в удалении и повторной вставке тега.rulesушел. Здесь нам явно нужна дополнительная обработка.

4.2 Песочница глобальных переменных

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

Это основное направление реализации микроинтерфейса. Я лично так думаю. Видно, что все не очень убеждены. «Кто не знает, что нельзя писать глобальные переменные? Таких ненадежных людей не будет». На самом деле, если вы попробуете, то обнаружите, что их много. Например, в Toutiao используется подключаемая библиотека для обрезки изображений. Это очень полный, достойный и классический пакет, поддерживающийReactиJQuery. Он пишет одноэлементную реализацию для файла global. И в процессе разработки и отладки наши команды разных направлений бизнеса действительно использовали разные версии этого пакета.

Конечно, это не важно и не вызывает проблемы. Более мрачный пример:reGeneratorRuntime. он скомпилированasyncСинтаксис, Бабель под конфиг будетdeleteэтот объект. Непонятно, в чем заключается принцип, и нет необходимости говорить больше, но совершенно точно, что он будет конфликтовать и вызывать проблемы. Однажды наша арбузная командаpolyfillЭтот тип конфликта возникает между правилами и другим направлением бизнеса. Итак, вам нужно сравнить удалить, восстановить, переключиться обратно на арбуз и удалить.

Identifierэто еще одна забота.ты полностью осознаешьIdentifierчто это? Идентификатор — это имя переменной, которое работает в рамках области, в том числеfunction,let,class,const. ТолькоvarВещи, которые выходят, особенные и не будут заниматьIdentifier, вышеуказанные сеансы нельзя использовать повторно после того, как они заняты.

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

в глобальном масштабеvar a, на самом деле генерирует вне диапазонаIdentifierи дополнительно вglobalСоздайте ключ с тем же именем, указывающим на тот же адрес. Это дополнительная операция для оператора var. Это позволяет нам пройтиwindowспособ избавиться от глобальных переменных.

но если ты придешьconstНет пути, нет пути.classТо же самое. Нет возможности перечислить или удалить. Максимальное повторное использованиеclassОбъявление ключевого слова перезаписывается.

В любом случае, не думайте слишком много об этом.new functionУпаковка почти необходима. Вы также можете пройти какsetTimeoutЭтот входной параметр используется для управления асинхронной реализацией «многопроцессного» параллелизма.

Еще одинlocationне двигайся,обновит страницу. Занести в черный список.

Еще одна забавная вещь:functionиvarто же, что дополнительныйwindowДобавьте ключ выше. этоpropertyизconfigurableдаfalse- То есть его нельзя удалить. Но его можно назначить.

так что если вы зажигаетеvar a,можетdelete window.a; переписатьaэтоundefined. написатьfunction a, а затем напишитеdelete aявляется недействительным. но если вы напишетеfunction a, а затем напишитеvar a = 1. Какой эффект, вы даетеwindowК нему привязывается номер, который нельзя удалить, и он продолжается.function aНеизгладимое свойство иvar aзначение .

Больше удовольствияclass,тыclass B {},Сноваconsole log window.B, как это,undefind. Напиши сноваB = 1; потом посмотриwindow.BКак насчет этого? Продолжатьundefined,B = 1нет эффекта.

указывают на то, что потенциальный механизмclassКогда ключевое слово выполнено, дайтеglobalпривязана к мужчине по имени Б.property, но не является перечислимым и доступнымproperty,propertyимеютwritable true, enumerable: true, configurable: trueскрытые свойства вне .

4.3 Другое

Есть много объектов, которые нуждаются в технологической безопасности,Напримерcookie, но это не особо важно, просто согласитесь использовать одинpathВот и все--cookieКроме настройкиdomainтакже можно установитьpath. Просто большинство людей не устанавливают его (то есть устанавливают его как корневой каталог)/»).

localStorageВы также можете защитить его.Зависит от вашего бизнеса. потому что они принадлежатwindowsглобальные переменные, поэтому реализуйте завернутыеclassИнтегрируйте и моделируйтеlocalStorageОригинальное поведение в порядке. Сделайте так, чтобы все методы сначала добавляли ключprefix, а затем выполнить методsuper. этоprefixТекущая песочница может быть просто жестко запрограммированаuuidХорошо, потому чтоwindow.localStorageСама глобальная переменная находится в пределах защиты песочницы.

5. Другие функции песочницы

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

5.1 Система кэширования скрытых точек

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

5.2 console

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

В частности, ввести для журналаcallstackиспользуетсяnew ErrorПуть. Это можно сделать с помощьюerror.stackПолучите стек вызовов. Это значение представляет собой непосредственно строку, разделенную символом новой строки в формате Markdown, может быть записано в виде ссылки, а также может соответствовать исходному коду окна отладки.

Точно так же, когда встречается реальное исключение, с ним также следует обращаться таким же образом. отcatchк исключению, сноваthrowПеред выходом можно датьerror.stackЗначения все взломаны. Удалите ненужный стек — например, слой вашего пакетаnew Function, удалите эту строку. Содержание подсказки также может быть изменено.

5.3 sourceMapping

sourceMapping был изобретен закрытием Google и теперь является стандартом ES6. Принцип заключается в сопоставлении позиций символов с позициями символов. затем вnew FunctionМожно ли использовать в песочнице? Конечно.

Давай сначала поговоримnew FunctionПредставление. В chrome это новая анонимная среда в отладке:anonymous, позиции символьной строки и столбца отсчитываются от первой строки в начале функциональной строки. Если вы поместите скомпилированный и сгенерированный пакет sourceMap вnew functionЭта позиция полностью соответствует, никакого дополнительного взлома не требуется.

Это также потому, что хром может нормально его распознаватьnew Functionв конце строки параметровsourcemappingUrl=заметки. соответствуетcallstackВсе правильно. Во многих случаях мы обнаруживаем, что деловая сторона не будет беспокоиться об этом и будет думать, что я скачал его напрямую..jsСтек вызовов и sourceMap, которые упакованы, не беспокойтесь об отладке. На самом деле нет проблем. Оба в порядке.

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

Эпилог

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

Как и многие передовые и недавно разработанные концепции, микро-фронтенды все еще находятся в процессе быстрой эволюции и проверки, наши конкретные практики также быстро меняются, мы постоянно находим слабые места и исправляем их, а также стремимся развивать больше возможный. В этой борьбе от несовершенства к совершенству для меня большая честь поделиться своими достижениями с читателями. И после обмена, мы будем более благодарны, если мы сможем получить советы, обсуждения и предложения, и очень приветствуются. Мы также приветствуем больше людей, которые хотят присоединиться к нам, пожалуйста, отправьте нам электронное письмо, чтобы связаться с нами.aishiguang@bytedance.comили следуйтеВходящая ссылка.

Добро пожаловать в "Техническую команду ByteDance"