Архитектура Стартапа - Anton Skogorev Engineering & AI – Telegram
Архитектура Стартапа - Anton Skogorev Engineering & AI
2.1K subscribers
49 photos
1 video
2 files
109 links
Канал про архитектуру быстрорастущего бизнеса.

Привет, меня зовут Антон @skogorev.
Я - Технический Директор AI Center Tinkoff, ex Yandex Go Senior EM.

В переписках остается много полезных материалов, теперь я собираю их на этом канале.
Download Telegram
Code review checklist for distributed systems
https://medium.com/swlh/code-review-checklist-for-distributed-systems-b3fb94be5bfa

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

При межсервисных запросах:

Что делать, когда запросы во внешний сервис возвращают ошибку?
— иметь ветвь обработки ошибки
— иметь сценарии восстановления после ошибки
Что делать, когда внешний сервис недоступен?
— всегда ставить таймауты на запросы
— делать какое-то явно определенное число перезапросов
— использовать circuit breaker
— не обрабатывать таймауты как ошибки

При построении сервиса, который другие сервисы будут использовать:

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

Общие рекомендации:

— более агрессивно кэшировать
— определить единицу сбоя при ошибках
— инкапсулировать внутренние структуры сервисов и не размазывать их по системе

https://medium.com/swlh/code-review-checklist-for-distributed-systems-b3fb94be5bfa

#practices #article #microservices #en
How Discord Handles Two and Half Million Concurrent Voice Users using WebRTC

https://blog.discord.com/how-discord-handles-two-and-half-million-concurrent-voice-users-using-webrtc-ce01c3187429

В сегодняшней статье от 2018 года команда мессенджер Discord рассказывает про архитектуру их сервиса. Интересно с точки зрения архитектурного кейса организации коммуникации между пользователями.

Статья тезисно:
— Для клиент-серверной коммуникации используется свой собственный фреймворк поверх WebRTC.
— Бэкенд построен на трех китах - Discord Gateway, Discord Guilds и Discord Voice. Клиенты общаются с бэкендом через Discord Gateway. Discord Guilds отвечает за оркестрацию каналов общения по Voice серверам, сам Discord Voice используется непосредственно для обмена контентом между клиентами.
— Guilds серверы для каждого нового пользовательского канала с помощью того же service discovery выбирают наименее загруженный ближайший к пользователю Voice сервер.
— Voice серверы с помощью service discovery репортят свой статус и текущую нагрузку на сервер (используется etcd).
— Клиентам, подключаемым к бэкенду сообщается адрес Voice сервера, на котором живет канал и к которому будут подключаться пользователи.
— Во время отказа Voice сервера, на котором живут каналы, он перестает отправлять свой статус в service discovery, клиенты при этом уведомляются, что сервер недоступен . Guilds сервер выбирает для канала новый Voice сервер, нотифицирует всех клиентов и канал успешно переезжает на другой хост.
— Такая архитектура позволяет достаточно неплохо масштабироваться и распределять нагрузку. На момент написания статьи Discord состоит из 850 Voice серверов в 13 регионах, которые передают более чем 220 Gbps.

#practices #article #startup #en
API Composition
https://microservices.io/patterns/data/api-composition.html

Сегодня достаточно простой, но очень полезный паттерн.
Создавая микросервисную архитектуру и соблюдая стратегию database per service, вы оказываетесь в ситуации, где для того, чтобы собрать даже самый простой, скажем, ответ для клиента, вам требуется сделать запрос в 3, 5 или даже 7 микросервисов. Такую функциональность вам, возможно, нужно даже иметь не в одном месте в коде.

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

#pattern #microservices #practices #doc #en
Как мы в Dropbox перешли с Nginx на Envoy

В конце прошлой недели вышла статья о том, как Dropbox перешел с Nginx на Envoy и стал одним из самых больших пользователей Envoy в мире. Значимое событие в индустрии.

Оригинальная статья: https://dropbox.tech/infrastructure/how-we-migrated-dropbox-from-nginx-to-envoy
Перевод: https://habr.com/en/company/southbridge/blog/513504/

#practices #article #backend #highload #ru #en
Безопасность REST API от А до ПИ

Тема, о которой иногда нужно напоминать самим себе — это безопасность. В сегодняшние статье таких напоминаний достаточно много. Автор рассматривает опасные уязвимости при разработке API. О некоторых из них коротко в этом посте:

