Что такое очередь сообщений?

Java очередь сообщений

предисловие

Только лысая голова может стать сильнее.

Текст был включен в мой репозиторий GitHub, добро пожаловать, звезда:GitHub.com/Zhongf UC очень…

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

1. Что такое очередь сообщений?

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

Очередь сообщений, обычно мы будем называть ее MQ (очередь сообщений), ну, это очень простая аббревиатура.

Давайте проигнорируем слово «Сообщение» и взглянем на «Очередь». На этом этапе все должны быть знакомы с очередью.

очередь - этопервым пришел-первым вышелструктура данных.

先进先出

В Java реализовано множество очередей:

Java的队列实现类

Итак, зачем вам очередь сообщений (MQ)?промежуточное ПОШерстяная ткань? ? ? На самом деле, эта проблема очень похожа на ту, когда я изучал Redis раньше. Redis — этоkey-valueБаза данных в памяти, хранящаяся в форме, очевидно, мы можем использовать класс реализации, такой как HashMap, для достижения аналогичного эффекта, так почему мы должны использовать Redis? "Коллекция Redis

  • На этом этапе вы можете догадаться, почему вы используете очередь сообщений (MQ)промежуточное ПО, который будет добавлен ниже.

Очередь сообщений можно просто понять как:поставить данные для передачи в очередь.

图片来源:https://www.cloudamqp.com/blog/2014-12-03-what-is-message-queuing.html
)

Популярная наука:

  • Помещение данных в очередь сообщений называетсярежиссер
  • Извлечение данных из очереди сообщений называетсяпотребитель

2. Зачем использовать очередь сообщений?

Зачем использовать очередь сообщений, чтобы спросить: каковы преимущества использования очереди сообщений. Давайте рассмотрим следующий сценарий

2.1 Развязка

Теперь у меня есть система А, которая может производитьuserId

系统A可以产生一个UserId

Затем, теперь есть система B и система C, которые нуждаются в этом.userIdделать сопутствующие операции

系统A给系统B和系统C传入userId这个值

В псевдокоде это может выглядеть так:

public class SystemA {

    // 系统B和系统C的依赖
    SystemB systemB = new SystemB();
    SystemC systemC = new SystemC();

    // 系统A独有的数据userId
    private String userId = "Java3y";

    public void doSomething() {

        // 系统B和系统C都需要拿着系统A的userId去操作其他的事
        systemB.SystemBNeed2do(userId);
        systemC.SystemCNeed2do(userId);
        
    }
}

Структурная схема выглядит следующим образом:

结构图

ок, все прошло за несколько дней без происшествий.

Однажды ответственный за систему B сказал ответственному за систему A, что теперь ответственный за систему BSystemBNeed2do(String userId)Этот интерфейс больше не используется,Пусть Система А не настроит ее.

Итак, человек, ответственный за Систему А, сказал: «Хорошо, тогда я не буду вам звонить».Удален код, вызывающий интерфейс системы B.:

public void doSomething() {

  // 系统A不再调用系统B的接口了
  //systemB.SystemBNeed2do(userId);
  systemC.SystemCNeed2do(userId);

}

Через несколько дней человек, отвечающий за систему D, получил запрос, и ему также нужно было использовать идентификатор пользователя системы А, поэтому он побежал к ответственному за систему А и сказал: «Брат, я хочу использовать твой идентификатор пользователя, вы настраиваете мой интерфейс."

Итак, Система А сказала: «Нет проблем, давайте сделаем это».

系统A需要调用系统D的接口

Затем код для системы А выглядит следующим образом:

public class SystemA {

    // 已经不再需要系统B的依赖了
    // SystemB systemB = new SystemB();
    
    // 系统C和系统D的依赖
    SystemC systemC = new SystemC();
    SystemD systemD = new SystemD();

    // 系统A独有的数据
    private String userId = "Java3y";

    public void doSomething() {

       
        // 已经不再需要系统B的依赖了
        //systemB.SystemBNeed2do(userId);

        // 系统C和系统D都需要拿着系统A的userId去操作其他的事
        systemC.SystemCNeed2do(userId);
        systemD.SystemDNeed2do(userId);

    }
}

время летит:

  • Несколько дней спустя человек, ответственный за систему E, пришел и сказал системе A, что требуется идентификатор пользователя.
  • Несколько дней спустя человек, отвечающий за Систему Б, пришел и сказал Системе А снова отключить интерфейс.
  • Через несколько дней к нам подошел ответственный за систему F и сообщил системе А, что требуется идентификатор пользователя.
  •  …

Итак, человек, отвечающий за Систему А, каждый день страдает от этого, меняясь и меняясь, меняясь и меняясь...

Есть еще одна проблема: при вызове системы C, если система C зависает, система A должна найти способ справиться с этим. Если время запроса истекает из-за задержки в сети при вызове системы D, то система A является обратной связью.failИли попробовать еще раз? ?

В конце концов ответственный за Систему А почувствовал, что менять ее время от времени скучно, и сбежал.

Затем компания наняла большого парня, который через несколько дней знакомства с большим парнем подошел и сказал:Запишите идентификатор пользователя системы A в очередь сообщений, чтобы систему A не нужно было часто менять.. Зачем? Давайте посмотрим на это вместе:

