company_banner

Технология Apphost: альтернативная вселенная микросервисов в Яндексе

    Привет, Хабр. Меня зовут Святослав Фельдшеров, я разрабатываю инфраструктуру в поиске Яндекса. Когда-то она представляла из себя бутерброд. Каждый её слой могли эффективно разрабатывать единицы людей. Однако верхний добавлял пикантности. Этот слой представлял из себя Apache с кучей Perl’овых модулей.

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

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


    Почему наша вселенная альтернативная?

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

    Архитектуру любого крупного сервиса Яндекса, в том числе Поиска, можно представить в виде большого графа. Его узлы — сервисы, рёбра — потоки передачи данных. Перейдём к примерам. Рассмотрим сервис больше чем из одного компонента: балансер, некоторый фронтенд, обращающийся к шардированному бэкенду:

    В чём проблема этой картинки? Допустим, вы отправили запрос в первый бэкенд, а он вернулся с кодом 500 или затаймаутился. Самая простая гипотеза — обычное невезение: затупила сеть, инстансу бэкенда, в который вы попали, стало плохо. Перезапросить ошибку в таком случае — вполне естественное желание. Но нельзя же повторять запросы бесконечно: если проблема посерьёзнее невезения, получим DDOS своими руками, бэкенд ляжет и не сможет вернуться к работе без вмешательства человека. Чтобы нагрузка не превышала разумную, важно предусмотреть в структуре балансера и фронтенда бюджеты на повторные запросы и классифицировать ошибки: перезапрашиваемые, быстрые, неперезапрашиваемые. Написать такую логику не очень сложно, но потребуются усилия и внимание всех команд компании.

    Такой подход сработает для сервиса из одного слоя, как на картинке выше. Но если слоёв больше — n, возникает проблема: нагрузка на нижний слой возрастет как (k)^n, где k — максимальное количество перезапросов на одном слое, оно же «рейт перезапросов». Побороть эту проблему сложнее: либо не делать сервисы многослойными, либо пробрасывать информацию про бюджет вместе с запросом и ответом каждого сервиса.

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

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

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

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

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

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

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

    Всё сетевое хождение в нашей вселенной выполняет один сервис — Apphost. В его конфиге прописаны связи и зависимости между сервисами. Например, граф для сервиса из примера выше в мире Apphost выглядел бы как-то так:

    Напомню: это граф зависимостей потоков данных между сервисами. Каждая вершина — отдельный сервис в нашем облаке.

    Почему нам так нравится наша вселенная?

    Она решает описанные выше проблемы.

    Если каждая команда пишет перезапросы самостоятельно, легко перегрузить источники. В Apphost прописаны хорошие перезапросы с бюджетами, что исключает рукотворный DDOS. При этом во всех хороших инсталляциях над Apphost есть только балансировщик нагрузки, то есть в системе три слоя. Рейт перезапросов мы настроили в 10% от потока, и проблема «сервис уложило перезапросами» почти решена.

    Путь запроса и расположение интересующего сервиса можно посмотреть в конфиге Apphost. Это всё равно непросто, например основной граф веб-поиска выглядит так:

    Но представьте, каково было бы собирать то же самое из кода по всему проекту!

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

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

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

    И на солнце бывают пятна: узкие места Apphost

    Хотя наш мир нам нравится, у жизни в нём есть свои сложности.

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

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

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

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

    Заключение

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

    Для меня до сих пор загадка есть ли что-нибудь похожее в опенсорсе. Но и как делать проекты масштаба нашего Поиска без аналога Apphost, представить не могу. Слышал про похожие идеи у Dropbox, Uber и Microsoft, но не знаю деталей о них. Если вы сталкивались с чем-то подобным, приходите обсудить в комментариях.   

    Спасибо!

    Яндекс
    Как мы делаем Яндекс

    Комментарии 51

      0

      Так выходит же, что это обычный брокер, просто самописный, нет?

        +4
        Не совсем похоже. Брокер скорее про очереди сообщений, задач, данных на доставку, а Аппхост про выполнение запроса в твой сервис.

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

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

        Брокер в Яндексе тоже есть, но не самописный, конечно :) Мы про него писали некоторое время назад.
        0

        Какой-то гибрид сервис меша и API Gateway

          +2
          А вот это прямо в точку! Когда думали как объяснять новым людям, что такое Аппхост, сошлись, что API Gateway самый близкий аналог. Только API Gateway это обычно кастомный код, а Аппхост это некоторый способ сконфигурировать свой API Gateway.

          А про сервис меш не думал никогда, но да, что-то есть.
            0
            Apphost это внутренне решение или доступно в вашем облаке? Если доступно интересно было пощупать, из статьи довольно поверхностно впечатление о сервисе.
              0
              Пока, увы, только внутреннее. К облаку мы еще не готовы, да и сходу объем спроса не понятен.
          +1

          О, ещё одна крупная российская компания пилит свой велосипед. С визуализацией и распределеными трассировками.

            +1
            На самом деле, мы рады взять готовое! Но где? Если знаешь проекты, которые делают то же самое, покажи.
              0
              Читал текст и думал — вот тут circuit breaker нужен, тут opentracing, тут еще что-то… Вопрос — вы же в курсе технологий, почему не просто микросервисы с нужными (стандартизированными) фишками?
                0
                Вот тут хороший вопрос и на него нет однозначного ответа. То есть, можно грамотно задизайнить то что есть сейчас на классической микросервисной архитектуре и это будет хорошо работать.

                Почему конкретно у нас Apphost, я для себя отвечаю так.
                — Понятное разделение зоны ответственности. Команда реализует бизнес логику, мы реализуем передачу данных. Когда мы что-то чиним, мы чиним у всех сразу.
                — Кто-нибудь обязательно забудет сделать одно из N обязательных действий с использованием правильной стандартизованной технологии и все сломает.
                — И шестую проблему из статьи не понятно как решать. Чтобы внедрить фичу, тебе придется комитить в код другой команды, или ставить на них задачу.
                  0
                  Шестую задачу мы стараемся решить тем, что во фреймворке (который содержит абстракции поддерживает трейсинг метрики и тп) добавляем функционал.
                  Все сервисы создаются грубо говоря xx.NewService, тем самым простое использование renovate бота заставляет его сделать пул реквесты во всех репах как только либа с фреймворком обновилась. (он и мерджить может такое автоматом если тесты прошли успешно)
                    0
                    Вообще звучит хорошо, да. В очень похожем сеттинге живет другой большой поисковик. Как там устроен поиск я доподлинно не знаю, но все сервисы создаются через grpc описание, в моннорепозитории можно пойти и всем закомитить нововеденние. Так что, да схема может работать.

                    Про шестую проблему, все таки не совсем тебя понял. Чтобы внедрить фичу, мне нужно потрогать все сервисы на пути пользователь -> мой микросервис. То есть пойти кода написать в микросервисы соседних команд, что не очень удобно. Под аппхостом, я добавил вершинку в граф, написал бекенд этой вершинки и готово.
                      0
                      про шестую — не нужно своими руками ничего делать. это делает автоматика обновляя используемую библиотеку фреймворка в модулях и пересобирая бинарник в ci/cd
                +2

                Так их же полно )
                envoy (как основа для API gateway/service mesh, можно самому воспользоваться), gloo, ambassador (правда, k8s only), kong, gravitee, tyk — сотни их
                Причем многие опенсурс. Есть и платные.
                Основная ценность — именно, что дополнительный функционал помимо retry, circuit breaker, tracings etc., а закрытие АПИшек авторизацией, веб-панели со статистикой, возможность управления из GUI etc. etc.

                +4
                Написав «ещё одна» вы подразумеваете еще кого-то кроме указанной в посте компании? Когда дело касается действительно высоких нагрузок (даже гигантских) готовое универсальное решение будет проигрывать самописному (при условии что пишут профессионалы со знанием предметной области).
                Это здорово что подобные «велосипеды» изобретаются «еще одной» крупной компанией.
                  0

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

                    +3

                    Nginx тоже когда-то был самописным велосипедом, ведь до него уже были как минимум Apache и IIS.

                      0

                      nginx стал не котироваться, когда он начал хотеть денег. Либо перекомпиляция и искать сторонние модули, либо покупаешь nginx plus.
                      В результате появляются статьи вроде https://m.habr.com/ru/company/oleg-bunin/blog/423085/
                      И, да, энвой — кумир 21го века, а энжинкс пора на боковую

                    +2
                    Интересный вопрос. А вот те «велосипеды», что конкурируют на рынке — почему их создание «целесообразно и оправдано», а создание альтернатив для них — это «общественно порицаемое деяние»(судя по комментам явно создаётся такое ощущение)? Почему создание нового фреймворка — это плохо. А использование старого и хорошо проверенного временем — это «верх профессионализма»?

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

                    А ведь в бизнесе ключевой момент успешности любого продукта(сервиса) заключается в наличии у него некоторого «конкурентного приемущества» — т.е. по-определению некоторого свойства, которым конкуренты не обладают. Чего-то абсолютно нового. Иногда это может упираться в отличия их IT-платформы в том числе. За счёт разнообразия и многообразия мы и имеем общий прогресс.

                    Почему существуют бизнесмены и реализуют всё новые и новые бизнес-идеи? Почему не говорят: «Нафиг что-то придумывать и рисковать делать новое. Возьму франшизу или открою ларёк». Так вот для реализации их идей и требуются нетиповые подходы и разработки. Просто всегда есть риск, что «ставк»а не сыиграет.

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

                    Говорить, что «создавать велосипеды — это плохо и непрофессионально» можно только неявно признаваясь в том, что: (1) либо наши задачи очень сильно типовые; (2 )либо собственного профессинализма никогда для реализации подобной задачи не хватит; (3) либо при наличии ресурсов риск реализации кажется неоправданным. Но так думают не все и не во всех случаях. И поэтому, по мне, лучше привествовать всё новое. Иначе так всю жизнь и придётся ездить на «велосипеде»… трёхколёсном… хоть и чертовски надёжном:)
                      +4
                      Ну дак гуглу можно пилить велосипеды а яндексу — нет. Всё просто.
                    –3
                    Правильно сказано «единая точка отказа»!
                    «На деле так как инстансов Apphost много, они живут на машинах из разных стоек — значит, сервис выживает при выпадении хоста, стойки или даже целого датацентра»
                    Это касательно железа. А если баг в софте Apphost?
                      +8
                      Если баг в софте, то да, можно все сломать. Но тут как, если баг в ядре, балансировщике нагрузки, софте свитча, в супервизоре облака, все сломается точно так же… Так что добавление Apphost не делает конструкцию более хрупкой.

                      Остается только качественно тестироваться и аккуратно катать релизы.
                      0
                      Допустим, вы отправили запрос в первый бэкенд, а он вернулся с кодом 500 или затаймаутился. Самая простая гипотеза — обычное невезение: затупила сеть, инстансу бэкенда, в который вы попали, стало плохо. Перезапросить ошибку в таком случае — вполне естественное желание. Но нельзя же повторять запросы бесконечно: если проблема посерьёзнее невезения, получим DDOS своими руками, бэкенд ляжет и не сможет вернуться к работе без вмешательства человека. Чтобы нагрузка не превышала разумную, важно предусмотреть в структуре балансера и фронтенда бюджеты на повторные запросы


                      Вот тут мне не очень понятна логика. Если у нас что-то временно «не так», можно вернуть клиенту код 503, который означает, что:

                      The server cannot handle the request (because it is overloaded or down for maintenance). Generally, this is a temporary state


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

                      Выделять эти ресурсы внутри кластера — дороже для кластера, как в плане ресурсов, так и в плане сложности.

                      Можно как-то усилить аргументацию в пользу реализации «перезапрашивание» внутри кластера?
                        0

                        Подозреваю, что клиент для поиска — это, в большинстве случаев, простой вэб-браузер, он просто покажет эту 503 пользователю, а тот огорчится.

                          0
                          Пожалуй да, если сервис должен выдать некий статический html, то 503 не подойдет.
                          0
                          Вот тут мне не очень понятна логика. Если у нас что-то временно «не так», можно вернуть клиенту код 503, который означает, что:

                          нет, есть же концепция graceful degradation ) Когда ты клиенту возвращаешь часть функционала, а что там у тебя под капотом его волновать не особо должно


                          Подозреваю, что клиент для поиска — это, в большинстве случаев, простой вэб-браузер, он просто покажет эту 503 пользователю, а тот огорчится.

                          +++ Но есть же AJAX! Viknet и соответственно, половина веб страниц — по факту это уже динамические веб-приложения

                            0

                            Я думаю, конкретно в поиске довольно большая часть запросов идёт напрямую из поисковой строки браузера на выдачу.
                            Ну и есть такое соображение, что делать повторные запросы внутри ДЦ гораздо быстрее, чем от клиента.

                          0

                          Расскажите на примере, как выглядит взаимодействие со стороны рядового сервиса А, который хочет отправить запрос в сервис Б, а затем в В.


                          Условно, сервис посылает запрос на http://apphost (допустим, набор реплик получен через service discovery или любым другим способом), где apphost — какая-то реплика AppHost. Каким образом сервис А скажет, что он отправляет запрос в сервис Б/В? Заголовок? Префикс пути? Что-то ещё?

                            0
                            Сервис А не хочет отправлять запросы в Б и В.

                            На аппхосте добавляется правило: когда клиент пришел по урлу Х — сходить в Б и В, взять из их ответов вот такие данные и сходить с этими данными в А
                              0

                              Как тогда обстоит дело с вложенностью?


                              Т.е. пришёл юзер на урл X, аппхост отправил этот запрос в сервис А, сделал какую-то часть логики, затем ему потребовалось, допустим, получить информацию о пользователе, которая хранится в сервисе Б. А сервису Б ещё нужно подгрузить ещё какую-то информацию из сервиса В.


                              В статье есть пример графа взаимодействий, на котором особо ничего не видно. + есть схематичный пример (в разделе с узкими местами), но там вложенности нет. Поэтому неясность остаётся :)


                              клиент пришел по урлу Х

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

                                0
                                Как тогда обстоит дело с вложенностью?

                                какая вложенность, не понимаю?


                                На аппхосте добавляется правило: когда клиент пришел по урлу Х — сходить в Б и В, взять из их ответов вот такие данные и сходить с этими данными в А

                                чисто функционал api gateway, так-то.


                                Т.е. пришёл юзер на урл X, аппхост отправил этот запрос в сервис А, сделал какую-то часть логики, затем ему потребовалось, допустим, получить информацию о пользователе, которая хранится в сервисе Б. А сервису Б ещё нужно подгрузить ещё какую-то информацию из сервиса В.

                                странный сценарий, я так понял, что А, Б и В фактически независимы друг от друга.

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

                                  С точки зрения апхоста другой граф/другой апхост это такой же источник, как и любой другой.
                                    0
                                    Вложенности нет. И обращений обратно к аппхосту быть не должно. Если сервис А зависит от Б — это должно быть учтено в графе, чтобы аппхост сам, превентивно, сходил в Б и получил что нужно, и только потом дергал А.
                                      0

                                      По сути получается некий аналог ФП в мире микросервисов, понял, спасибо :)

                                        0

                                        Это, извините, не «А зависит от Б», а запрос клиента зависит от А и Б(А) (потому что аргументы для Б могут прийти любым другим способом, кроме того, чтобы быть получены из А). Но вообще такие связки выглядят как какой-то своеобразный (кривой?) дизайн. Надеюсь, что он спроектирован осмысленно, а не просто так. И есть реальные причины так делать

                                          0
                                          Наоборот, запрос клиента зависит от Б и А(Б). Ну да, статья как раз о том, почему это осмысленно и какие реальные причины так делать (проблемы) :)
                                          0

                                          Допустим, есть сервис А. Он владеет некоторыми данными о приславшем запрос юзере. На основании этих данных А решает, надо ли делать запрос в Б, и с какими параметрами. Как именно аппхост разруливает эту ситуацию?


                                          По графу аппхост знает, что для выполнения задачи А ему может (или нет) понадобиться запрос в Б с неизвестно какими параметрами (потому что они в БД сервиса А). Как аппхост сделает запрос в Б самостоятельно, до запроса в А?


                                          Есть вариант, когда нужный метод А делится на две части: первая "вернуть из БД параметры для запроса в Б, если этот запрос нужно сделать", и вторая "использовать ответ от Б (если туда отправлялся запрос) из своих параметров и завершить обработку запроса юзера". Тогда аппхост сможет сделать вызовы А1, (опционально) Б(A1), А2(Б(А1)). Но этот вариант заметно усложняет реализацию А (бизнес-логика может быть довольно сложной, на сколько частей надо будет разделить один метод, которому нужно отправить запросы в 10 других сервисов?), плюс переносит часть бизнес-логики из А в аппхост, плюс вынуждает А выставить часть своих внутренностей наружу как публичное API (тот самый запрос A1 возвращающие данные из БД нужные для запроса в Б).

                                            0
                                            Да, аппхост плохо разруливает эту ситуацию, действительно, будет заметное усложнение логики. Но если вы проектируете сервисы для работы в парадигме аппхоста — вы постараетесь с самого начала делать сервисы так, чтобы таких ситуаций не возникало. Кто главный источник данных в вашем запросе — сервис А или сервис Б? Если сервис А — почему он владеет данными о юзере, не должны ли они быть сосредоточены в сервисе Ю? И цепочка например Ю, А(Ю), Б(Ю)?
                                              0

                                              Не приводит ли этот подход (проектирование в парадигме аппхоста) к тому, что появляются такие вот сервисы Ю, которые иначе были бы вообще не нужны, и, более того, по сути дают через API прямой доступ к данным, которые, по-хорошему (с точки зрения bounded context, например), должны бы принадлежать другому сервису и вообще не быть доступны напрямую через API?


                                              И стоит ли такое нарушение инкапсуляции и повышенная хрупкость (изменение структуры данных Ю потребует изменения его API, что в свою очередь скорее всего потребует изменения API сервисов принимающих эти данные от Ю) тех плюшек, которые даёт аппхост? Ведь получается, что мы гробим архитектуру ради мелких технических преимуществ (вроде наглядности графа и избавления от логики ретраев в коде сервисов) — в дальней перспективе такое обычно сказывается очень негативно.

                                                0
                                                Встречный вопрос: почему у вас сервис А хочет ходить в сервис Б? Почему данные, необходимые для похода в Б, лежат в БД сервиса А? Не спутаны ли у вас сервисы?)

                                                А так это всё трейдоффы \(º_o)/

                                                Пока у вас прямолинейный подход дает два сервиса А и Б, и А ходит в Б — вам аппхост, наверно, не нужен. Когда все это приводит к тому что там слоев, скажем, пять — то уже становится пора это как-то поплющить — чтобы не гробить архитектуру. Аппхост — просто системно подходит к тому чтобы плющить, делает архитектуру строго однослойной. Со своими плюсами и минусами, конечно.
                                    0
                                    Странно это как-то — сделать один общий оркестратор «для всего»…
                                      0
                                      А иметь в наличии много разных оркестраторов если этого «всего» очень много — это не странно? :)
                                        0
                                        Нет, это укладывается в концепцию микросервисной архитектуры, где каждый сервис идеологически должен решать ровно одну задачу.
                                          +1

                                          Главное — не переборщить с разбивкой на микросервисы, а то Вы скатываетесь к прям «функциям» (серверлесс), но сложность по факту никуда не девается и это ещё вопрос — что проще — управлять 5 серверами, 50 «микросервисами» или 500 «наносервисами»

                                            +3
                                            В «концепцию» может какую-то и укладывается, но вот в голову не всегда:) Иногда можно получить комбинаторный взрыв на многообразии связей между избыточным множеством компонентов, и, как следствие, увеличение числа точек отказа и увеличением сложности управления такой системы, т.е. прямым увеличение эксплуатационных расходов со снижением общей надёжности. Надо всегда помнить, что декомпозиция и нормализация — это всего лишь инструмент, а не правило. И, как любым инструментом, ими нужно пользоваться только целесообразно ситуации.
                                        0
                                        Сори, если пропустил — на чем сервис написан и как примерно в него выкладываются конфиги?
                                          0
                                          Написан на плюсах.

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

                                          Аппхосты уже смотрят в YT и качают оттуда обновления.
                                          0

                                          В яндексе изобрели оркестратор микросервисов. Что скажете насчет Netflix Conductor? https://netflix.github.io/conductor/

                                            0
                                            Интересная статья, спасибо! На чем написан Apphost, если не секрет? И что с Apach'eм и Перловыми модулями? Отправили их на вечный покой?
                                              +1
                                              Перловые модули едут на покой уже несколько лет :) Насколько я знаю, уже не далеко.

                                              Язык — плюсы.
                                                0
                                                Спасибо! У меня прям приступ ностальгии, стоило про этот перловый код вспомнить. В то же время приятно, что от него наконец избавились.

                                            Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                                            Самое читаемое