Недостатки аутентификации пользователей — API2:2019 Broken User Authentication.
Три вида: API key, Basic Authentication, Cookie-Based Authentication, Token-Based Authentication. Рекомендуют использовать последний с access token и refresh token.

Недостатки контроля доступа к объектам — API1:2019 Broken Object Level Authorization.
Все просто. Доступ до вызова DELETE /users/anton должен иметь только пользователь anton или специальная роль, например, "администратор". Если отдаются непубличные данные по ссылке, то ссылку должно быть тяжело подобрать.

Разглашение конфиденциальных данных — API3:2019 Excessive Data Exposure.
Предоставление излишних данных. Например, метод GET /user/anton возвращает ответ на секретный вопрос для восстановления пароля.

Небезопасная десериализация — API6:2019 Mass Assignment.
Недостаточный контроль за входными параметрами. Например, пришедший в запросе json парсится на все поля и они апдейтятся в базе данных. Таким образом, в методе изменения пользователя POST /user/anton можно передать дополнительный атрибут balance и изменить баланс пользователя.

Отсутствие проверок и ограничений — API4:2019 Lack of Resources & Rate Limiting.
Необходимо защитить API от подбора, например, с помощью rate limiter.

Внедрение — API8:2019 Injection.
Подразумевают возможность передать в API параметры, которые выполняются как SQL запрос или команда ОС. Например, метод GET /user/{id}, который внутри делает запрос в базу данных "SELECT FROM USERS WHERE ID={id}" можно использовать как GET /user/1;%20DROP%20TABLE%20USERS и получить смертельный запрос "SELECT FROM USERS WHERE ID=1; DROP TABLE USERS"

Недостатки управления API — API9:2019 Improper Assets Management.
Имеется в виду необходимость контролировать версионность вашего API. В production должны быть доступны только те версии API, которые должны там быть.

Недостатки журналирования и мониторинга — API10:2019 Insufficient Logging & Monitoring.
Речь про то, что нужно мониторить те части системы, что могут пробовать взломать. Например, неудачные попытки авторизации.

Небезопасный транспортный уровень — Insecure Transport.
Передача с помощью HTTP там, где обязательно нужно использовать HTTPS.

Небезопасные пароли — Insecure Passwords.
Не давать задавать небезопасные пароли, не хранить в открытом виде, использовать надежное хэширование.

Небезопасные Cookies и данные в Local Storage — Insecure Cookies and Local Storage.
Нужно помнить, что данные Cookies доступны пользователю. Лучше хранить только служебную информацию.

Использование компонент с известными уязвимостями — Using Components with Known Vulnerabilities.
SDK, frameworks, код с github. Нужно понимать, что сторонние компоненты могут содержать в себе уязвимости.

Межсайтовое выполнение скриптов — CWE-79 Cross-site Scripting (XSS).
Это когда можно вызвать GET /user/<noscript>alert("hacked")</scipt>. Фронтенд попробует написать, что пользователь не найден и на рендеринге исполнит вредоносный скрипт в браузере пользователя.

Межсайтовая подмена запросов — CWE-352 Cross-Site Request Forgery (CSRF).
Предположим, есть финансовая организация с онлайн кабинетом. В Cookies запоминается пользователь, чтобы при входе ему не надо было каждый раз вводить свой логин/пароль. Пользователь случайно заходит на сайт злоумышленника, который отправляет в финансовую организацию транзакцию на перевод денег, в которую браузер автоматически помещает данные из запомненных Cookies.

Кросс-доменное использование ресурсов — Cross-origin resource sharing (CORS).
Можно явно укзаывать поддерживаемые HTTP методы, заголовки и URL, на которых можно вызывать методы API: Access-Control-Allow-Origin: https://example.com:8080

https://habr.com/ru/post/503284/

#article #backend #api #highload #ru
Инцидентный менеджмент или shit happens.
https://medium.com/@AlertOps/the-ultimate-guide-to-incident-management-88b012047a39

В компании, какого бы размера она не была, нужно уметь выносить уроки из произошедших инцидентов (где под инцидентом обычно подразумевают непредвиденные события в сервисе, от которых пострадали пользовательские сценарии, или просто — "страдают пользователи"). Процесс работы с инцидентами называется инцидентным менеджментом.
Кстати, не так давно я писал о об опыте сервиса Ситимобил работы с инцидентами, достаточно интересное чтение.

