Search
Write a publication
Pull to refresh

Comments 40

Отличная статья, сжато и по делу, респект автору!

P.S. CH и как TSDB хорош, не обязательно InfluxDB в инфраструктуру тащить.

Статья замечательная, хорошо и структруировано. От себя, со стороны ползателя, добавлю только одно замечание:

Совершенно упущен размер контента, отдаваемого сервером в браузер, из-за которого по современным сайтам ходить "из деревни" (с 56кбод) практически не реально. От 100 до 400мегабайт на запрос. Да, большая часть их кеширована на разных уровнях и НЕ нагружает сервера, но .. клиенту это этого ни разу не легче.

Помнится в 2000-х коллега жаловался, что у них уволили нескольких разрабов, после того как анализ проблем сайта выловил размер страницы под .. мегабайт (всего, Карл!) .. Вспоминаю те времена начала интрентета и .. приходит понимание "как был прав тот директор ИТ".

Люто, бешено плюсую!! Теперь и в больших городах инет слабый. И бесит что банковской приложухе lte подавай

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

Ваш сервис может отдавать пользователю HTTP 200 OK за миллисекунду, но при этом в payload не иметь запрошенной информации. Или, например, не выполнять запрошенное действие в реальности.

Пример: в онлайн-магазине есть смысл иметь "виртуального покупателя", который раз минуту (например) проходит по всему базовому клиентскому пути - листает каталог, собирает корзину, делает чекаут, проводит оплату, отменяет заказ.

Да, в аналитической системе вам нужно будет убирать его заказы из массива данных во избежание искажений статистики. Зато вы в каждый момент времени будете уверены в том,, что базово ваша система работает корректно (если будете "глазами" этого виртуального покупателя контролировать ответы вашей системы). А о проблемах узнаете раньше, чем большинство реальных лодей с ними столкнутся.

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

У меня для этой цели, например, есть несколько "манекенов пользователей" прямо с реальными номерами мобильных телефонов (для 3DS), с реальными email и разными user-agent. Прямо рекомендую всем.

Похоже на регрессионное автотестирование функционала. У нас тестировщики сьюты пишут и гоняют их пачками на отдельном стенде.

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

Это называется Synthetic Testing - стандартная фича во многих системах мониторинга. Он обычно используется в дополнение к RUP (real user monitoring). Внедрение, в самом деле, требует креатива и адаптации системы по многим вопросам. Поэтому лучше начинать с самых простых read-only сценариев.

Это точно. Очевидные камни преткновения (далеко не все) - внешние системы и взаимодействие с ними. Проводить реальные платежи? А как быть с фискализацией, бить реальные чеки прихода и возврата прихода? И так далее.

А как быть с фискализацией, бить реальные чеки прихода и возврата прихода? 

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

Да, обычно источником сценариев является даже не регресс, а смоук.

Насчет компрометации манекена - не уверен что понял мысль. Какова модель угрозы? Что значит "компрометация манекена", кому и зачем это может пригодиться? Можете развернуть тезис?

У нас на проекте есть шардирование базы (из-за специфики самого проекта) и да, какая же это боль, мне от одного упоминания плакать хочется

Браво аплодипую стоя. Читается как увлекательный роман.

Не подскажете где работайте? Прямо таки интересно где трудиться такие толковые архитекторы

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

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

Работа с фичефлагами требует определенной культуры разработки. Иначе можно утонуть в болоте фичефлагов.

Вижу старый фичефлаг в реквесте - отправляю на рефакторинг очистить код. Не?

мда... ну, для начала:

Canary Releasing (Канареечное развертывание).
Вы внимательно следите за метриками ошибок и производительности на этой «канареечной» группе. Ключ к успеху — автоматический мониторинг и откат. Система сама должна обнаружить всплеск ошибок и откатить релиз

ОК. канарейка убита, инженер не проснулся.
но птица накакала в Базу: запорото ~10К записей. что дальше?

Вопрос версионирования базы вообще не рассмотрен. А именно он вызовет самую большую боль, особенно если баз больше одной, либо микросервисы каждый со своей базой... Как это чистить, если что то пошло не так - видимо руками... Честно сказать, я вообще не понимаю, как сейчас это все решается, с учетом количества отдельных команд и микросервисов - единого ответственного за успешность миграции данных нету... Легко представить, что например, команда, которая пишет микросервис "склад" прошляпила баг в новой версии, которые проявляется в каком нибудь не частом сценарии и приводит к двойному списанию товара... Вопрос на засыпку: как восстановить правильные остатки, если "птица нагадила" ? Бэкап раскатать нельзя, он испортит и правильные тоже, т к не учитывает базу заказов из другого микросервиса... Остается только писать скрипт-заплату, который возьмет старую базу, все заказы (по логам или еще как то) и все пересчитает... По моему адова работенка (особенно с учетом того, что это надо сделать быстро...), ну его нафиг, не за зарплату обычного мидла уж точно. За полляма - ну может быть можно подумать 😁

Я не настоящий архитектор, но думаю решение этой проблемы бекап + события. Т.е. вы разворачиваете бэкап на момент релиза, а затем на него накатываете все события от релиза и до ролбэка. События должны привести базу (используя старую версию приложения) в правильное состояние - удалить неверные изменения и оставить верные.

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

