Дизайн интерфейса отправки сообщений (включая исходный код)

Java задняя часть Java EE
Дизайн интерфейса отправки сообщений (включая исходный код)

мне 3 года, один годCRUDдесятилетний опытmarkdownПрограммисты 👨🏻‍💻 известны как качественные игроки в Багувен круглый год

Что делать сегодня, чтобы достичьaustin-apiа такжеaustin-api-implЧасть кода модуля.После завершения этого блока будет открыта вся связь между модулями.

Остин проектОсновные функции: отправлять сообщения

значение проекта: Раз есть необходимость в отправке сообщений в компании, то должны быть и подобныеaustinпроекта, а также отправлять и обрабатывать все виды сообщений унифицированным образом. Это способствует объединению функций и повышает эффективность разработки бизнес-требований.

Не много ББ, начнем сегодняшнюю тему

01. Дизайн интерфейса

существуетaustini-apiИнтерфейс для отправки сообщений определяется в модуле, вaustin-api-implРеализуйте конкретную логику ниже. Мое определение реализации интерфейса:

public interface SendService {
​
​
    /**
     * 单模板单文案发送接口
     * @param sendRequest
     * @return
     */
    SendResponse send(SendRequest sendRequest);
​
​
    /**
     * 单模板多文案发送接口
     * @param batchSendRequest
     * @return
     */
    SendResponse batchSend(BatchSendRequest batchSendRequest);
​
}

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

Параметры интерфейса, которые я определил, следующие:

public class SendRequest {
​
    /**
     * 执行业务类型
     */
    private String code;
​
    /**
     * 消息模板Id
     */
    private Long messageTemplateId;
​
​
    /**
     * 消息相关的参数
     */
    private MessageParam messageParam;
    
}

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

02. Реализация кода

Как видно из процесса,austin-apiПосле получения запроса сообщение отправляется наMQиз

Какая польза от этого? Предположим, что время обслуживания сообщения истекло,austin-apiЕсли это прямой вызов службы интерфейса доставки, она может существоватьтайм-аутРиск, тормозящий работу всего интерфейса. MQ здесь, чтобы выполнять асинхронность и развязку, а также в определенной степени противостоять бизнес-трафику.

заподавляющее большинствоДля отправленных сообщений бизнес-сторона не слишком обеспокоена тем, может ли онакогда вызывается интерфейсзнать результат отправки, инекоторые каналы при отправкеЯ не знаю результат отправки (конечный результат сообщается асинхронно, например, SMS и PUSH push)

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

Два дня назад я разместил статью на платформе блогов "Интервьюер: Как проектировать при изменении системных требований?", некоторые пользователи сети прокомментировали:

Интервьюер: Я понимаю, возвращайтесь и ждите уведомления. ... ведущий: Сяо Ван, как план рефакторинга нашей системы переменных? Сяо Ван: Нет проблем.Сначала определите цепочку ответственности, найдя наш бизнес, а затем разверните скрипты на каждом конкретном этапе и добавьте интерфейс оркестрации сервисов на верхний уровень для унифицированного управления.... ведущий: Звучит интересно, как кандидаты сегодня? Сяо Ван: Не упоминайте, он сказал, что у него 5 лет опыта проектирования крупномасштабных систем, и он никогда не использовал Redis. Разве это не сезон вербовки? Достаточно набрать двух стажеров, которые придут и будут сражаться за меня. Ведущий: Ладно, делим временные узлы и вехи, и начинаем проект на слиянии. Сяо Ван: Хорошо.

В этой реализации я также использовал модель цепочки ответственности, и вы можете перейти к конкретному и полному коду.GiteeПросто потяните его. Многие студенты обнаружили, что они не могут понять код после извлечения кода Вы можете отсортировать роли в цепочке ответственности в соответствии со следующим рисунком. Если вы действительно этого не понимаете, предлагаю перелистнуть статью о цепочке ответственности, которую я написал ранее (две уже отправлены)

Вернемся к реализации кода. На этот раз я реализовал следующее:предварительная проверка параметров->Сборка параметров->отправлять сообщения

Да, я нарисовал так много картинок, сначалапоставить лайк, обратите внимание на первую волну.

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