Мое мнение, что инцидентный менеджмент должен строиться на следующих принципах:
— Когда страдают пользователи, нужно не тратить время на поиск виноватых, а пустить силы на быстрое устранение проблемы.
— Когда происходит инцидент, нужно оценить масштаб трагедии, желательно в количестве пользователей или деньгах. Эта оценка вам даст понимание как конкретно чинить и какими методами. Иногда достаточно в рабочем режиме выкатить релиз с исправлением, а иногда можно и перезагрузить бэкенд с даунтаймом.
— Когда проблема устранена, нужно принять меры для того, чтобы этого больше не повторилось. Обычно в таск-менеджере создается инцидентный таск, который заполняется подробным логом того, что произошло. Нужно на свежую голову ответить на главный вопрос - что мы сделаем, чтобы в будущем этого не повторилось? Ответы на этот вопрос нужно заводить в виде связанных задач.
— Расскажите о ней. Как инструмент прозрачности можно использовать, например, ежемесячные репорты.
— Не вините людей. Часто инцидент — результат стечения многих обстоятельств. Не нужно взгружать кого-то конкретного, это не та культура, которую вы хотите иметь в команде.

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

https://medium.com/@AlertOps/the-ultimate-guide-to-incident-management-88b012047a39
https://medium.com/swlh/incident-management-process-5655ba586cf4
https://www.atlassian.com/incident-management/itsm

#practices #managment #backend #highload #en
btw, Канал не под NDA, в него можно приглашать абсолютно всех по ссылке: https://news.1rj.ru/str/startup_architecture
Можно также поддержать лайком или поделиться постом в FB: https://fb.com/antonskogorev/posts/2398716847093667
Ну а обсудить материал в связанном с каналом чате: https://news.1rj.ru/str/joinchat/CAd00lDH88dDo_Bjkjo5xA
DDD (Domain driven design) или предметно-ориентированное проектирование.

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

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

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

Одна из самых сложных задач тут — определиться с набором ограничений домена, который называется Bounded context. Про него в следующий раз.

https://medium.com/walmartglobaltech/building-domain-driven-microservices-af688aa1b1b8
https://habr.com/ru/post/428209/
https://martinfowler.com/bliki/BoundedContext.html

Стоит также посмотреть на каноничные труды по Domain Driven Design — книгу Эрика Эванса https://www.ozon.ru/context/detail/id/5497184/

#practices #ddd #microservices #en
DDD Strategic Patterns: How To Define Bounded Contexts

Главные принцип микросервисной архитектуры - слабая связанность и сильное сопряжение. DDD нацелен на достижение этого критерия и одна из ключевых концепций здесь - ограниченный контекст или bounded context.

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

https://codeburst.io/ddd-strategic-patterns-how-to-define-bounded-contexts-2dc70927976e
http://blog.sapiensworks.com/post/2012/04/17/DDD-The-Bounded-Context-Explained.aspx
https://martinfowler.com/bliki/BoundedContext.html

#practices #ddd #microservices #en
Давайте соберем статистику и закроем тему. Вы практикуете DDD?
Anonymous Poll
20%
Да
44%
Нет
36%
Не знаю
Things I Wished More Developers Knew About Databases

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

— Вам повезло, если 99.999% времени нет проблем в сети
— ACID имеет много значений
— Каждая DB имеет разные возможности consistency и isolation
— Оптимистичная блокировка — это вариант, когда вы не можете взять обычную блокировку
— Есть аномалии помимо грязных чтений и потери данных
— Моя база и я не всегда согласны с порядком элементов
— Шардинг на уровне приложения может жить вне приложения
— AUTOINCREMENT может быть вредным
— Устаревшие данные могут быть полезными и lock-free
— Между любыми источниками синхронизации происходят расхождения времени.
— Lantency имеет много значений
— Оцените требования к перформансу каждой транзакции
— Вложенные транзакции могут быть вредными
— Транзакции не должны поддерживать состояние приложения
— Query planners могут сказать много о базах данных
— Онлайн миграции сложные, но возможные
— Значительный рост базы приводит к непредсказуемости

