Не используйте Spring Event вслепую! Из трагедии нашей компании я обобщил 6 лучших практик!
Не используйте Spring Event вслепую! Из трагедии нашей компании я обобщил 6 лучших практик!

Привет всем, я Букай Чен~

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

Spring Платформа событий реализует механизм публикации и подписки на основе событий. Разработчики могут настраивать события и публиковать события в определенных бизнес-сценариях Spring. Событие будет транслироваться слушателям, слушающим это событие. Слушатели могут реализовать Spring Интерфейс слушателя ApplicationListenerЗарегистрируйтесь,ХОРОШОиспользовать EventListenerаннотация Зарегистрируйтесь。

Это краткое введение в Spring Event. В Интернете много обучающих программ начального уровня. Я не буду здесь вдаваться в подробности и углубляться в текст!

Расширенный веб-сайт Java: https://java-family.cn.

1. Почему говорится, что бизнес-система должна сначала реализовать плавное завершение работы служб, прежде чем использовать Spring Event?

Spring При передаче сообщения Spring будет ApplicationContext Найти всех слушателей в getBean получать bean Пример. Однако Spring Существует предел————ApplicationContext Во время завершения работы GetBean не допускается. В противном случае будет сообщено об ошибке.

Эти знания трудно получить. Это причина окончательного позиционирования нашей компании после провала онлайн-среды. На это должен обратить внимание каждый!

Несколько дней назад в онлайн-системе появились два журнала исключений. При получении компонента не удалось найти соответствующий компонент. Стек вызовов меня очень смутил. Почему Get Bean не смог найти соответствующий компонент? .

Информация в стопке объяснил причину。Do not request a bean from a BeanFactory in a destroy method implementation

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

Из-за высокого системного трафика и миллионов ежедневных заказов параллельная работа одной машины относительно высока даже в непиковые периоды, поэтому небольшой объем трафика поступает или не обрабатывается в период отключения службы. В этом сценарии, если вы используете Spring Event для публикации событий, Spring не сможет нормально транслировать событие, и обязательно произойдет исключение, приводящее к сбою обработки!

Каждый должен помнить! Перед использованием SpringEvent необходимо сначала управлять службой, чтобы при ее закрытии сначала отсекался входящий трафик (Http, MQ, RPC), а затем закрывалась служба и закрывался контекст Spring!

Подробный анализ см.:

https://juejin.cn/post/7281159113882468371

2. Почему события Spring теряются на этапе запуска службы?

Ситуация, с которой столкнулась наша компания: Kafka conumser существовать init-method стадия начинается потребление, однако Spring EventListener быть зарегистрированным в Spring момент времени отстает init-method момент времени, поэтому Kafka Consumer используется в Spring Event При публикации события прослушиватель не найден, и обработка сообщения теряется.

Как вы можете видеть на картинке ниже init-method момент времени отстающий EventListener Зарегистрированный момент времени。

Проще говоря: SpringBoot Будет ли Spring полностью запущен до открытия Httpпоток. Это дает нам вдохновение: следует ли существовать Весна После завершения запуска включите входящий трафик.Rpcи MQ-трафик Так и должно быть, поэтому предлагаю всем существовать SmartLifecype или ContextRefreshedEvent Позиция ожидания Зарегистрируйтесь на сервисе и включите трафик.

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

Какие бизнес-характеристики подходят для публикации – модель подписки

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

Для каких бизнес-сценариев подходит SpringEvent? Это определяется особенностями модели подписки-публикации.

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

Модель публикации-подписки реализует разделение модулей публикации и подписки. Однако для сценариев строгой согласованности модель публикации-подписки не подходит.

3. Сценарии строгой согласованности не подходят для модели публикации по подписке.

Бизнес с сильной последовательностью, такой как сценарий коносамента. На этапе коносамента успешный вычет запасов и коносамент успешного заказа должны быть точно такими же. Такие сценарии, как сбой вычета запасов, но успех коносамента; сбой коносамента и отсутствие отката запасов, являются ненормальными сценариями, которых следует избегать!

Сценарий коносамента, используйте Spring Событие будет иметь много проблем. Предположим, что выпуск предшествует событию перед коносаментом, а бизнес-логика подписчика события может включать такие операции, как списание запасов и блокировка ресурсов купонов. Ошибка вычета запасов. Неспособность заблокировать ресурсы требует отката всего процесса коносамента. Spring Модель подписки на события не может этого обеспечить. Исключение подписки——>откат способность.

Издатель событий не может знать, какие подписки не удалось использовать, а какие подписчики успешно? Процесс отката не может быть запущен точно. (Если вы принудительно откатите на основе события Spring, вы также можете это сделать, но решение будет очень сложным!)

