GraphQL — это язык запросов данных, предложенный Facebook.Основными функциями являются агрегация данных и запрос по требованию.В настоящее время он широко используется между интерфейсом и сервером для решения проблемы гибкого использования данных клиентами. В этой статье представлена еще одна практика использования GraphQL: мы погружаем GraphQL на внутренний уровень BFF и объединяем технологию метаданных для реализации запросов по требованию, выполнения данных и логики обработки. Это не только решает проблему гибкого использования данных на внутреннем уровне BFF, но и позволяет напрямую повторно использовать логику полевой обработки, что значительно повышает эффективность исследований и разработок. Практические решения, представленные в этой статье, были реализованы в некоторых бизнес-сценариях Meituan и дали хорошие результаты.Я надеюсь, что этот опыт может быть полезен для всех.
1 Происхождение лучшего друга
Термин BFF взят из сообщения в блоге Сэма Ньюмана.Pattern:Backends For Frontends«Ссылаясь на службу на переднем конце задней части. BFF - это решить любые проблемы? Согласно первоначальному описанию, с подъемом мобильного интернета, оригинальная адаптация функций веб-сервера рабочего стола при предоставлении надежды использовать мобильное приложение, но есть проблема в этом процессе:
- Мобильное приложение и десктопная сеть имеют различия в пользовательском интерфейсе.
- Мобильное приложение включает в себя разные терминалы, не только iOS, но и Android, между пользовательскими интерфейсами этих разных терминалов есть различия.
- Уже существует большая связь между исходной функциональностью бэкэнда и настольным веб-интерфейсом.
Из-за различий в конце функции сервера должны быть адаптированы и адаптированы в соответствии с различиями в конце, в то время как бизнес-функция самого сервера относительно едина, что создает противоречие - между единой бизнес-функцией сервер и различные требования конца противоречия. Итак, как решить эту проблему? Это также "Одноцелевые пограничные службы для пользовательских интерфейсов и внешних сторон", описанные в подзаголовке статьи. Введен BFF, и BFF используется для адаптации к многоконечным различиям. Эта модель также широко используется в отрасли. .
В реальной деловой практике есть много причин для этой сквозной разницы, включая технические и бизнес-причины. Например, является ли клиент пользователя Android или iOS, большой это экран или маленький экран и какая у него версия. Другой пример: к какой отрасли относится бизнес, какова форма продукта, в какой сценарий помещена функция, кто является целевой группой пользователей и так далее. Эти факторы приведут к различию функциональной логики, ориентированной на конец.
В этом вопросе бизнес отображения товаров, отвечающий за команду автора, имеет определенное мнение.Тот же бизнес товаров, логика функции отображения на стороне C глубоко зависит от типа товара, отрасли, формы транзакции, места доставки. , групповая ориентация и др. Факторы влияния. В то же время свойство частых итераций потребительско-ориентированных функций усилило и углубило это противоречие, заставив его перерасти в противоречие между одиночной стабильностью сервера и гибкостью различий на конце, что также является товарным отображением. (товарный дисплей BFF ) Неизбежность существования бизнес-системы. В этой статье в основном представлены некоторые проблемы и решения в контексте демонстрации товаров Meituan в магазине.
2 Основные противоречия в контексте BFF
Введение слоя BFF должно решить противоречие между единственной стабильностью сервера и различными и гибкими требованиями терминала Это противоречие не исчезло, а было перенесено. От исходного противоречия между бэкендом и фронтендом к противоречию между БФФ и фронтендом. Основная работа авторского коллектива заключается в борьбе с этим противоречием. Ниже в качестве примера используется конкретный бизнес-сценарий в сочетании с текущими бизнес-характеристиками, чтобы проиллюстрировать конкретные проблемы, с которыми мы сталкиваемся в производственном режиме BFF. На следующем рисунке показаны модули отображения полок для групповых покупок в двух разных отраслях. Мы рассматриваем эти два модуля как сценарии отображения двух продуктов. Это два набора независимо определенной логики продуктов, и они будут повторяться отдельно.
На ранней стадии развития бизнеса таких сценариев не так много. Слойная система BFF построена в «каминном стиле», а функции быстро разрабатываются и запускаются под нужды бизнеса, в таких условиях это противоречие не очевидно. С развитием бизнеса и развитием промышленности сформировалось много таких функций отображения товаров, и противоречие постепенно усиливалось, главным образом, в следующих двух аспектах:
- Эффективность бизнес-поддержки. С ростом числа сценариев отображения товаров и стремительной тенденцией API-интерфейсов эффективность бизнес-поддержки и людские ресурсы имеют линейную зависимость, а системные возможности не могут поддерживать крупномасштабное расширение бизнес-сценариев.
- Высокая сложность системы: основные функции продолжают повторяться, а внутренняя логика полна
if…else…
, код написан процедурно, сложность системы высока, ее сложно модифицировать и поддерживать.
Тогда вопрос в том, как его создать? Это в сочетании с «Stovepipe» системами строительства фона и товарной витрины сцены, обращенной к бизнесу, а также для понимания характеристик системы.
Особенности a: множество высоких внешних зависимостей, есть разница между количеством сцен, которые нужно взять, требованиями к пользовательскому опыту.
На иллюстрации показаны два модуля полки для групповых закупок в разных отраслях.Для такого, казалось бы, небольшого модуля, серверной части необходимо вызвать более 20 нижестоящих сервисов на уровне BFF, чтобы получить все данные.Это один из них. В приведенных выше двух различных сценариях существуют различия в требуемых наборах источников данных, и такие различия являются общими.Это второй вариант.Например, определенный источник данных, необходимый для полки для покупок группы педикюра, не требуется для группы красоты. Полка для покупок Покупка группы красоты Определенный источник данных, требуемый полкой, но не требуемый полкой покупки группы педикюра. Хотя есть много нижестоящих сервисов, также необходимо обеспечить взаимодействие с пользователем C-стороны, которая является третьей.
Эти характеристики доставили много трудностей технологии: 1) Размер агрегации трудно контролировать, а функция агрегации строится по разным сценариям? Или единая конструкция? Если конструкция разбита на сценарии, то должна возникнуть проблема многократного написания одной и той же логики агрегации в разных сценариях. Если конструкция унифицирована, то в большом и всеобъемлющем агрегировании данных неизбежно будут некорректные вызовы. 2)Проблема контроля сложности логики агрегации.В случае такого количества источников данных необходимо продумать не только как написать бизнес логику,но и расстановку асинхронных вызовов.Если сложность кода не может быть ну контролируется, последующая агрегация изменений и модификаций будет проблемой.
Особенность 2: Существует множество логик отображения, существуют различия между сценами и общая логическая связь личности.
Мы можем четко определить, что логика сцены определенного типа является общей, например, сцена отображения, связанная с групповым порядком. Интуитивно видно, что он в основном отображает информацию одного измерения группы, но это только видимость. На самом деле, в процессе генерации модулей есть много различий, например следующие два отличия:
- Различия в логике объединения полей: например, заголовки групповых покупок двух полок групповых покупок на приведенном выше рисунке являются примерами. Заголовок тот же. Правила отображения на полке групповых покупок Liren следующие:[Тип] + название групповой покупкиИ правила отображения на долях Pedicure Group покупают полки:название групповой покупки.
- Различия в логике сортировки и фильтрации: например, в одном групповом списке сценарий А сортируется по продажам в обратном порядке, а сценарий Б — по цене.Логика сортировки в разных сценариях различается.
и тому подобноеЛогика отображенияЕсть еще много отличий. Подобные сценарии на самом деле имеют много различий во внутренних различиях, как справиться с этой разницей, является проблемой.Следующий является наиболее распространенным способом написания, и конкретные поля условий используются для определения логического маршрута, как показано ниже.
if(category == "丽人") {
title = "[" + category + "]" + productTitle;
} else if (category == "足疗") {
title = productTitle;
}
Это решение не является проблематичным с точки зрения функциональной реализации, а также может быть мультиплексировано. Однако на самом деле, в случае большого количества сцен, будет много разной логики суждения, наложенной вместе, и функция всегда будет в состоянии представить, система будет становиться все более сложной и все более сложной. заключается в изменении и обслуживании.
Суммировать: В слое BFF есть различия в сценах отображения разных продуктов. На ранней стадии развития бизнеса система поддерживает быстрый бизнес методом проб и ошибок за счет самостоятельного построения, в этом случае проблемы, вызванные различиями в бизнесе, не очевидны. С непрерывным развитием бизнеса необходимо создавать и использовать все больше и больше сценариев, демонстрируя тенденцию к масштабированию. В это время бизнес выдвинул более высокие требования к технической эффективности.На фоне множества сценариев и различий между сценариями, как обеспечить эффективность расширения сценария и контролировать сложность системы, является основной проблемой, с которой сталкиваются наши бизнес-сценарии..
3 Анализ режима приложения BFF
В настоящее время в отрасли существует в основном два режима для таких решений: один — внутренний режим BFF, а другой — внешний режим BFF.
3.1 внутренний режим BFF
Режим Back-end BFF означает, что BFF отвечает за одноклассников back-end. В настоящее время наиболее распространенной практикой этого режима является решение BFF back-end на основе GraphQL. В частности, back-end инкапсулирует отображение поля в сервис отображения и предоставляет его после оркестровки GraphQL для внешнего использования. Как показано ниже:
Самая большая особенность и преимущество этого режима заключается в том, что, когда поле отображения уже существует, серверной части не нужно заботиться о различных требованиях внешнего интерфейса, а возможность запроса по запросу поддерживается GraphQL. Эта функция вполне может справиться с проблемой различий полей отображения в разных сценариях.Фронтенд может напрямую запрашивать данные по запросу на основе GraphQL, а бэкэнд не нужно менять. В то же время, благодаря возможностям оркестрации и агрегации запросов GraphQL, серверная часть может разложить логику на различные сервисы отображения, поэтому сложность уровня BFF может быть в определенной степени решена.
Однако, исходя из этой модели, все еще существует несколько проблем: проблема детализации службы отображения, проблема разделения графа данных и проблема диффузии поля.На следующем рисунке показан конкретный случай, основанный на текущей модели:
1) Продемонстрируйте проблемы проектирования сервисной детализации
Это решение требует, чтобы логика представления и логика выборки были инкапсулированы в модуль для формирования службы представления, как показано на рисунке выше. На самом деле связь «многие ко многим» между логикой отображения и логикой набора чисел иллюстрируется приведенным выше примером:
задний план: есть две службы отображения, которые соответственно инкапсулируют возможности запроса названий продуктов и этикеток продуктов.место действия: В это время ПМ поднял спрос, рассчитывая, что название товара в определенной сцене будет отображаться в виде "[тип] + название товара". В это время сращивание названия товара зависит от данные о типе, и данные о типе в это время отображаются в сервисе отображения этикетки продукта.проблема: Служба отображения названия продукта вызывает данные о типе сама по себе или объединяет две службы отображения вместе?
Проблема, описанная выше, заключается в контроле степени детализации службы отображения Мы можем сомневаться, что вышеприведенный пример связан с тем, что степень детализации службы отображения слишком мала? Затем посмотрите на это в обратном порядке: если вы объедините два сервиса вместе, неизбежно возникнет избыточность. В этом сложность демонстрации сервис-дизайна,Основная причина заключается в том, что логика отображения и логика выборки чисел находятся во взаимосвязи «многие ко многим», но результаты предназначены для объединения..
2) выдает разбиение данных Рис.
Данные нескольких сервисов отображения объединяются в график (схема GraphQL) через GraphQL для формирования представления данных. Когда данные необходимы, пока данные находятся на графике, их можно запросить по требованию на основе запроса. Итак, вопрос в том, как должна быть организована эта диаграмма? Это одно изображение или несколько изображений? Если граф слишком велик, это неизбежно приведет к сложным проблемам обслуживания взаимосвязей данных, а если граф слишком мал, ценность самого решения будет снижена.
3) Показать внутреннюю сложность сервиса + проблема распространения модели
Как упоминалось выше, при отображении названия продукта используются разные логики сращивания, которые особенно часто встречаются в сценариях отображения продуктов. Например, цена одинакова, отрасль А показывает цену после скидки, отрасль Б показывает цену до скидки, одинаковое положение этикетки, отрасль С показывает срок службы, а отрасль Г показывает характеристики товара. , и т.д. Так вот вопрос, как устроена модель дисплея? Взяв в качестве примера поле заголовка, нужно поместитьtitle
Поля в порядке, или поставьте их отдельноtitle
иtitleWithCategory
? Если это первое, то служба должна существовать внутриif…else…
Эта логика, используемая для различенияtitle
сплайсинг, что также приводит к сложностям в рамках службы представления. При наличии нескольких полей вполне возможно, что число полей модели, отображающих службу, также будет увеличиваться.
Суммировать: внутренний режим BFF может в определенной степени решить сложность внутренней логики, предоставляя при этом механизм мультиплексирования для отображения полей. Но все еще остаются нерешенные вопросы, такие как детальный дизайн службы презентаций, разделение графа данных, а также сложность и увеличение количества полей в службе презентаций. В настоящее время к представителям этой модельной практики относятся Facebook, Airbnb, eBay, iQiyi, Ctrip, Qunar и так далее.
3.2 Интерфейсный режим BFF
Интерфейсный режим BFF специально представлен в разделе «И автономия» статьи Сэма Ньюмана, что означает, что сам BFF является обязанностью самой фронтенд-команды, как показано на следующей диаграмме:
Концепция этой модели заключается в том, что потребности команды могут быть доставлены, нет необходимости разбивать ее на две команды, а сами две команды несут большие затраты на общение и совместную работу. По существу, это также переосмысление «противоречия врага» в «противоречие между людьми». Фронтенд полностью берет на себя разработку BFF и реализует самодостаточность запросов данных, что значительно снижает совместные затраты на фронт и бэк. Но эта модель не затрагивает некоторые из наших основных вопросов, например, как бороться со сложностью, как бороться с дифференциацией, как отображать то, как устроены модели. Кроме того, эта модель также имеет некоторые предпосылки и недостатки, такие как более полная интерфейсная инфраструктура; внешние интерфейсы необходимо заботиться о рендеринге, но также необходимо понимать бизнес-логику.
Суммировать: интерфейсный режим BFF использует внешний интерфейс для независимого запроса и использования данных, тем самым снижая стоимость совместной работы между группами и повышая эффективность исследований и разработок BFF. Нынешний практический представитель этой модели — Alibaba.
4 Проектирование архитектуры агрегации информации на основе GraphQL и метаданных
4.1 Общая идея
Путем анализа двух режимов внутреннего BFF и внешнего BFF мы, наконец, выбираем внутреннюю модель BFF.Внешняя схема BFF оказывает большое влияние на текущую модель НИОКР, не только требует много интерфейсные ресурсы, но также необходимо создать полную интерфейсную инфраструктуру. Стоимость реализации программы относительно высока.
Хотя в упомянутом выше бэкэнд-режиме GraphQL BFF есть некоторые проблемы, в целом он имеет большое справочное значение, например, идея отображения повторного использования полей, идея запроса данных по запросу и скоро. В сцене отображения продукта,80% работы сосредоточено на части агрегации и интеграции данныхИ эта часть имеет высокую ценность повторного использования, поэтому информационные запросы и агрегация являются основными противоречиями, с которыми мы сталкиваемся. Поэтому наши идеи таковы:Основываясь на усовершенствовании внутренней схемы BFF GraphQL+, логика выборки и логика отображения могут быть ускоренными, компонуемыми и многоразовыми., общая структура показана на следующей диаграмме:
Как видно из приведенного выше рисунка, самое большое отличие от традиционного решения GraphQL BFF заключается в том, что мы делегируем GraphQL части агрегации данных, Поскольку данные поступают из товарного поля, а поле относительно стабильно, масштаб графика данных управляема и относительно стабильна. Кроме того, основной дизайн общей архитектуры также включает следующие три аспекта: 1) разделение извлечения и отображения данных, 2) нормализация модели запроса, 3) архитектура, управляемая метаданными.
Мы решаем проблему детализации службы отображения за счет разделения извлечения и отображения, и в то же время делаем логику отображения и логику выборки упрощенной и многократно используемой; за счет нормализованного дизайна модели запроса для решения проблемы увеличения поля отображения; за счет архитектура, управляемая метаданными, для достижения возможности визуализации, автоматизации оркестровки и выполнения бизнес-компонентов позволяет студентам, изучающим бизнес-развитие, сосредоточиться на самой бизнес-логике. Ниже мы представим эти три части одну за другой.
4.2 Основной дизайн
4.2.1 Разделение выборки и отображения
Как упоминалось выше, в сценарии товарного дисплея логика отображения и логика поиска чисел находятся в отношениях «многие ко многим», а традиционное практическое решение BFF на основе GraphQL инкапсулирует их вместе, что затрудняет проектирование. степень детализации основной причины службы отображения. Подумайте, на чем сосредоточена логика выборки и логика отображения? Логика выборки сосредоточена на том, как запрашивать и агрегировать данные, а логика отображения — на том, как обрабатывать и генерировать необходимые поля отображения.У них разные задачи, и вместе они увеличивают сложность службы отображения. Поэтому наша идея состоит в том, чтобы разделить логику выборки и логику отображения и по отдельности инкапсулировать их в логические блоки, которые называются блоком выборки и блоком отображения соответственно. После того, как выборка и отображение разделены, GraphQL также погружается для реализации агрегации данных по запросу, как показано на следующем рисунке:
Итак, какова степень детализации инкапсуляции выборки и отображения логики? Он не может быть слишком маленьким или слишком большим.При проектировании детализации мы исходим из двух основных соображений: 1)мультиплекс, логика отображения и логика поиска чисел являются активами, которые можно повторно использовать в сцене отображения товаров. Мы надеемся, что их можно будет ускорить и использовать отдельно по запросу; 2)Простой, сделайте его простым, чтобы его было легко модифицировать и поддерживать. На основании этих двух соображений размер частиц определяется следующим образом:
- Количество единиц: Попробуйте инкапсулировать только один внешний источник данных, и в то же время он отвечает за упрощение модели, возвращаемой внешним источником данных.Эта часть сгенерированной модели называется моделью выборки.
- дисплей: Попробуйте инкапсулировать логику обработки только одного поля дисплея.
Преимущество разделения в том, что оно простое и может использоваться в комбинации, так как же добиться комбинированного использования? Наша идея состоит в том, чтобы описать отношения между ними через метаданные, и на основе метаданных для связывания и запуска используется унифицированная среда выполнения.Конкретный дизайн будет представлен ниже. Благодаря разделению выборки и отображения, ассоциации метаданных и комбинированному вызову во время выполнения логический блок может быть простым и в то же время удовлетворять требованиям повторного использования, что также решает проблемы, существующие в традиционных решениях. .Детализация сервисов отображения.
4.2.2 Нормализация модели запроса
Какой вид интерфейса отображается результатом обработки блока отображения? Далее мы введем проблему дизайна интерфейса запросов.
1) Сложности в дизайне интерфейса запроса
Существует два шаблона проектирования для распространенных интерфейсов запросов:
- Строго типизированный шаблон: Строго типизированный режим означает, что интерфейс запроса возвращает объекты POJO, и каждый результат запроса соответствует определенному полю в POJO с определенным бизнес-значением.
- Слабо типизированный шаблон: Слабо типизированная схема относится к результатам запроса, возвращаемым в схеме K-V или JSON без явных статических полей.
Эти две модели широко используются в промышленности и имеют явные преимущества и недостатки. Сильный режим ввода для удобства разработчиков, но бизнес постоянно повторяется, в то же время система будет продолжать осаждать богатые единицы отображения, в этом случае интерфейс DTO вернулся в поле, будет все больше и больше, каждый раз будет поддерживаться новый функции, изменение интерфейса должно сопровождаться обновлением версии JAR модели запроса. Обновления JAR связаны с поставщиками данных и потреблением данных с двух сторон, эффективность очевидна. Кроме того, вполне возможно, что модель непрерывного итеративного запроса, в конечном итоге, будет включать сотни полей, которые трудно поддерживать.
Режим слабого типа как раз может компенсировать этот недостаток, но режим слабого типа очень недружественный к разработчикам.Какие результаты запросов в интерфейсной модели запросов совершенно непонятно разработчику в процессе разработки, но программисту естественно нравится понимать логику через код, а не конфигурацию и документацию. На самом деле у этих двух шаблонов проектирования интерфейсов есть общая проблема — отсутствие абстракции.В следующих двух разделах мы представим абстрактные идеи и поддержку возможностей фреймворка при проектировании модели запроса, возвращаемой интерфейсом.
2) Дизайн нормализации модели запроса
Возвращаясь к сценарию отображения продукта, существует множество различных реализаций поля отображения, например, две разные реализации названия продукта: 1) название продукта; 2) [категория] + название продукта. Отношение между названием продукта и этими двумя логиками отображения, по существу, является абстрактно-конкретным отношением. Идентифицируя этот ключевой момент, идея ясна, наша идея состоит в том, чтобы абстрагировать модель запроса. Модель запроса представляет собой все абстрактные поля отображения, и одно поле отображения соответствует нескольким единицам отображения, как показано на следующем рисунке:
На уровне реализации взаимосвязь между полями отображения и единицами отображения также описывается на основе метаданных.Исходя из приведенных выше дизайнерских идей, распространение моделей можно в определенной степени замедлить, но нельзя избежать расширения. Например, в дополнение к стандартным атрибутам, которые есть у каждого продукта, таким как цена, запасы и продажи, различные типы продуктов обычно имеют атрибуты, уникальные для этого продукта. Например, для темы секретной комнаты есть такой атрибут описания, как «написание нескольких человек». Наше решение состоит в том, чтобы ввести расширенные атрибуты, которые специально содержат такие нестандартные поля. Модель запроса устанавливается стандартными полями + расширенными атрибутами, которые могут лучше решить проблему.Полевая диффузияПроблема.
4.2.3 Архитектура, управляемая метаданными
До сих пор мы определили, как разлагатьсяблок бизнес-логикии как спроектироватьмодель запросаи упоминает использование метаданных для описания отношений между ними. Бизнес-логика и модели, реализованные на основе приведенных выше определений, имеют высокую ценность повторного использования и могут быть депонированы в качестве бизнес-активов. Итак, зачем использовать метаданные для описания отношений между бизнес-функциями и моделями?
Мы вводим описание метаданных для двух основных целей: 1) автоматическая организация логики кода, описывающая взаимосвязь между бизнес-логикой через метаданные, и среда выполнения может автоматически реализовывать взаимосвязь между логикой на основе метаданных, тем самым устраняя большое количество 2) визуализация бизнес-функции, сами метаданные описывают функции, предоставляемые бизнес-логикой, как показано в следующих двух примерах:
Начиная с моно-, пример: 30. Поля отображения цены монорутки, например: 100.
Эти метаданные передаются в систему и могут использоваться для отображения функций, предоставляемых текущей системой. Компоненты и их ассоциации описываются метаданными, а бизнес-компоненты автоматически вызываются и выполняются путем анализа метаданных через фреймворк, формируя следующую архитектуру метаданных:
Общая архитектура состоит из трех основных частей:
- Бизнес-возможности. Стандартные блоки бизнес-логики, включая блоки выборки, блоки отображения и модели запросов, являются ключевыми активами многократного использования.
- Метаданные: опишите бизнес-функции (такие как: блок отображения, блок поиска чисел) и взаимосвязь между бизнес-функциями, например, данные, от которых зависит блок отображения, и поля отображения, отображаемые блоком отображения.
- Механизм выполнения: отвечает за использование метаданных, а также за планирование и выполнение бизнес-логики на основе метаданных.
Благодаря органичному сочетанию трех вышеперечисленных частей формируется архитектура стиля, управляемая метаданными.
5 практик оптимизации для GraphQL
5.1 Используйте упрощение
1) Проблема прямого использования GraphQL
Внедрение GraphQL внесет некоторые дополнительные сложности, такие как некоторые концепции, принесенные GraphQL, такие как: Schema, RuntimeWiring, ниже приведен процесс разработки, основанный на собственной Java-инфраструктуре GraphQL:
Эти концепции увеличивают стоимость обучения и понимания для студентов, которые не знакомились с GraphQL, и эти концепции обычно не связаны со сферой бизнеса. Мы надеемся использовать только функцию запросов по требованию GraphQL, но сам GraphQL тянет вниз. В центре внимания студентов, изучающих бизнес-развитие, должна быть сосредоточена на самой бизнес-логике. Как решить эту проблему?
Знаменитый ученый-компьютерщик Дэвид Уилер сказал: «Все проблемы в области информатики можно решить на другом уровне косвенности». Нет проблем, которые нельзя решить добавлением слоя. По сути, за это должен кто-то отвечать. Поэтому мы добавляем слой исполнительного механизма поверх нативного GraphQL, чтобы решить эти проблемы. Цель состоит в том, чтобы оградить сложность GraphQL и пусть разработчики просто сосредоточатся на бизнес-логике.
2) Стандартизация интерфейса выборки
Прежде всего, необходимо упростить доступ к данным, роднымDataFetcher
иDataLoader
Все они находятся на относительно высоком уровне абстракции и лишены бизнес-семантики.В сценариях запросов мы можем сделать вывод, что все запросы относятся к следующим трем режимам:
- 1 чек 1: запрос результата на основе условия.
- 1 проверить N: запрос нескольких результатов на основе одного условия.
- Чарльз Н Н: Пакетная версия одной проверки или одной проверки.
В результате мы стандартизировали интерфейс запроса. Студенты, изучающие бизнес-процессы, могут судить о том, к какому типу они относятся, исходя из сцены, а также могут выбирать и использовать их по мере необходимости. Стандартизированный дизайн интерфейса поиска данных выглядит следующим образом:
Студенты, изучающие бизнес-разработки, могут выбрать количество средств доступа, которые им нужно использовать, и указать тип результата с помощью дженериков.Относительно просто проверить 1 и 1. Для проверки N мы определяем его как интерфейс пакетного запроса, который используется для соответствует запросу "N+1". "сценарий, в которомbatchSize
поле используется для указания размера сегмента,batchKey
Он используется для указания ключа запроса, для развития бизнеса нужно указать только параметры, а другие фреймворки обработают его автоматически. В дополнение к этому мы также ограничили, что возвращаемый результат должен бытьCompleteFuture
, который используется для обеспечения полной асинхронности агрегированных запросов.
3) Автоматизация оркестрации агрегации
Стандартизация интерфейса доступа к данным делает семантику источника данных более понятной, а процесс разработки можно выбирать по необходимости, что упрощает развитие бизнеса. Но в это время студенты по развитию бизнеса написалиFetcher
После этого вам нужно перейти в другое место, чтобы написатьSchema
, и писатьSchema
Напиши сноваSchema
иFetcher
развитию бизнеса больше нравится процесс написания кода, и они менее склонны идти в другое место, чтобы получить конфигурацию после написания кода, и одновременное обслуживание кода и соответствующей конфигурации также увеличивает вероятность ошибок.Могут ли эти сложные шаги устранить?удалить?
Schema
иRuntimeWiring
По сути, мы хотим описать некоторую информацию. Если информация может быть описана другим способом, наша идея оптимизации: отметьте аннотацию в процессе развития бизнеса, опишите информацию через метаданные, аннотированные по аннотации, и обменять другие вещи. Пусть Рамки делают это. Диаграмма раствора выглядит следующим образом:
5.2 Оптимизация производительности
5.2.1 Проблемы с производительностью GraphQL
Хотя GraphQL имеет открытый исходный код, Facebook имеет только открытые соответствующие стандарты и не предлагает решения. Платформа GraphQL-Java предоставлена сообществом.Основываясь на решении GraphQL-Java с открытым исходным кодом в качестве механизма запросов по запросу, мы обнаружили некоторые проблемы в приложениях GraphQL, некоторые из которых вызваны неправильным положением, а некоторые вызваны Проблемы в реализации самого GraphQL, такие как несколько типичных проблем, с которыми мы столкнулись:
- Разбор запросов с интенсивным использованием ЦП, в том числе
Schema
анализ иQuery
анализ. - Когда модель запроса более сложная, особенно задержка в существовании больших списков.
- Выпуск потребления моделей на основе отражения
-
DataLoader
Проблема иерархического планирования.
Поэтому мы внесли некоторые оптимизации и изменения в использование и структуру для решения перечисленных выше проблем. В этой главе основное внимание уделяется нашим идеям оптимизации и преобразования в GraphQL-Java.
5.2.2 Оптимизация компиляции GraphQL
1) Обзор принципов языка GraphQL
GraphQL — это язык запросов для создания клиентских приложений, основанный на интуитивно понятном и гибком синтаксисе для описания их требований к данным и взаимодействий. GraphQL относится к предметно-ориентированному языку (DSL), а используемый нами клиент GraphQL-Java реализован на уровне компиляции языка на основе ANTLR 4. ANTLR 4 — инструмент определения и идентификации языка на основе Java. Язык, их соотношение таково:
Принимается исполняющим движком GraphQLSchema
иQuery
Все они основаны на содержимом, выраженном на языке, определенном GraphQL. Механизм выполнения GraphQL не может напрямую понимать GraphQL и должен быть переведен компилятором GraphQL в объект документа, понятный механизму выполнения GraphQL перед выполнением. Компилятор GraphQL основан на Java.Опыт показал, что в случае интерпретации в реальном времени высоконагруженных сценариев эта часть кода станет горячей точкой процессора, а также будет занимать задержки отклика.Schema
илиQuery
Чем сложнее, тем очевиднее потеря производительности.
2) Кэш компиляции схемы и запроса
Schema
Высказанные мнения являются моделью данных и принимают число однородных, относительно стабильных, число не так много, в нашем бизнесе есть место для обслуживания. Поэтому наш подход основан на том, что запуск будетSchema
Созданный механизм выполнения GraphQL создается и кэшируется как синглтон.Query
Для каждой сцены,Query
некоторые отличия, т.Query
Результат синтаксического анализа нельзя использовать как синглтон, наш подход заключается в реализацииPreparsedDocumentProvider
интерфейс, основанный наQuery
Быть ключомQuery
Результаты компиляции кэшируются. Как показано ниже:
5.2.3 Оптимизация механизма выполнения GraphQL
1) Механизм выполнения GraphQL и проблемы
Давайте сначала посмотрим на механизм работы механизма выполнения GraphQL-Java. Предположим, мы выбираем стратегию исполнения, которая будетAsyncExecutionStrategy
, чтобы увидеть процесс выполнения механизма выполнения GraphQL:
Приведенная выше диаграмма последовательности была упрощена, и некоторая нерелевантная информация была удалена.AsyncExecutionStrategy
изexecute
Метод представляет собой реализацию стратегии выполнения объекта в асинхронном режиме, начальную точку выполнения запроса и точку входа запроса корневого узла.AsyncExecutionStrategy
Логика запроса для нескольких полей объекта принимает метод реализации цикла + асинхронность, Мы начинаем сAsyncExecutionStrategy
изexecute
Метод срабатывает, и процесс запроса GraphQL понимается следующим образом:
- вызвать текущую границу поля
DataFetcher
изget
метод, если поле не привязаноDataFetcher
По умолчаниюPropertyDataFetcher
поле запроса,PropertyDataFetcher
Реализация основана на отражении для чтения полей запроса из исходного объекта. - будет из
DataFetcher
Запрос получает результат, упакованный какCompletableFuture
, если сам результатCompletableFuture
, то он не будет сворачиваться. - результат
CompletableFuture
После завершения позвонитеcompleteValue
, обрабатываемые отдельно в зависимости от типа результата.- Если результатом запроса является тип списка, то тип списка будет пройден и выполнен рекурсивно для каждого элемента.
completeValue
. - Если тип результата является типом объекта, то выполняется на объекте
execute
, вернуться к исходной точке, т.AsyncExecutionStrategy的execute
.
- Если результатом запроса является тип списка, то тип списка будет пройден и выполнен рекурсивно для каждого элемента.
Выше приведен процесс выполнения GraphQL, в чем проблема с этим процессом? Давайте посмотрим на проблемы, возникающие при применении и практике GraphQL в наших бизнес-сценариях на основе последовательности маркировки на графике.Эти проблемы не означают, что они также являются проблемами в других сценариях, а только для справки:
Вопрос 1:PropertyDataFetcher
Проблема с точкой доступа процессора,PropertyDataFetcher
Он относится к горячему коду во всем процессе запроса, и его собственная реализация также имеет некоторые возможности для оптимизации.PropertyDataFetcher
Выполнение станет точкой доступа ЦП. (Чтобы узнать о конкретных проблемах, обратитесь к фиксации и преобразованию на GitHub:GitHub.com/graph up — просто ав…)
вопрос 2: Расчет списка - это трудоемкость. Расчет списка является циркулярным. Для сценариев, где существует большой список в результате запроса, цикл приведет к значительной задержке в общем запросе. Давайте возьмем конкретный пример. Предположим, что есть размер списка 1000 в результате запроса, и обработка каждого элемента составляет 0,01 мс, затем общее время составляет 10 мс. На основании механизма запроса GraphQL эта 10 мс заблокирует весь ссылка на сайт.
2) Оптимизация преобразования типов
Модель GraphQL, полученная с помощью механизма запросов GraphQL, и бизнес-реализацияDataFetcher
Возвращаемая модель выборки является изоморфной, но типы всех полей преобразуются во внутренние типы GraphQL.PropertyDataFetcher
Причина, по которой он стал точкой доступа ЦП, заключается в процессе преобразования модели.Схема процесса преобразования из модели, определяемой бизнесом, в модель типа GraphQL показана на следующем рисунке:
Когда в модели результатов запроса много полей, например десятки тысяч, это означает, что каждый запрос содержит десятки тысяч полей.PropertyDataFetcher
Операция на самом деле отражается на проблеме точки доступа ЦП.Наше решение этой проблемы состоит в том, чтобы сохранить исходную бизнес-модель неизменной и заменить не-PropertyDataFetcher
Результаты запроса, в свою очередь, заполняют бизнес-модель. Как показано на следующей диаграмме:
Основываясь на этой идее, результат, который мы получаем с помощью механизма выполнения GraphQL, — это бизнес-процесс.Fetcher
Возвращаемая объектная модель не только решает проблему горячих точек ЦП, вызванную преобразованием отражения поля, но и повышает удобство для развития бизнеса. Поскольку модель GraphQL похожа на модель JSON, в этой модели отсутствуют бизнес-типы, и ее очень сложно использовать непосредственно для развития бизнеса. Вышеупомянутые оптимизации были протестированы в пилотном сценарии, и результаты показали, что среднее время отклика в этом сценарии сократилось на 1,457 мс, среднее количество строк — 99 — на 5,82 мс, а средняя загрузка ЦП снизилась примерно на 12 %.
3) Оптимизация расчета списка
Когда элементов списка много, потребление задержки, вызванное однопоточным методом расчета элемента списка обхода по умолчанию, очень очевидно, и эта оптимизация задержки необходима для сценариев, которые чувствительны к времени отклика. Наше решение этой проблемы состоит в том, чтобы полностью использовать многоядерные вычислительные возможности процессора, разбивать список на задачи и выполнять их параллельно через несколько потоков.Механизм реализации следующий:
5.2.4 Оптимизация планирования GraphQL-DataLoader
1) Основные принципы DataLoader
Сначала кратко представим основной принцип DataLoader, DataLoader имеет два метода, один из которыхload
,одинdispatch
, в сценарии решения задачи N+1 DataLoader используется так:
Все разделено на 2 этапа, первый этап вызываетload
, вызываемый N раз, второй этап вызываетdispatch
,перечислитьdispatch
При фактическом выполнении запроса данных достигается эффект пакетного запроса + фрагментация.
2) Проблема планирования DataLoader
Реализация интегрированной поддержки GraphQL-Java для DataLoader находится в разработке.FieldLevelTrackingApproach
середина,FieldLevelTrackingApproach
Какие проблемы с реализацией? Нижеследующее основано на диаграмме, показывающей проблемы, вызванные собственным механизмом планирования DataLoader:
Проблема очевидна, судя поFieldLevelTrackingApproach
реализация, следующий уровеньDataLoader
изdispatch
Перед выдачей необходимо дождаться возврата результатов этого уровня. На основе такой реализации формула расчета общего времени запроса равна: ВСЕГО = MAX (задержка 1-го уровня) + MAX (задержка 2-го уровня) + MAX (задержка 3-го уровня) + … ,Общее время запроса равно сумме максимальных значений затрат времени каждого слоя.Фактически, если расположение ссылок написано самими студентами по развитию бизнеса, теоретический эффект заключается в том, что общие затраты времени равны к ссылке с самой длинной ссылкой. потраченное время, это разумно. иFieldLevelTrackingApproach
Результаты, показанные реализацией .
Проблема в том, что приведенная выше реализация неприемлема в некоторых бизнес-сценариях, например, ограничение времени отклика нашего сценария списка составляет менее 100 мс, из которых по этой причине включены десятки мс. Один из способов решения этой проблемы — самостоятельно организовать сценарии с особо высокими требованиями к времени отклика без использования GraphQL, другой — решить эту проблему на уровне GraphQL для сохранения единства архитектуры. Далее поговорим о том, как мы расширяем исполняющий движок GraphQL-Java для решения этой проблемы.
3) Оптимизация планирования DataLoader
Для проблемы производительности планирования DataLoader,Наше решение состоит в том, чтобы вызвать определенныйDataLoader
изload
После этого сразу звонитеdispatch
способ выдачи запроса запроса, вопрос в том, как мы узнаем, какая загрузка является последней загрузкой? Эта проблема также является трудностью при решении проблемы планирования DataLoader.Ниже приведен пример, объясняющий наше решение:
Предположим, структура модели, которую мы запрашиваем, выглядит следующим образом: корневой узелQuery
Поле ниже, имя поляsubjects
,subject
Ссылка представляет собой список,subject
Ниже есть два элемента, обаModelA
экземпляр объекта ,ModelA
Есть два поля,fieldA
иfieldB
,subjects[0]
изfieldA
АссоциацияModelB
экземпляр ,subjects[0]
изfieldB
Связать несколькоModelC
пример.
Чтобы облегчить понимание, мы определяем некоторые понятия, поле, экземпляр поля, завершенное выполнение экземпляра поля, размер значения экземпляра поля, размер выполнения объекта значения экземпляра поля, завершенное выполнение объекта значения экземпляра поля и т. д.:
-
поле: имеет уникальный путь, является статическим и не имеет ничего общего с размером объекта среды выполнения, например:
subjects
иsubjects/fieldA
. -
Экземпляр поля: Экземпляр поля с уникальным путем является динамическим и зависит от размера объекта во время выполнения, например:
subjects[0]/fieldA
иsubjects[1]/fieldA
полеsubjects/fieldA
пример. - Экземпляр поля выполнен: экземпляр объекта, связанный с экземпляром поля, был выполнен GraphQL.
-
Размер значения экземпляра поля: количество экземпляров объекта, на которые ссылаются экземпляры поля, как в приведенном выше примере,
subjects[0]/fieldA
Размер значения экземпляра поля равен 1,subjects[0]/fieldB
Размер значения экземпляра поля равен 3.
В дополнение к приведенным выше определениям наш бизнес-сценарий также удовлетворяет следующим условиям:
- Существует только 1 корневой узел, и корневой узел представляет собой список.
-
DataLoader
Должен принадлежать к полю, под полемDataLoader
Должен выполняться количество раз, равное количеству экземпляров объекта под ним.
Основываясь на приведенной выше информации, мы можем провести следующий анализ проблемы:
- При выполнении экземпляра поля мы можем знать размер текущего экземпляра поля, размер экземпляра поля равен ассоциации поля
DataLoader
Необходимо выполнить под текущим экземпляромload
количество раз, поэтому выполнениеload
После этого мы можем узнать, является ли текущий экземпляр объекта последним объектом своего экземпляра поля. - Экземпляр объекта может зависать в разных экземплярах поля, поэтому только когда текущий экземпляр объекта является последним экземпляром объекта его экземпляра поля, это не означает, что текущий экземпляр объекта является последним из всех экземпляров объекта, если и только Значение true, если экземпляр узла, в котором находится экземпляр объекта, является последним экземпляром узла.
- Мы можем рассчитать количество экземпляров поля из размера экземпляра поля, например, мы знаем
subjects
размер равен 2, тогда мы знаемsubjects
Поле имеет два экземпляра поляsubjects[0]
иsubjects[1]
, также знаю полеsubjects/fieldA
Есть два экземпляра,subjects[0]/fieldA
иsubjects[1]/fieldA
, поэтому мы можем сделать вывод из корневого узла, был ли выполнен экземпляр поля.
Проведя приведенный выше анализ, мы можем сделать вывод, что условие для выполнения объекта состоит в том, что экземпляр поля, в котором он находится, и все экземпляры родительского поля поля, в котором он находится, выполняются, а текущий исполняемый экземпляр объекта является последним. объект экземпляра поля, где он находится экземпляр времени. Основываясь на этой логике суждения, наш план реализации состоит в том, чтобы завершать вызов после каждого вызова.DataFetcher
Когда , определить, необходимо ли инициироватьdispatch
, если да, инициируйте. Кроме того, указанные выше сроки и условия отсутствуютdispatch
Проблема в том, что есть частный случай, когда текущий экземпляр объекта не является последним, а оставшийся размер объекта равен 0, тогда текущая ассоциация объектов никогда не сработаетDataLoader
изload
, поэтому, когда размер объекта равен 0, требуется дополнительное суждение.
Согласно приведенному выше логическому анализу, мы достиглиDataLoader
Вызовите оптимизацию ссылки для достижения теоретического оптимального эффекта.
6 Влияние новой архитектуры на модель НИОКР
Продуктивность определяет производственные отношения.Архитектура агрегации информации на основе метаданных является основной производительностью построения сцены отображения, а модель и процесс развития бизнеса являются производственными отношениями, поэтому они также будут меняться соответствующим образом. Далее мы представим влияние новой архитектуры на исследования и разработки с точки зрения режима и процесса разработки.
6.1 Модель развития, ориентированная на бизнес
Новая архитектура предоставляет набор стандартизированных ограничений декомпозиции кода, основанных на абстракции бизнеса. В прошлом понимание системы студентами-разработчиками, скорее всего, сводилось к «проверке сервисов и объединению данных», но теперь понимание бизнеса и декомпозиции кода студентами-разработчиками будет последовательным. Например, блок отображения представляет логику отображения, а блок выборки представляет логику выборки. В то же время многие сложные и подверженные ошибкам логики были заблокированы фреймворком, и студенты, занимающиеся исследованиями и разработками, могут больше сосредоточиться на самой бизнес-логике, такой как: понимание и инкапсуляция бизнес-данных, понимание и написание логики представления и запросы. модели Абстракция и построение. Как показано на следующей диаграмме:
6.2 Модернизация процесса НИОКР
Новая архитектура влияет не только на написание кода НИОКР, но и на совершенствование процесса НИОКР.Основываясь на возможностях визуализации и конфигурации, реализуемых архитектурой метаданных, существующий процесс НИОКР значительно отличается от предыдущего процесса НИОКР, как показано на рисунке. на следующем рисунке показано:
В прошлом это была модель разработки "одна палочка до конца". Для создания каждой сцены отображения требовался весь процесс от взаимодействия интерфейса до разработки API. На основе новой архитектуры система автоматически поддерживает многоуровневое повторное использование и возможности визуализации и настройки.
Дело 1: Это наилучшая ситуация. В настоящее время функция выборки и функция отображения были решены. Все, что нужно сделать студентам НИОКР, это создать план запроса, выбрать требуемый блок отображения на основе операционной платформы и удерживать Идентификатор плана запроса на основе запроса Интерфейс может найти необходимую отображаемую информацию Интерфейс визуализации и настройки показан на следующей диаграмме:
Случай 2: В настоящее время может не быть функции отображения, но вы можете видеть через операционную платформу, что источник данных был подключен, так что это не сложно.Вам нужно только написать логику обработки на основе существующего источника данных.Это очень крутая логика обработки, кусок чистой логики, список источников данных показан на следующей диаграмме:
Случай третий: В худшем случае система не может удовлетворить текущие возможности запроса в это время, что бывает редко, потому что серверная служба относительно стабильна, поэтому не нужно паниковать, просто подключите источник данных в соответствии со стандартной спецификацией. , а потом написать Достаточно обработать фрагменты логики, а потом эти возможности можно постоянно переиспользовать.
7 Резюме
Сложность сцены отображения товаров отражается в следующем: много сцен, много зависимостей, много логики, и между разными сценами есть различия. В этом контексте, если он находится на ранней стадии бизнеса, нет необходимости слишком много сомневаться в индивидуальном методе строительства «в стиле дымохода». Однако с непрерывным развитием бизнеса, непрерывной итерацией функций и тенденцией крупномасштабных сценариев постепенно станут очевидными недостатки персонализированного построения «в стиле дымохода», включая такие проблемы, как высокая сложность кода и отсутствие способность осадков.
Основываясь на анализе основных противоречий, с которыми сталкивается Meituan при выкладке товаров в магазине, в этой статье представлены:
- Различные режимы применения BFF в отрасли, а также преимущества и недостатки различных режимов.
- Улучшенный дизайн схемы на основе метаданных на основе схемы GraphQL BFF.
- Проблемы и решения, с которыми мы столкнулись в практике GraphQL.
- Представлено влияние новой архитектуры на модель НИОКР.
В настоящее время основные сценарии отображения товаров, за которые отвечает команда автора, были перенесены в новую структуру.Основываясь на новой модели исследований и разработок, мы добились повторного использования логики отображения более чем на 50% и повышения эффективности более чем в 1 раз. Я надеюсь, что эта статья может быть полезной для всех.
8 ссылок
- [1]Сэм Ньюман.IO/patterns/AR…
- [2] woohoo.whost works.com/talent/radar/special...
- [3] Изучите серверную систему поставщика электроэнергии, посмотрите, этого достаточно
- [4]Определение фреймворка — Википедия
- [5] Эффективные исследования и разработки — исследования и практика Xianyu в области агрегации данных
- [6] «Архитектура системы — проектирование продуктов и разработка сложных систем»
9 Информация о наборе
Комплексный научно-исследовательский центр Meituan Daodian уже долгое время набирает инженеров, занимающихся интерфейсом, серверной частью, хранилищем данных, инженерами по алгоритмам машинного обучения / интеллектуального анализа данных, расположенным в Шанхае.Заинтересованные студенты могут отправлять свои резюме по адресу:tech@meituan.com(Указать в теме письма: Комплексный научно-исследовательский центр Meituan Daodian — Шанхай).
Прочтите другие сборники технических статей от технической команды Meituan
внешний интерфейс | алгоритм | задняя часть | данные | Безопасность | Эксплуатация и техническое обслуживание | iOS | Android | контрольная работа
|Ответьте на ключевые слова, такие как [акции 2020 г.], [акции 2019 г.], [акции 2018 г.], [акции 2017 г.] в диалоговом окне строки меню общедоступной учетной записи, и вы сможете просмотреть коллекцию технических статей технической группы Meituan в течение годы.
| Эта статья подготовлена технической командой Meituan, авторские права принадлежат Meituan. Добро пожаловать на перепечатку или использование содержимого этой статьи в некоммерческих целях, таких как обмен и общение, пожалуйста, укажите «Содержимое воспроизводится технической командой Meituan». Эта статья не может быть воспроизведена или использована в коммерческих целях без разрешения. Для любой коммерческой деятельности, пожалуйста, отправьте электронное письмо по адресуtech@meituan.comПодать заявку на авторизацию.