Дальше канарейка это типо тоже самое, но на пол шишечки и тут я вообще не понимаю как можно быть наполовину беременным. Конкретно этот новый релиз пишет данные куда? В отдельную/зеленую базу? Значит время синхронизации между синий и зелёной базой вообще потенциально несколько дней, т.е. нужно из синей базы постоянно реплики кидать в зелёную пока релиз не будет признан успешным. Нагрузка на инфру увеличивается на все время обкатки релиза. С другой стороны этот процес гарантирует наличие бэкапа с момента релиза - это ваша синия база. В теории если у вас приложение важные изменения в базе делает через очередь, то вот вам и эвент лог. Тогда автоматика отката примерно такая:

  1. Выключаем для 5% зелёный релиз

  2. Блокируем пользователей попавших в зелёный релиз

  3. Берём лог/очередь из зелёного релиза и накатываем на синий

  4. Возвращаем несчастных пользователей

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

БД одна, но в sql-миграциях надо поддерживать обратную совместимость для возможности отката кода.

В свое время, для склада с партионным учетом на ПХП + Мускуль убил месяц на то, чтобы остатки правильно считались "на лету" а не хранились в БД. Какало в БД много кого и регулярно. Находишь задвоенный, кривой документ перемещения и удаляешь. Остаток выправляется сам.

Всё верно. Мы так за системой БЭСТ пересчитывали остатки на фокспро скриптом (ну как "скриптом" - это целая система еще одна была =) ) Но ведь мы на это время блокировали пользователей или делали это на копии с последующем ручным разбором расхождений.... Как это будет выглядеть на миллионной юзер-базе.... Даже не хочу представлять, пусть архитектор думает, а я обыным сеньором потружусь =))

Статья отличная шпагралка по базовым рецептам решения проблем и приоритете их рассмотрения.

Два момента:

1. «Ручка API» — API handle, по-русски "обработчик API"

2.Разработка высоконагруженых сервисов, не API. API — это интерфейс, в статье больше про особенности реализации интерфейса, а не то как определять сам интерфейс.

"Ручка" - говорят, жаргон. Подёргать ручку - прекраснож.

Ещё "эндпоинт" говорят

Супер! Где же вы были раньше?) делаю свой первый веб сайт и столько вопросов и мало ответов. А тут, неожиданно такая статья и в которой, в общих словах, но понятно рассказано про важные моменты.

Особенно спасибо про информацию о TSDB, я уже подумывал начать писать логи в постгре или клик хаус 😅

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

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

Отличная подборка методов, как некий ориентир для тех кто думает, как оптимизировать. Кстати, кэширование каталогов товаров в e-commerce прям отлично работает и без него вообще никак.

Мне кажется, нераскрыто несколько вопросов: canary releasing отдельный "ад" при изменении схемы данных при обновлениях.

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

P.S. перевод терминов местами непривычный (gpt-like).

Великолепная статья. Сталкивался со многими проблемами в разработке. Некоторые решения использую в связке. Однозначно добавлю в закладки и если возникнет трудность с DevOps, то обращусь к статье

Статья годная, но у Feature Flags есть большой минус, который не описали. Нужно тестировать комбинации фичи. Иначе они могут положить сервисы. У нас такое было, коллеги из другого отдела сделали фитчи, по отдельности фитчи проверили, а в комбинации произошел спам запросов на мой сервис и меня рано утром поднимали для решения проблемы + утром у всех клиентов часть софта не открывалось.

Поясните, пожалуйста, почему хранить долго refresh token - это ок, а access token - нет.

Авторизация может происходить тысячи раз в секунду, лазить в БД на каждый запрос - это верный способ угробить производительность сервиса. Поэтому выдаём пользователю токен, предъявление которого делает запрос авторизованными и сидим довольные. Пока не понадобилось пользователя разлогинить или забанить. Что делать? Делаем этот токен действительным в течении минуты, например, и вместе с ним выдаём долгоживущий, но одноразовый refresh token, для проверки которого нужно сходить в БД. Если пользователя нужно лишить доступа, просто удаляем refresh token из БД. Итого мы имеем возможность раз в минуту отзывать доступ и при этом обслужить условные сто тысяч запросов к сервису не трогая БД для проверки доступа.

То есть так решается вопрос не безопасности и риска компрометации токена на стороне клиента, а производительности сервера. Спасибо!

Это не совсем точное описание.

Проблема производительности сервиса аутентификации/авторизации зачастую решается традиционными способами (кешированием), без refresh token. Но на масштабах гугла кеширование уже не работает и нужно исключить саму связь между сервисом куда пришёл юзер и сервисом аутентификации - и вот тогда возникает необходимость в разделении на refresh и access token (у которого есть неприятная цена в виде задержки между моментом блокирования доступа пользователю и моментом когда его текущий access token истечёт). А поскольку большинство подходов/протоколов/best practice мы получаем от гигантов, то иногда нам заодно подсовывают и проблемы гигантов, которые для нас не особо актуальны - вот и тянут refresh токены куда надо и куда не надо.

Но есть и другая сторона. Напр. когда клиент OAuth это не только и не столько браузер, но и серверная часть, то тут уже возникает вопрос безопасности - очевидно, что серверная часть клиента более способна хранить секреты, в отличие от браузера, и тут появляется смысл в refresh token который хранится только на сервере, который использует его для выдачи access token для браузера/мобильного приложения.

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

API в API это как? :) Если речь о коммуникации между нашими собственными сервисами, то там удобнее использовать mTLS а не токены. Если речь о коммуникации между нашим и сторонним сервисом то придётся делать так как требует сторонний сервис.

Ага, это сервис к сервису) про mTLS что-то видел, когда istio подключали, но мы пока от этого комбайна только рутинг используем, надо посмотреть внимательнее. Спасибо!

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

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

Sign up to leave a comment.

Articles