https://medium.com/@rakyll/things-i-wished-more-developers-knew-about-databases-2d0178464f78

#article #databases #medium #en
Books in Software Architecture
https://medium.com/@nvashanin/books-in-software-architecture-6ad974e524ce

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

🥇 Software Architecture in Practice (3rd Edition) (SEI Series in Software Engineering) - Len Bass, Paul Clements, Rick Kazman
🥈 Essential Software Architecture - Ian Gorton
🥈 Patterns of Enterprise Application Architecture - Martin Fowler
🥇 Domain-Driven Design: Tackling Complexity in the Heart of Software - Eric Evans
🥇 Stakeholder Theory: The State of the Art - R. Edward Freeman, Jeffrey S. Harrison, Andrew C. Wicks, Bidhan L. Parmar, Simone de Colle
🥈 Applying UML and Patterns: An Introduction to Object-Oriented Analysis and Design and Iterative Development - Craig Larman
🥈 Documenting Software Architectures: Views and Beyond - Paul Clements, Felix Bachmann, Len Bass, David Garlan, James Ivers, Reed Little, Paulo Merson, Robert Nord
🥉 Software Systems Architecture: Working With Stakeholders Using Viewpoints and Perspectives - Nick Rozanski, Eóin Woods
🥈 Designing Software Architectures: A Practical Approach (SEI Series in Software Engineering) - Humberto Cervantes, Rick Kazman
🥇 Software Estimation: Demystifying the Black Art - Steve McConnell
🥇 Site Reliability Engineering- Betsy Beyer, Chris Jones, Jennifer Petoff, Niall Richard Murphy
🥉 Enterprise Architecture As Strategy: Creating a Foundation for Business Execution - Jeanne W. Ross, Peter Weill, David Robertson
🥉 Designing Data-Intensive Applications: The Big Ideas Behind Reliable, Scalable, and Maintainable Systems - Martin Kleppmann

#books #medium #en

https://medium.com/@nvashanin/books-in-software-architecture-6ad974e524ce
Что же такое этот GraphQL?
https://www.freecodecamp.org/news/so-whats-this-graphql-thing-i-keep-hearing-about-baf4d36c20cf/

GraphQL — это язык запросов, разрабатываемый компанией Facebook, зарелизившийся на широкую аудиторию в 2015 году и стремительно набирающий популярность последние несколько лет.
Обычно, его рассматривают как альтернативу REST API для взаимодействия разных компонентов вашей архитектуры.

Простой запрос на GraphQL
 {
posts { # this is an array
noscript
body
author { # we can go deeper!
name
avatarUrl
profileUrl
}
}
}

Основная его особенность и отличие от REST в том, что вам не нужно иметь много разных endpoint'ов, чтобы получить все нужные данные. Интерфейс позволяет иметь единственный endpoint для всего, а клиенты самостоятельно запрашивают только ту информацию, которая им нужна.

Но тогда возникают слишком тяжелые endpoint'ы?- спросите вы. В REST подобную проблему можно было бы решить в помощью API Composition. GraphQL предоставляет инструмент резолверов.

Resolvers позволяют сматчить поля в запросе GraphQL на непосредственные фетчеры этих полей. Фактически, это функции, которые дают понять где и как найти те данные, которые запрашивает клиент.

Пример резолверов
 {
post(root, args) {
return Posts.find({ id: args.id });
}
},
Post: {
author(post) {
return Users.find({ id: post.authorId})
}
}

Это может быть поход в базу данных или даже запрос в сторонний сервис.

#graphql #microservices #practices #rest #en #ru

