dprdev блог: мысли о .net и архитектуре
198 subscribers
2 photos
6 links
Всякое об IT, технологиях, архитектуре, рабочих моментах и факапах

.net, c#, architecture, microservices, databases, devops, apache kafka и прочее зло в наличии
Download Telegram
Коротко о главном: максимально субъективный взгляд на IT, технологии и архитектуру

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

Welcome в dpr/dev space !

PS: (токсичным) Желающим похоливарить про кафку тут всегда рады.


Полезные теги для поиска

#orchestration
#distributed_transactions
#temporal
#security
#auth
#dotnet
#efcore
#db
#db_design
#dwh
#system_design
#api_design
#infrastructure
🌭2🎃2
Наблюдая извечные холивары о том, что такое МСА, когда нужно применять МСА, чем МСА лучше монолита, становится немного грустно: к сожалению, многие люди тотально не понимают двух вещей
1) довольно большое количество людей было введено в заблуждение относительно многих вещей, касающихся МСА
2) довольно немногие в действительности понимают, когда и зачем нужно декомпозировать монолит на разные деплоймент-юниты (сервисы. в привычной для всех терминологии)

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

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

Глядя на все это, давно посещает мысль написать цикл статей на эту тему.
Возможно, начну со скейлинга (или очередного определения мса 🙈)
#temporal
#distributed_transactions
#orchestration

Temporal: Введение. Часть 1

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

Естественно, такие преимущества, как персистентность шагов, восстановление после сбоев (DR), высокая скорость исполнения и прочее — все это присутствует. Почитать можно здесь.

Сам Temporal состоит из нескольких ключевых компонентов:

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

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

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

Temporal: Введение. Часть 1
👍2
dprdev блог: мысли о .net и архитектуре pinned «Коротко о главном: максимально субъективный взгляд на IT, технологии и архитектуру Тут могут быть - различные истории из рабочего опыта - интересные подходы и нюансы, которые могут мне повстречаться - описания жирных факапов прямо с прода Welcome в dpr/dev…»
#api_design
#system_design

Дизайн API: Как быть, когда есть множество потребителей

Хотя я начал писать о Temporal, решил отвлечься на другую тему, которая с ним мало связана: дизайн API.

В предыдущей статье о Temporal мне задали несколько вопросов о непонятном атрибуте в названии URL, который встретился в тексте прошлой статьи [HttpPost("system.clients.startUserGrantedWorkflow")]. Вопрос был вызван наличием группы system в URL адресе.

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

