Практика Vivo по архитектуре высокой доступности на основе родного RabbitMQ

Архитектура

1. Фоновое описание

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

С 2016 по 2018 год для всех сервисов использовался один кластер, с ростом масштабов бизнеса нагрузка на кластер становилась выше, часто возникали отказы кластера.

В 2019 году RabbitMQ вступил в стадию построения высокой доступности и завершил службу имен MQ компонента высокой доступности и двухактивную конструкцию кластера RabbitMQ в том же городе.

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

С момента построения высокой доступности в 2019 году бизнес-трафик вырос в десять раз, а серьезных сбоев кластер не испытывал.

RabbitMQ — это программное обеспечение брокера сообщений с открытым исходным кодом, которое реализует протокол AMQP и возникло в финансовой системе.

Имеет богатые возможности:

  1. Гарантия надежности сообщения, RabbitMQ гарантирует надежность отправки сообщения путем подтверждения отправки, гарантирует надежность сообщения в кластере посредством кластеризации, сохраняемости сообщений и зеркальной очереди, а также гарантирует надежность потребления сообщения путем подтверждения потребления.

  2. RabbitMQ предоставляет клиентов на нескольких языках.

  3. Предусмотрено несколько типов обменов.После отправки сообщений в кластер они направляются в определенные очереди через обмены.

  4. RabbitMQ предоставляет полную информацию об управлении и API управления, которые можно быстро интегрировать с собственной системой мониторинга через API управления.

Проблемы, обнаруженные RabbitMQ в конкретной практике:

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

  2. Собственный клиент RabbitMQ использует адрес кластера для подключения.При использовании нескольких кластеров бизнес должен заботиться об адресе кластера, что сбивает с толку.

  3. Родной RabbitMQ имеет только простую аутентификацию по имени пользователя/паролю и не аутентифицирует используемые бизнес-приложения.. Легко смешивать информацию об обмене/очередях для разных предприятий, что приводит к ненормальному использованию бизнес-приложений.

  4. Используется множество бизнес-приложений, и нет платформы для поддержки связанной информации об отправителях и потребителях сообщений, а сторона стыковки не может быть определена после нескольких итераций версии.

  5. Клиенты имеют неограниченный трафик, а внезапный и аномальный бизнес-трафик влияет на кластер или даже разрушает его.

  6. У клиента нет политики аномальной повторной передачи сообщений, которая должна быть реализована пользователем.

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

  8. При использовании зеркальной очереди главный узел очереди будет падать на конкретный узел.Когда количество очередей кластера велико, легко получить несбалансированную нагрузку на узлы.

  9. RabbitMQ не имеет возможности автоматической балансировки очередей и склонен к неравномерной загрузке узлов кластера при наличии большого количества очередей.

Во-вторых, общая структура

1. MQ-Portal - приложение для поддержки приложений

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

В процессе приложения MQ-Portal (как показано на рисунке выше) определяется и отправляется приложение для отправки сообщений, использования приложения, использования обмена/очереди, отправки трафика и т. д., а затем оно входит во внутренний рабочий порядок vivo. процесс утверждения.

После утверждения процесса заказа на работу через интерфейс обратного вызова заказа на работу назначьте конкретный кластер, используемый приложением, и создайте отношение привязки обмена/очереди в кластере.

Из-за физической изоляции нескольких кластеров для обеспечения высокой доступности услуг в формальной среде невозможно просто определить местонахождение используемого кластера по имени обмена/очереди.

Каждая биржа/очередь связана с кластером с помощью уникальной пары rmq.topic.key и rmq.secret.key, так что конкретный используемый кластер можно найти во время процесса запуска SDK.

rmq.topic.key и rmq.secret.key будут назначены в интерфейсе обратного вызова тикета.

2. Обзор возможностей клиентского SDK

Клиентский SDK инкапсулирован на основе spring-message и spring-rabbit и на этой основе предоставляет такие возможности, как аутентификация использования приложения, адресация кластера, ограничение тока клиента, сброс производства и потребления и блокировка передачи.

2.1 Приложение использует аутентификацию

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

Чтобы избежать смешивания обмена/очереди для разных сервисов, приложение должно быть аутентифицировано.

Аутентификация приложения выполняется с помощью SDK и MQ-NameServer.

Когда приложение запускается, оно сначала передает информацию rmq.topic.key, настроенную приложением, на MQ-NameServer, а MQ-NameServer определяет, является ли используемое приложение тем же, что и приложение приложения, и во время этого выполняется вторичная проверка. процесс отправки сообщений SDK.

/**
  * 发送前校验,并且获取真正的发送factory,这样业务可以声明多个,
  * 但是用其中一个bean就可以发送所有的消息,并且不会导致任何异常
  * @param exchange 校验参数
  * @return 发送工厂
*/
public AbstractMessageProducerFactory beforeSend(String exchange) {
    if(closed || stopped){
        //上下文已经关闭抛出异常,阻止继续发送,减少发送临界状态数据
        throw new RmqRuntimeException(String.format("producer sending message to exchange %s has closed, can't send message", this.getExchange()));
    }
    if (exchange.equals(this.exchange)){
        return this;
    }
    if (!VIVO_RMQ_AUTH.isAuth(exchange)){
        throw new VivoRmqUnAuthException(String.format("发送topic校验异常,请勿向无权限exchange %s 发送数据,发送失败", exchange));
    }
    //获取真正的发送的bean,避免发送错误
    return PRODUCERS.get(exchange);
}

