Как стать автором
Обновить
16
11
Олег Стрекаловский @OlegStrekalovsky

Backend программист

Отправить сообщение

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

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

Про логирование выбросов вы правильно подметили. Логи и метрики с отдельными метками для ошибок очень помогают разбираться в неоднозначных ситуациях. Наша платформа предоставляет нам отдельные графики с RT для всех типов неуспешных запросов.

Очень странный кейс в духе: "Представим, что специализированных кэшей не существует, у нас бесконечно много денег. Вытянут ли базы данных нагрузку, если их использовать как кэш". Никакого экономического анализа целесообразности такой замены нет. Что там с latency ответов в обоих сценариях? Использовался ли pipelining для redis-like кэшей?

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

Идея структурного дизайна конечно имеет право на жизнь. Но это всё покрывает только примитивные программы, типа CRUD (хоть с тысячей ручек), где самая главная проблема - это отделить io, чтобы проще писать тесты. Что делать с программами, где появляются очень большая вариативность (тот же пример "Охота на хампуса" из "Чистой архитектуры"), что от чего должно зависеть, чтобы программа была расширяемая - на все эти вопросы этот подход ответа на даёт. DDD и Чистая архитектура, были представлены существенно позже Structured Design и они пытались дать ответы для более масштабных программ. Просто ли применять более сложные подходы - нет, и в этом я соглашусь с автором. Но это совсем не значит, что нужно скатываться в такой примитивизм из 60ых годов вне зависимости от задачи.

Можете хотя бы словами описать как вы эти проблемы решали? Это достаточно важные детали, чтобы даже этот более простой пример саги, когда можно положиться на надёжный транспорт сообщений, стал более похож на то, что можно реально использовать.

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

Теперь DoDo узнали где ещё можно хантить .Net разработчиков, которые ещё и с их областью деятельности знакомы :)

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


Так в этом и сложность DDD, что надо с одной стороны обеспечить изоляцию поддоменов, с другой — не нарушить инварианты всех агрегатов, а с третей — не просадить в ноль производительность. Вы же срезали кучу углов видимо в погоне за тем, чтобы назвать это DDD, но он и близко так не делается. Ваша статья — это просто какой-то пример реализации. Методологически она скорее вредна тем, кто подумает «так вот как DDD делать надо».

Приведите хоть один практический совет по реализации из книги, который не вписывается в эту архитектуру


Большие графы объектов похоронят вашу производительность при таком подходе. Ну либо производительность вам совсем не важна, тогда и обсуждать тут нечего.

В этом примере также типичные антипаттерны типа анемичной модели, из-за чего логика работы объекта полностью переезжает в ваш слой «бизнес процессов» и появляется low cohesion со всеми вытекающими, вследствие чего смысла в отдельных доменных объектах практически не остаётся.

Вы очень поверхностно поняли смысл DDD и почему его авторы рекомендуют именно те подходы, которые помогают делать поддерживаемый код при автоматизации сложных бизнес процессов. Если вам всё это влом понимать — так не надо себя мучать. Сделайте CRUD и если оно заработает для вашей задачи — ну и замечательно. DDD имеет высокий порог входа и имеет смысл только в реально сложных областях, когда CRUD справляться с ними перестаёт.
Я не понял, почему вы считаете, что ваша логика «не замкнута в гексагон». Вы тут по сути только добавили ещё один круг бизнес процессов (что в книге Вон Вернона тоже есть) и больше никаких отличий от каноничного способа реализации DDD я не вижу. Действительно важная проблема — вы тут не выделяете агрегаты и позволяете себе атомарно выполнять действия над разными сущностями не только одного, но и разных доменов. Будь у вас более сложная модель данных в базе — это бы вышло боком по из-за неминуемых проблем с производительностью. Я бы всё-таки порекомендовал вам почитать книгу Вон Вернона. Она хоть и большая, но в ней даны многие практические советы по реализации DDD, чтобы вы своим велосипедом по граблям не катались.
Смысл гексагональной архитектуры только в том, чтобы направления зависимостей были только «внутрь кольца». А вот каноничная многоуровневая архитектура — это когда все зависимости идут строго в одном направлении, и это совсем не так, как у вас. Важно понимать, что в обоих архитектурах по сути действия идут снаружи до базы и обратно, но именно в гексагональной архитектуре направление зависимостей и направление потока данных не совпадает — это и есть dependency inversion. И именно это свойство отличает гексагональную от уровневой.
Иногда Ops-ы вешают мониторинг 5xx ошибок на корневом балансере в попытке быстро понимать, когда что-то перестало нормально отвечать. Этакий ультимативный способ понимать, что что-то случилось, когда нет более гранулярного способа детектировать проблемы на уровне самих обработчиков запросов (особенно когда за балансером стоит их целый каскад). Если разработчики введут использование 5xx кодов как нечто нормальное, то Ops-ы будут часто тригериться на эти false positive. В прекрасном будущем, когда везде будет devops и плоская иерархия команд, отвечающая за прод и никакого верхнеуровневого мониторинга не потребуется, разработчики наверно смогут использовать любые коды, которые им понравятся. Но даже тогда если вы захотите реализовать внешний «планетарный мониторинг» вашего сервиса, то специализированные сервисы, которые будут «обзванивать» ваш прод, вряд ли оценят отдачу 5xx вместо 2xx, когда проблем у сервиса нет.

Не стоит использовать 5xx в штатных сценариях, т.к. часто на эти коды вешают какой нить высокоуровневый алертинг по умолчанию. Ops-ы вас проклянут за такое.

А не проще зайти с другой стороны и просто уведомлять админа, когда софт не может выполнить команду удалённого отключения пользователя (можно даже периодически чекать удалённую систему, что компьютер реально заблокирован, когда он и должен быть заблокирован)?
Если трендюлей за взлом не может выписать софт — их всегда сможет выписать админ :)
Предвосхищая статью про собственную реализацию OAuth сервера — смотрели ли на готовые реализации типа Keycloak?
Неплохой подход к решению этой проблемы был предложен в докладе Николая Алименкова
Modern CI/CD in the microservices world with Kubernetes
Часто оплачиваю в терминалах счета за ЖКХ с помощью штрих-кода. Именно в терминалах, а не в приложении, т.к. нужен нормальный чек. При этом приложение посчитало, что это чертовски популярная операция. И его не смутил тот факт, что через приложение я это никогда не делал. Но теперь это топ1 рекомендация в нём. WAT?!
А если заказчик будет использовать ваше API для облака? Он должен будет сам хранить у себя оригиналы и самостоятельно миграцию проводить прогоняя все свои оригинальные фотографии повторно?
И что такое «скрипт подбора»?

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

Каким образом вы проводите миграции в своей системе?
Например выходит новый алгоритм сравнения лиц и вам надо пересчитать вектора признаков по фотографиям детектов — всегда ли ваш детект совместим с модулем корреляции? Вы храните оригиналы фотографий в системе или только обрезанные лица?
Каким образом после миграции вы пересчитываете кастомные пороги на инсталляциях?
Что насчёт ситуаций, когда пользователи сидят за NAT? Особенно когда эти пользователи ещё и знают друг друга (например сотрудники одной организации или какого-то небольшого интернет провайдера)
1

Информация

В рейтинге
582-й
Откуда
Вологда, Вологодская обл., Россия
Дата рождения
Зарегистрирован
Активность

Специализация

Backend Developer
Senior
Golang