4. Бизнес-характеристики конечной согласованности подходят для модели публикации-подписки.

Сценарии окончательной согласованности идеально подходят для использования Spring Events.

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

Среди подписчиков существующего успешного события,Есть только один результат выполнения — успех. Даже если случился провал,Вам также следует попробовать еще раз, пока не добьетесь успеха. Например выпускать Коносамент успешный MQ Сообщения, освобождение ресурсов, таких как блокировки коносаментов, — все это бизнес-логика, которая должна добиться успеха.

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

Если мы не используем Spring Event,Затем мне нужно вручную написать шаблон наблюдателя,И уведомить сообщение о заказе соответствующему наблюдателю в соответствии со статусом. Кроме того, всякий раз, когда добавляется новая бизнес-логика,,Мне нужно добавить группу потребителей Kafka.,И проанализировать сообщение заказа в существующем коде,Затем отправьте событие соответствующим подписчикам в зависимости от статуса. Короче говоря, мне нужно распределить событие соответствующим слушателям согласно статусу.

существуют В этой сцене используйте Spring Мероприятие очень подходящее. Каждое событие может быть инкапсулировано как Spring Event,И любую бизнес-логику можно передать@EventListenerАннотация для регистрации соответствующего статусасобытиеслушатель(Однако следует отметить, что,Если подписчиков слишком много,Тогда время потребления сообщений Kafka может увеличиться. Так как же это решить? ). использовать Spring Event Фреймворк намного лучше, чем писать собственный рукописный шаблон. прослушивателя.

5. Используйте SpringEvent, чтобы получить дополнительные гарантии надежности!

Spring Событие подходит для бизнес-сценариев, в которых необходимо обеспечить конечную согласованность, но для обеспечения надежности необходимо предоставить возможности повторных попыток. Используя applicationContext.publishEvent(event) Метод выпускасобытие, Spring будет выполнять связанных подписчиков по порядку. Если возникает исключение, publicEvent Метод выдаст исключение, и пользователь почувствует, что обработка логики подписки не удалась.

существоватьвыпускатьсобытиечас,Необходимо учитывать ситуацию, когда логика подписки ненормальна.,Я предлагаю три решения

  1. Подписчики пробуют еще раз сами

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

Следующий пример кода performSuccess Когда метод генерирует исключение, Spring Метод будет выполняться повторно до успешного завершения, вплоть до повторной попытки. 3 раз, можно установить время интервала и время приращения интервала повторных попыток.

Язык кода:javascript
копировать
@Retryable(value = Exception.class, maxAttempts = 3, backoff = @Backoff(delay = 100L, multiplier = 2))
public void performSuccess(PerformEvent event) {
    
}

использовать @Retryable Прежде чем комментировать, не забудьте представить spring-retry pom полагаться

Язык кода:javascript
копировать
<dependency>
    <groupId>org.springframework.retry</groupId>
    <artifactId>spring-retry</artifactId>
    <version>1.2.4.RELEASE</version>
</dependency>
  1. подписчикполагаться Kafka Повторная попытка группы потребителей

еслисуществовать Kafka потребительиспользуется вSpring Событие, обработка повторных попыток очень проста. Вам нужно обращаться к нам только в том случае, если ваше потребление является ненормальным. Kafka Просто верните провал потребления, Кафка Попытка будет повторена автоматически.

также,Сообщения также можно отправлять в специальную очередь недоставленных писем.,существуют повторные обработки сообщений в очереди недоставленных писем! разные компании Kafka Схема реализации возможности повтора может быть разной, и каждый может сделать свой выбор.

  1. Заблаговременно сообщайте об аномалиях сбоев на платформу управления сбоями.

Процесс устранения неполадок

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

Выяснив причину проблемы и попросив соответствующих коллег устранить проблему, нажмите кнопку «Повторить». Когда фоновая система управления сбоями получает запрос на повторную попытку, она вызывает бизнес-систему через Rpc SPI, чтобы повторить ошибку и уведомлять фоновую систему управления о результатах успеха и неудачи.

6. Подписчики Spring должны обеспечить идемпотентность

Для повышения надежности необходимы дополнительные механизмы повторных попыток, обеспечивающие Spring подпискавыпускатьнадежность。

Если есть повторные попытки, должна быть идемпотентность! Убедитесь, что логика подписчика идемпотентна. Spring не знает, какие подписчики выполнили операцию успешно, а какие нет. Spring выполнит всех подписчиков при следующей повторной попытке. Следовательно, логика подписки должна быть идемпотентной, чтобы предотвратить возникновение несогласованности данных.

Зачем нужна очередь сообщений MQ и Spring Event?