2.2 Кластерная адресация

Как упоминалось выше, приложения используют RabbitMQ для выделения кластеров строго в соответствии с условиями загрузки и бизнес-трафиком кластера, поэтому разные обмены/очереди, используемые конкретным приложением, могут быть размещены на разных кластерах.

Чтобы повысить эффективность развития бизнеса, необходимо оградить влияние нескольких кластеров на бизнес, поэтому кластер автоматически адресуется в соответствии с информацией rmq.topic.key, настроенной приложением.

2.3 Текущий лимит клиента

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

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

2.4. Сброс производства и потребления

(1) С ростом масштаба бизнеса нагрузка на кластер продолжает расти, и в это время кластерный бизнес необходимо разделить. Чтобы уменьшить необходимость избегать перезапуска бизнеса в процессе разделения, требуется функция сброса производства и потребления.

(2) Если кластер неисправен, это может привести к отключению потребителей.В это время бизнес-потребление можно быстро поднять, сбросив производство и потребление.

Для реализации сброса производства и потребления необходимо реализовать следующие процессы:

  • Сбросить заводские параметры соединения

  • сбросить соединение

  • установить новое соединение

  • Перезапустите производство и потребление

CachingConnectionFactory connectionFactory = new CachingConnectionFactory();
connectionFactory.setAddresses(address);
connectionFactory.resetConnection();
rabbitAdmin = new RabbitAdmin(connectionFactory);
rabbitTemplate = new RabbitTemplate(connectionFactory);

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

2.5, блокировка передачи

RabbitMQ блокирует отправку сообщений, когда использование памяти превышает 40% или использование диска превышает лимит.

Поскольку команда промежуточного программного обеспечения vivo завершила построение внутригородского активного-активного RabbitMQ, когда кластер блокируется при отправке, он может сбросить производство и потребление в активно-активный кластер, чтобы завершить быструю передачу блокировки.

2.6 Многокластерное планирование

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

Таким образом, SDK должен поддерживать возможность планирования нескольких кластеров и удовлетворять потребности большого бизнес-трафика, распределяя трафик по нескольким кластерам.

3. MQ-NameServer — поддержка MQ-SDK для обеспечения быстрого аварийного переключения.

MQ-NameServer является сервисом без сохранения состояния. Он может обеспечить свою высокую доступность за счет развертывания кластера. В основном он используется для решения следующих задач:

  • MQ-SDK запускает аутентификацию, и приложение использует позиционирование кластера.

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

  • Управляйте MQ-SDK, чтобы сбросить производство и потребление.

4. Практика развертывания высокой доступности MQ-Server

Все кластеры RabbitMQ используют архитектуру развертывания «активный-активный» в одном городе, полагаясь на адресацию кластера и возможности быстрого переключения при сбое, предоставляемые MQ-SDK и MQ-NameServer, для обеспечения доступности кластера.

4.1. Решение проблемы кластерного разделения мозга

RabbitMQ официально предоставляет три стратегии восстановления кластера с разделенным мозгом.

(1) игнорировать

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

(2) pause_minority

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

(3) автолечение

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

Поскольку все кластеры RabbitMQ развернуты в том же городе, что и активный-активный, даже если ненормальный бизнес-трафик одного кластера может быть автоматически перенесен в кластер активного-активного компьютерного зала, стратегия pause_minority выбирается, чтобы избежать проблемы разделения мозга. .

В 2018 году из-за джиттера сети много раз возникало расщепление кластера.После изменения стратегии восстановления кластера расщепления проблема больше не возникала.

4.2 Кластерное решение высокой доступности

RabbitMQ использует кластерное развертывание, а поскольку стратегия восстановления кластера с разделенным мозгом использует режим pause_minority, для каждого кластера требуется как минимум 3 узла.

Рекомендуется развернуть высокодоступный кластер с 5 или 7 узлами и контролировать количество очередей кластера.

Очереди кластера — это зеркальные очереди, обеспечивающие резервное копирование сообщений во избежание потери сообщений из-за исключений узла.

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

Все очереди настроены на ленивые очереди, чтобы уменьшить колебания использования памяти узла.

4.3. Двойное активное строительство в одном городе

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

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

Получите самую последнюю доступную информацию о кластере с помощью пульса MQ-NameServer и повторно подключитесь к кластеру «активный-активный» в случае сбоя, чтобы обеспечить быстрое восстановление функций приложения.

3. Будущие вызовы и перспективы

В настоящее время использование RabbitMQ в основном расширено на стороне MQ-SDK и MQ-NameServer. Реализация SDK относительно сложна. На более позднем этапе можно надеяться, что можно будет построить прокси-уровень промежуточного программного обеспечения сообщений, который может упростить SDK и более детально управлять бизнес-трафиком.

Автор: Дерек