(Примечание: Это первая версия реализации. Логику или комментарии по основе обязательно добавлю позже. На самом деле я уже ее пишу, но обычно запихиваю код на маленьком этапе, так что помнитеstarЗагрузите gitee, чтобы увидеть последний код)

Давайте начнем сПредпроверкаНу, в основном, чтобы определить, передан ли идентификатор шаблона и переданы ли параметры сообщения (регулярная проверка параметров, если есть проблема, напрямую разорвать ссылку и вернуться, чтобы сообщить вызывающему абоненту, что есть проблема)

Давайте посмотримСборка параметров, в основном черезИдентификатор шаблона для проверки содержимого всего шаблона, то согласновход в бизнесСоберите свою собственную TaskInfo (сообщение о задаче).

У некоторых учащихся могут возникнуть вопросы❓: Почему нельзя напрямую использовать POJO шаблона? Вместо этого его нужно собрать в TaskInfo?

На самом деле это относительно легко понять.Шаблон используется как информация для пользователя для настройки сообщения, что является самой примитивной информацией. Но нам нужно сделать обработку, когда мы отправляем его. Например, если я хочу объединить параметры URL-ссылки, написанной пользователем, я хочуЗаполнительЧтобы заменить реальное значение, мне нужно добавить бизнес-идентификатор в шаблон для отслеживания данных и так далее.

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

Здесь стоит упомянуть, чтоmsgContentОписание этого поля. В шаблоне определение этого поля в аннотации базы данных (это поле должно храниться в базе данных какJSONформат):

`msg_content`        varchar(600) COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '' COMMENT '消息内容 占位符用{$var}表示',

Структура JSON разных каналов отличается:

  • СМС: {"content":"","url":""}
  • Почта: {"content":"","subTitle":""}
  • Push: {"content":"","subTitle":"","phoneImgUrl":""}
  • Мини-программа: {"content":"","pagePath":"" ......}

Первая реакция заключается в том, что я хочу определить поля, которые все каналы могут использовать в TaskInfo. Позже мне показалось, что это не очень красиво, поэтому я определил различныеModel(у разных каналов доставки свои модели контента)

Итак, я использую отражение для сопоставления при сборке TaskInfo и заменяю заполнитель с помощьюPropertyPlaceholderHelper

Отправка очень проста, я напрямую сериализую TaskInfo в JSON, а потом десериализую при чтении.

Стоит отметить, что поскольку TaskInfo использует ContentModel для хранения модели контента, нам нужно писать «информацию о классе» при сериализации JSON, иначе при десериализации данные подклассов будут недоступны.

03. Резюме

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

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

Оглядываясь назад, на самом делеaustin-apiПосле того, как слой получает запрос, перед отправкой сообщения в MQ операции здесь очень просты. На самом деле, можноОбщий бизнесДелайте это здесь (например, функцию общей дедупликации), но после моего рассмотрения она все равно не подходит.

austin-apiЭто уровень доступа, пока что он только считывает конфигурацию из базы данных через id, и нет трудоемкой операции (а значит, параллелизм, который он может нести, чрезвычайно велик). Предполагая, что в будущем будет узкое место для чтения базы данных по идентификатору, мы также можем рассмотреть возможность получения конфигурации из Redis или даже из локальной памяти.

Это определяется бизнесом: часто изменений в шаблоне не так много, и даже если есть проблема сильной консистентности в кеше, это вполне приемлемо для такого небольшого времени.

Question:Зачем вам нужен MQ для отправки сообщения?

Answer: отправка сообщения фактически вызывает API, предоставляемый каждой службой. Если предположить, что служба сообщения истекает,austin-apiЕсли служба вызывается напрямую, она существуеттайм-аутРиск, тормозящий работу всего интерфейса. MQ здесь, чтобы выполнять асинхронность и развязку, а также в определенной степени противостоять бизнес-трафику.

Question: Можете ли вы кратко описать, что делает уровень доступа?

Answer:

Обратите внимание на мой публичный аккаунт WeChat【Java3y】Помимо технологий, я также расскажу о повседневной жизни, некоторые слова можно сказать только тихо~[Онлайн-интервьюер + написание Java-проектов с нуля]Непрерывное высокоинтенсивное обновление! попросить звезду! !Оригинал это не просто! ! Проси три! !

Ссылка на гите:gitee.com/austin

Ссылка на гитхаб:github.com/austin