https://www.freecodecamp.org/news/so-whats-this-graphql-thing-i-keep-hearing-about-baf4d36c20cf/
(перевод: https://habr.com/en/post/326986/)
https://medium.com/free-code-camp/why-graphql-is-the-future-of-apis-6a900fb0bc81
https://itnext.io/graphql-in-a-microservices-architecture-d17922b886eb
🧑‍🚀
Сегодня Святослав Фельдшеров рассказывает о разработке альтернативной вселенной микросервисов в поиске Яндекса. Он напомнит 6 основных проблем традиционной микросервисной инфраструктуры, решение которых и привело нас к технологии Apphost.
11 причин почему вы можете потерпеть неудачу с микросервисами

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

1. Менеджмент недооценивает сложность разработки микросервисов (камнем преткновения становится сложность поднятия разных частей проекта для локальной разработки)
2. Нет процесса обновления библиотек и инструментов до последних версий
3. Использование общих (коммунальных) сервисов для разработки
4. Недостаточность визибилити структуры микросервисов в системе контроля версий
5. Нет четкого определения что такое микросервис
6. Нет четкой стратегии по переиспользованию кода
7. Нет явного ограничения в используемых технологиях
8. Зависимость между людьми (команды сильно фокусируются только на своих частях и никто не смотрит на общую картину)
9. Отсутсвие документации
10. Функциональность важнее платформы
11. Отсутсвие автоматического тестирования

https://medium.com/xebia-engineering/11-reasons-why-you-are-going-to-fail-with-microservices-29b93876268b

#article #practices #medium #en
Знакомство с Greenplum
Попалась неплохая открытая вводная лекция про базу данных для аналитики на основе PostgreSQL - Greenplum.
Понятно рассказывается про то, что такое аналитические MPP базы данных, как с их помощью строят Data Lake (с примерами из Uber и Avito), и как построена архитектура таких БД на примере Greenplum.

https://www.youtube.com/watch?v=qpwA1z3s4uA
и чуть более сложно про внутреннюю архитектуру: https://www.youtube.com/watch?v=k9ckMfD-qf4

#video #mpp #greenplum #datalake #ru
Глубокое погружение в индексы MongoDB
https://medium.com/swlh/mongodb-indexes-deep-dive-understanding-indexes-9bcec6ed7aa6

В статье про индексы MongoDB описываются некоторые базовые аспекты движка: структура данных, хранение на диске, загрузка в память. Некоторая выжимка:
Структура данных:
— B-Tree структура индексов с алгоритмической сложностью поиска O(logN).
Хранение на диске:
— Использование prefix index compression позволяет не дублировать информацию, сохраняя одинаковые префиксы только один раз.
Загрузка в память
— Индексы работают отлично только когда помещаются в память. В других случаях нужно думать про то, как правильно организовать поиск, чтобы держать на минимуме IO диска.

#database #mongodb #medium #en
CAP теорема в распределенных системах.

Осознал, что не было публикаций про такие базовые вещи, как CAP теорема. Теорема Брюера (более известная под названием CAP теорема) говорит нам о том, что в распределенной системе можно выбрать достижение не более 2 из:
- Consistency. Согласованность. (во всех узлах распределенной системы информация не противоречит друг другу),
- Availability. Доступность (любой запрос к распределенной системе завершается ответом),
- Partition tolerance. Устойчивость к разделению (расщепление распределенной системы не приводит к недоступности отдельных узлов).

https://medium.com/swlh/cap-theorem-in-distributed-systems-edd967e7bdf4
https://habr.com/en/post/328792/
https://habr.com/ru/post/258145/

#theorem #distributed #cap #medium #habr #ru #en
Event-based Microservices: обработка ошибок

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

Ошибки можно разделить на два типа:
Временные (проблемы с подключением, системные сбои)
Постоянные (баги, ошибки сериализации)
Временные ошибки можно решить простым образом — ретраями. Постоянные ошибки в основном требуют внимания человека, они должны зажечь алертинги.

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

В статье приводится два способа обработки приведенных выше типов ошибок:

Retry Events.
Основной смысл в том, что мы помечаем событие как обработанное, вынимаем его из пайплайна и прикапываем где-то в стороне как "требующее повторной обработки". Это специальное сообщение содержит всю информацию о первоначальном событии, чтобы чуть позже (например, когда сеть восстановится) его можно было легко повторить. Если после нескольких повторов сообщение не обрабатывается успешно, его стоит обработать как dead letter.

Dead letter events.
Основной смысл такой же - помечаем события как обработанные, вынимаем из пайплайна, прикапываем в стороне. При сообщения такого рода должны зажигать алертинги и привлекать людей к починке проблемы. Сообщения можно также повторить, отправив в пайплайн после устранения первоочередной проблемы.

https://medium.com/usertesting-engineering/event-based-microservices-error-handling-7c84e3cb1332
https://docs.microsoft.com/ru-ru/azure/event-grid/manage-event-delivery

#article #practices #distributed #microservices #medium #en