Дизайн API: Как быть, когда есть множество потребителей
🔥4
скомпилировал статьи в блог на github pages, теперь читать будет проще
🔥7
вот и первое падение в проде: окно даунтайма публичных ссылок составило почти 2 часа, исчерпав почти годовой лимит :(

алертинг в виде подписчиков отработал штатно
😁4👍2👏1
Давно ничего не публиковал / писал: с головой утонул в работе. Сейчас, вроде как, немного разгрузился.
Решил воспользоваться помощью чата: накидайте, пожалуйста, тем в комменты, что интересно было бы обсудить и, возможно, почитать в какой-то небольшой статье (архитектуры, требования, mediatr, smth else)
Как насчет работы с jsonb в EF Core для постгрес провайдера, организации структуры БД, подводных камней и некоторых атипичных задач, вроде шифрования данных, версионирования и миграций, concurrency или индексации ?
🔥11👍3
К сожалению, статья немного задерживается (

Объем получается довольно большим (с учетом примеров), да и некоторые набитые шишки (например, с mutable операциями при создании computed stored columns по tstz типам) не сразу вспомнить удается :)

Постараюсь на этих выходных добить
👍6
#ef_core
#db_design
#postgresql

Тонкости JSONB в PostgreSQL и EF Core: Как постичь дзен?

Сегодня мы рассмотрим работу с JSONB в базе данных PostgreSQL совместно с родной для .NET ORM от Microsoft — Entity Framework Core.

Мы разберём, как удобно хранить данные в денормализованном виде, как защититься от параллельных изменений и как поступать, когда необходимо выстраивать отношения между сущностями, чьи атрибуты упакованы в JSONB. Помимо этого, мы затронем такие темы, как optimistic concurrency, data encryption, миграции подобных сущностей и их версионирование.

Итак, начнём.

Тонкости JSONB в PostgreSQL и EF Core: Как постичь дзен?
👍8🤯2🎉2🔥1
ну, что, как насчет того, чтобы пойти в deep dive темы и поговорить о реализации динамических конфигураций (с перезагрузкой в рилтайме) в .net, подгружаемых из сервиса бизнес конфигов ?

накидайте лайков, если хотите об этом почитать (или свои варианты в комменты)



Кстати, в предыдущей статье о JSONB забыл написать о довольно важной теме: миграции с property converter на owned entities

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

Если вы не использовали хитро-выдуманных настроек сериализаторов, то просто изменяете HasConversion на Owns(One|Many) и всё, попутно разметив enum (если нужно) и добавив новую миграцию (dotnet ef migrations add)

Если же вы использовали какие-то кастомные настройки, то тут уже может быть сложнее. Возможно, многие проблемы решатся через конвертеры уже на конкретных свойствах внутри OwnsOne/Many, но если нет, то придется пилить мигратор (с помощью IHostedService) и бампить версию схемы

Поэтому рекомендую не извращаться с кастомными конвертерами, чтобы не было больно в будущем. Или сразу идти в owned entities
🔥12👍3
Понял одно: порядок и последовательность не для меня

Вторая статья из цикла про temporal на подходе. На этот раз поговорим о workflow versioning :)
🔥5💯1
Сегодня наблюдал довольно интересную дискуссию о том, какой крутой argocd. Действительно, инструмент интересный, модный и молодежный (к сожалению, забивающий на целый ряд задач, которые не ложатся в gitops парадигму, но кому это важно, верно ?).

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

Если кто узнал себя (точно знаю, что есть пара таких человек), - делитесь опытом в комментариях.


У нас тут в команде очень крутая кул-стори достигла своей кульминации. Вчера начались проблемы с инфраструктурой.

Argo вдруг «сошёл с ума» (отвалилась кукуха): каждые 30 секунд он пересоздавал NEG между Load Balancer и кластером GKE. Ситуация усугублялась тем, что в чат посыпались многочисленные ошибки 502 и начали отваливаться некоторые клиентские запросы (вывозили на ретраях). Мы решили временно отключить Argo и принялись искать первопричину. В итоге выяснилось, что (сами себе буратино, тк. пропустили анонс) гугл обновил апи asm ingress и арго начал постоянно реконсилировать манифесты, пересоздавая NEG-и

Давно собирались переделать старый ASM Ingress на новый GKE Gateway (там завезли кучу крутых плюшек). Казалось бы, под такой повод - сам Бог велел, поэтому решили в т.ч. обновить инфру на GKE Gateway в рамках фикса существующего ASM Ingress.

Сказано — сделано: за три часа переписали манифесты. Развернули всё на стейджинге — даунтайм составил около 15 минут (в основном из-за нового провиженинга сертификатов). Это было терпимо, хотя и неприятно. После успешного обновления Staging решили перенести изменения на прод утром по московскому времени, чтобы минимизировать влияние на пользователей.

Начали выкатывать обновление: прошли уже те самые 15 минут, потом 20, 30, — а сервис так и не заработал. Нервозность нарастала, хотя масштаб беды мы ещё не до конца понимали.
Попробовали повторно установить всё (с полным удалением Ingress и пересозданием его в Argo), но это не помогло. Спустя ещё 15 минут инфраструктура всё равно ругалась на то, что трафик из LB не может попасть в кластер через NEG.

Тут полезли в VPC Flow logs: поняли, что проблема, скорее всего, в настройках Firewall. С ASM Ingress GKE автоматически создавал нужные правила, а с новым GKE Gateway — нет.

Зачесали репу, пытаясь ответить на несколько вопросов:
- Почему на стейджинге всё заработало (ведь инфраструктура через IaaC и полностью идентична) ?
- Что теперь делать с продом ?