Однажды мой друг сказал мне, что наша компания хороша в Spring Event Сценарий приложения следует заменить на MQ。существовать Позвольте мне объяснить это

Spring Событие и MQ Однако все они относятся к подписке на выпуск приложения. MQ Сравнивать SpringEvent Мощный и сложный. МК Больше подходит для развязки, изоляции и уведомления о событиях между приложениями. Например, такие события, как оплата заказа, завершение заказа, завершение выполнения заказа и т. д., должны транслироваться для уведомления других последующих микросервисов. Этот сценарий больше подходит для использования MQ 。

Однако для сценариев, когда вам нужно подписаться на выпуск внутри приложения, лучше использовать Весеннее событие. Эти два понятия не противоречат друг другу, MQ Возможности сильнее, а технические решения более «тяжелые». Весна Event Более компактный и подходит для подписок внутри приложения, чтобы обеспечить разделение бизнес-логики.

boy illustration
Неразрушающее увеличение изображений одним щелчком мыши, чтобы сделать их более четкими артефактами искусственного интеллекта, включая руководства по установке и использованию.
boy illustration
Копикодер: этот инструмент отлично работает с Cursor, Bolt и V0! Предоставьте более качественные подсказки для разработки интерфейса (создание навигационного веб-сайта с использованием искусственного интеллекта).
boy illustration
Новый бесплатный RooCline превосходит Cline v3.1? ! Быстрее, умнее и лучше вилка Cline! (Независимое программирование AI, порог 0)
boy illustration
Разработав более 10 проектов с помощью Cursor, я собрал 10 примеров и 60 подсказок.
boy illustration
Я потратил 72 часа на изучение курсорных агентов, и вот неоспоримые факты, которыми я должен поделиться!
boy illustration
Идеальная интеграция Cursor и DeepSeek API
boy illustration
DeepSeek V3 снижает затраты на обучение больших моделей
boy illustration
Артефакт, увеличивающий количество очков: на основе улучшения характеристик препятствия малым целям Yolov8 (SEAM, MultiSEAM).
boy illustration
DeepSeek V3 раскручивался уже три дня. Сегодня я попробовал самопровозглашенную модель «ChatGPT».
boy illustration
Open Devin — инженер-программист искусственного интеллекта с открытым исходным кодом, который меньше программирует и больше создает.
boy illustration
Эксклюзивное оригинальное улучшение YOLOv8: собственная разработка SPPF | SPPF сочетается с воспринимаемой большой сверткой ядра UniRepLK, а свертка с большим ядром + без расширения улучшает восприимчивое поле
boy illustration
Популярное и подробное объяснение DeepSeek-V3: от его появления до преимуществ и сравнения с GPT-4o.
boy illustration
9 основных словесных инструкций по доработке академических работ с помощью ChatGPT, эффективных и практичных, которые стоит собрать
boy illustration
Вызовите deepseek в vscode для реализации программирования с помощью искусственного интеллекта.
boy illustration
Познакомьтесь с принципами сверточных нейронных сетей (CNN) в одной статье (суперподробно)
boy illustration
50,3 тыс. звезд! Immich: автономное решение для резервного копирования фотографий и видео, которое экономит деньги и избавляет от беспокойства.
boy illustration
Cloud Native|Практика: установка Dashbaord для K8s, графика неплохая
boy illustration
Краткий обзор статьи — использование синтетических данных при обучении больших моделей и оптимизации производительности
boy illustration
MiniPerplx: новая поисковая система искусственного интеллекта с открытым исходным кодом, спонсируемая xAI и Vercel.
boy illustration
Конструкция сервиса Synology Drive сочетает проникновение в интрасеть и синхронизацию папок заметок Obsidian в облаке.
boy illustration
Центр конфигурации————Накос
boy illustration
Начинаем с нуля при разработке в облаке Copilot: начать разработку с минимальным использованием кода стало проще
boy illustration
[Серия Docker] Docker создает мультиплатформенные образы: практика архитектуры Arm64
boy illustration
Обновление новых возможностей coze | Я использовал coze для создания апплета помощника по исправлению домашних заданий по математике
boy illustration
Советы по развертыванию Nginx: практическое создание статических веб-сайтов на облачных серверах
boy illustration
Feiniu fnos использует Docker для развертывания личного блокнота Notepad
boy illustration
Сверточная нейронная сеть VGG реализует классификацию изображений Cifar10 — практический опыт Pytorch
boy illustration
Начало работы с EdgeonePages — новым недорогим решением для хостинга веб-сайтов
boy illustration
[Зона легкого облачного игрового сервера] Управление игровыми архивами
boy illustration
Развертывание SpringCloud-проекта на базе Docker и Docker-Compose