В больших монолитных приложениях отслеживание и мониторинг ошибок часто становятся неэффективными из-за отсутствия четкого права собственности. Данное руководство решает эту проблему, предлагая структурированный подход к назначению ответственности посредством аннотаций домена.
Настройка эффективного мониторинга для крупных монолитных компаний с участием нескольких команд может оказаться сложной задачей. Без четкого определения ответственности отслеживание ошибок становится общим и часто игнорируется. Одним из решений является поручить дежурным инженерам определить, какая группа должна реагировать на сигналы мониторинга. Однако более эффективный подход — включить информацию о домене и команде в каждый журнал и диапазон Datadog.
Чтобы отслеживать, какая команда отвечает за различные части нашего приложения, мы используем систему под названием «Аннотации домена». Аннотации домена помечают каждую часть кода вашего приложения, четко указывая, кто за что отвечает. Это обеспечивает четкую организацию и подотчетность в управлении обязанностями.
Аннотации доменов предоставляют четкий и организованный метод отслеживания обязанностей команды в монолитном приложении. Пометив части вашего кода аннотациями домена, вы можете:
Чтобы обеспечить эффективный мониторинг и отслеживаемость, каждый веб-запрос помечается соответствующей информацией о домене. Это достигается за счет сотрудничества нескольких компонентов: DomainProvider
, DomainSpanService
, DomainMdcProvider
и DomainHandlerInterceptor
.
Вот общий обзор процесса, изображенного на следующей диаграмме:
Детальная реализация этих компонентов будет инкапсулирована в общую библиотеку, предоставляющую многократно используемое решение для маркировки и мониторинга веб-запросов в крупных монолитных приложениях.
Определить право собственности на уровне класса легко с помощью аннотаций домена. Применяя аннотации верхнего уровня к основным классам, право собственности распространяется на все подробные ресурсы в этих классах. Каждая команда может помечать принадлежащие ей классы соответствующими аннотациями предметной области, обеспечивая ясность и подотчетность без необходимости отмечать каждый отдельный метод.
В случаях, когда несколько команд владеют кодом в одном классе и немедленный рефакторинг неуместен, вы можете пометить отдельные методы разными аннотациями предметной области, которые имеют приоритет над аннотациями уровня класса. Это позволяет назначать конкретные методы различным командам, обеспечивая гибкость без усложнения общей структуры.
Хотя аннотации домена невероятно полезны, в редких случаях их невозможно использовать. Например, мы столкнулись с проблемами при создании заданий Quartz, которые не работали плавно с аннотациями домена из-за конфликта между логикой АОП Quartz и логикой АОП, используемой для аннотаций домена.
Для заданий и процессов, которые нельзя аннотировать напрямую, мы использовали DomainTagsService непосредственно в реализации заданий. Такой подход позволил нам вручную добавлять теги домена в логику выполнения задания.
Вот пример того, как мы интегрировали DomainTagsService в задание Quartz:
final override fun execute(context: JobExecutionContext) { domainTagsService.invoke(domain) { withLoggedExecutionDetails(context, ::doExecute) } }
Хотя наличие отдельных сервисов для каждой команды дает значительные преимущества в мониторинге и владении, оно сопряжено с высокими затратами и усилиями по разделению монолита, а также с потенциальными дополнительными расходами на разработку. Учитывая возможность сокращения времени сборки с помощью Gradle, когда монолит разделен на модули, поддержание монорепозитория во многих случаях может быть наиболее эффективным решением.
Чтобы упростить мониторинг деятельности каждой команды в Datadog, вы можете назначить искусственные имена сервисов для диапазонов разных команд. Такой подход гарантирует, что у каждой команды будет свой собственный раздел в инструментах мониторинга Datadog. Хотя использование искусственных имен служб может сбить с толку, если вам нужно управлять многими службами, это становится управляемым при ограниченном количестве серверных служб. Добавление префиксов к этим искусственным именам сервисов помогает поддерживать организованность и ясность в настройке Datadog, упрощая различие между разными командами и их обязанностями.
использовать диаграмму вместо скриншота?? наличие рабочего/веб-приложения здесь не имеет смысла
Использование искусственных имен служб для журналов может создать путаницу, поскольку одна и та же запись журнала может появиться в разных службах.
Например, рассмотрим две конечные точки, использующие одну и ту же службу аутентификации. Если эти конечные точки помечены разными доменами, логика аутентификации будет создавать журналы для разных искусственных сервисов. Это может вызвать путаницу при просмотре журналов, поскольку они появляются под несколькими именами служб. Чтобы избежать этой проблемы, лучше применять искусственные имена служб только к диапазонам, которые объединены в трассировки, чтобы было меньше путаницы.
Имеет ли это какой-то смысл? Я не думаю, что это
Вот визуальное представление этой проблемы:
Использование искусственных сервисов позволяет не только работать со следами APM, но и фильтровать по сервисам в Datadog Metrics, которые хранятся в течение длительного периода, что позволяет отслеживать изменения в течение длительного периода.
Ниже приведен снимок экрана монитора в Datadog, который использует в запросе искусственное имя службы konsus-assets
:
Ниже приведен снимок экрана панели управления в Datadog, которая использует в фильтре искусственное имя службы konsus-assets
:
Используя поддельные сервисы в своей стратегии мониторинга, вы можете повысить прозрачность и подотчетность действий каждой команды в рамках монолитного приложения. Такой подход упрощает процесс создания и обслуживания мониторов и информационных панелей для конкретных групп, что приводит к более эффективному и организованному мониторингу в Datadog.
Аннотации домена обеспечивают простой подход к упрощению мониторинга монолитных приложений в Datadog. Реализуя эту стратегию, вы можете повысить управляемость журналов, диапазонов и метрик, превратив вашу систему мониторинга в инструмент, адаптированный для конкретных команд. Это улучшает подотчетность и организацию, а также способствует более эффективному устранению неполадок и анализу производительности вашего приложения.
DomainTagsService
, непосредственно в реализациях заданий гарантирует сохранение мониторинга, специфичного для домена.Определите домены и команды
Это изменится с появлением библиотеки!!!
Создайте перечисления, представляющие различные домены и команды вашего приложения:
@Domain
— это аннотация, которую можно применять к классам или функциям, отмечая их определенным значением домена.DomainValue
— это перечисление, представляющее различные домены, каждый из которых связан с командой.Team
— это перечисление, представляющее различные команды, работающие над приложением. @Retention(AnnotationRetention.RUNTIME) @Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION) annotation class Domain(val value: DomainValue) enum class DomainValue(val team: Team) { USER_MANAGEMENT(Team.TEAM_A), PAYMENT_PROCESSING(Team.TEAM_B), NOTIFICATIONS(Team.TEAM_C) } enum class Team { TEAM_A, TEAM_B, TEAM_C }
Аннотируйте классы (и методы, если необходимо)
@Domain(DomainValue.USER_MANAGEMENT) class UserService { @Domain(DomainValue.PAYMENT_PROCESSING) fun processPayment() { ... } }
Обработка неподдерживаемых случаев
В случаях, которые не могут быть аннотированы напрямую, используйте DomainTagsService
напрямую, чтобы обернуть логику.
fun executeNotSupportedByAnnotationsLogic() { domainTagsService.invoke(domain) { executeLogic() } }
Монитор с Datadog
Используйте искусственные сервисные фильтры для мониторов, информационных панелей и фильтрации трассировок APM.
Выполнив эти шаги, вы сможете эффективно реализовать аннотации домена в своем монолитном приложении, гарантируя улучшенный мониторинг, подотчетность и общую эффективность.