系统A将userId写到消息队列中,系统C和系统D从消息队列中拿数据

Система A записывает идентификатор пользователя в очередь сообщений, а системы C и D получают данные из очереди сообщений.Каковы преимущества такого?

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

    • Даже если системе D больше не нужны данные userId, системе B внезапно снова потребуются данные userId. Это не имеет ничего общего с системой A, и системе A не нужно менять какой-либо код.
  • Систему D userId брать не через систему А, а из очереди сообщений, чтобы попасть внутрь.Даже если система D зависнет или время запроса истечет, это не имеет ничего общего с системой A, только с очередью сообщений..

Таким образом, система А и системы В, С и Dразъединение.

2.2 Асинхронный

Давайте рассмотрим следующую ситуацию: Система А по-прежнемупозвонить напрямуюСистема Б, С, Д

直接调接口

код показывает, как показано ниже:

public class SystemA {

    SystemB systemB = new SystemB();
    SystemC systemC = new SystemC();
    SystemD systemD = new SystemD();

    // 系统A独有的数据
    private String userId ;

    public void doOrder() {
     
        // 下订单
      	userId = this.order();
        // 如果下单成功,则安排其他系统做一些事  
        systemB.SystemBNeed2do(userId);
        systemC.SystemCNeed2do(userId);
        systemD.SystemDNeed2do(userId);

    }
}

ПредположениеСистеме A требуется 50 мс для вычисления определенного значения userId, 300 мс для вызова интерфейса системы B, 300 мс для вызова интерфейса системы C и 300 мс для вызова интерфейса системы D. Тогда этот запрос требует50+300+300+300=950ms

И мы узнаем, что то, что делает Система А,Основной бизнес, а системы B, C и DнеосновнойБизнес. Например, система А обрабатываетразместить заказ, а система B — это заказ, размещенный успешно, затем отправьте текстовое сообщение, чтобы сообщить конкретному пользователю, что заказ был выполнен успешно, а система C и система D также занимаются некоторыми тривиальными вопросами.

Тогда, в это время, дляУлучшить пользовательский опыт и пропускную способность, фактическиасинхронноВызовите интерфейс системы B, C, D. Итак, мы можем сделать это так:

此时才用了100ms

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

  • Первоначально весь запрос занимал 950 мс (синхронизация)
  • Вызов других системных интерфейсов теперь будет асинхронным, всего 100 мс (асинхронно).

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

2.3 Пиковое отсечение / ограничение тока

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

削峰的场景

Дополнительные 1000 запросов могут поставить насВся система сломана...итак, есть способ написать в очередь сообщений:

写到消息队列中,系统从消息队列中拿到请求

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

3. Что не так с использованием очередей сообщений?

После наших вышеприведенных сценариев мы уже можем обнаружить, что на самом деле очереди сообщений могут делать довольно много вещей.

Говоря об этом, давайте вернемся к началу статьи: «Очевидно, что в JDK уже реализовано много очередей, нужно ли нам промежуточное ПО для очередей сообщений?» На самом деле все очень просто, хотя реализовано много типов очередей. от JDK, все они Дапростая очередь памяти. Почему я говорю, что JDK — это простая очередь памяти? Давайте посмотрим, как реализовать очередь сообщений (промежуточное ПО)что можно считать.

3.1 Высокая доступность

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

万一单机的队列挂掉了

Поэтому, когда мы используем очереди сообщений в нашем проекте, мы должны集群/分布式из. сделать集群/分布式Следует надеяться, что очередь сообщений может обеспечитьс полкиВместо написания кода реализовать его вручную.

3.2 Проблема потери данных

Мы записываем данные в очередь сообщений, и системы B и C зависают, не успев получить данные из очереди сообщений.Если ничего не сделать, наши данные будут потеряны.

数据丢失问题

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

Где это существует?

  • диск?
  • база данных?
  • Редис?
  • Распределенная файловая система?

Синхронное хранилище или асинхронное хранилище?

3.3 Как потребитель получает данные очереди сообщений?

Как потребитель получает данные из очереди сообщений? Есть два способа:

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

3.4 Другое

Кроме них, мыкогда используешьНеобходимо рассмотреть различные вопросы:

  • Что делать, если сообщение используется повторно?
  • Я хочу убедиться, что сообщениеабсолютныйКак это сделать по порядку?
  • ……..

Хотя очереди сообщений принесли нам так много преимуществ, в то же время мы обнаружили, что введение очередей сообщений такжеУвеличить сложность системы. На рынке уже существует множество колес очередей сообщений, и каждая очередь сообщений имеет свои особенности.Какой MQ выбрать должен быть тщательно продуман.

Наконец

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

Использованная литература:

рад вывестигалантерейные товарыОбщедоступный номер технологии Java: Java3y. В паблике более 200 статейоригинальныйТехнические статьи, обширные видеоресурсы, красивые карты мозга — идите сюдаобрати внимание нанемного!

帅的人都关注了

Я думаю, что моя статья хорошо написана, пожалуйста, нажмитеотличный!