Первый вопрос временно оставили «на потом», а по второму решили следовать документации: вручную создать нужные правила для Firewall. Необходимо было учесть диапазоны IP адресов от Google LB, порты HealthCheck и IP-адреса нод. Возник закономерный вопрос: как?
Как обычно, гуглим и видим, что можно на ноды навесить кастомные сетевые теги.

Окей, без проблем. Добавили несколько строк в Terraform и решили протестировать на стейджинге. Запустили — и тут оказалось, что это «мутирующее» изменение в корне меняет конфигурацию: удаляет весь кластер и разворачивает его заново. В воздухе повис вопрос: «Ребята, а что с лицом ?»

После короткой тишины прозвучала фраза: «***, давайте откатывать прод».

15 минут — прод откачен к старой инфре, всё заработало. Изначальная проблема не решена: NEG-и всё ещё пересоздаются каждые 30 сек. argo мы-то по итогу вырубили, а вот стейдж восстанавливать примерно часа 4...



Естественно, тут наложилось множество проблем (и реконсиляция с арго, и наше решение обновлять инфру, и какая-то магия на полностью эквивалентных средах с простановкой рулов FW, и отсутствие deletion protection на кластере, и тд), но уж очень неприятный осадочек остался от этой истории (

Переехали по итогу на классический CI/CD. Зато ещё и на инфраструктуре довольно неплохо начали экономить

PS: Морали не будет
🔥8
🚀 Эксперимент: предлагайте темы для статей!

Пока моя статья о Temporal still in progress (но готово примерно 80%), у меня появилась идея.

Поскольку блог теперь работает на GitHub Pages, я решил провести небольшой эксперимент: добавил issue template в репозиторий блога, чтобы любой желающий мог предложить тему для следующей статьи.

🔗 Как предложить тему?
Просто создайте issue в репозитории:
👉 GitHub Issues – Предложить тему

Not sure if this will work, but let's try

Буду рад любым идеям и фидбеку
🔥8
#temporal
#distributed_transactions
#orchestration

Ухххх. Мне самому не верится, но я-таки нашел пару свободных часов и дописал то, что обещал дописать несколько месяцев назад :)


Temporal: Intro. Часть 2: workflow versioning

В этой статье мы продолжим говорить о Temporal, а именно о том, какие подходы существуют для версионирования temporal workflow.

Погнали:

Temporal: Intro. Часть 2: workflow versioning
🔥9
#temporal
#system_design
#requirements

Так-с, ну вот ещё одна :)

Несмотря на то, что в заголовке фигурирует Temporal, это не совсем статья про Temporal. Это материал про проектирование систем. Про то, как превратить неструктурированные хотелки в формальные требования, не потерять здравый смысл по пути, заложить архитектурный фундамент и не пожалеть об этом через месяц. Ну и спроектировать workflow на Temporal, конечно же :)

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

Интересно будет узнать в комментариях, насколько такой стиль заходит. Особенно от тех, кто осилит статью до конца (а статья получилась довольно большой, пришлось даже ужимать - надеюсь, что не в ущерб качеству) :)



📖 Часть 1 — «Анализ требований» — уже доступна:
Temporal: Deep Dive. От требований до workflow: проектируем биллинг с оркестрацией.


В этой статье мы отойдём от абстрактной теории и наконец-то займемся чем-то интересным. Вместо обсуждения надуманных примеров, мы возьмём вполне реалистичную задачу для огромного количества (не финтех) компаний — обработку платёжных транзакций. Вместе мы попробуем пройти весь путь: от первых продуктовых обсуждений до готовой системы, часть которой реализована с помощью Temporal Workflow.

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

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

Готовы? Поехали!
🔥142
dprdev блог: мысли о .net и архитектуре
#temporal #system_design #requirements Так-с, ну вот ещё одна :) Несмотря на то, что в заголовке фигурирует Temporal, это не совсем статья про Temporal. Это материал про проектирование систем. Про то, как превратить неструктурированные хотелки в формальные…
Собрал супер ценные комментарии от различных людей сразу из нескольких чатов (и относительно ЦА, и относительно подачи, и относительно некоторой базы + скоупа с целеполаганием). Всем спасибо.

Будет статья-hotfix :)
👍52