1. Введение в микросервисную архитектуру
1. Монолитная архитектура
Монолитная архитектура также известна как монолитное приложение, которое объединяет все функциональные модули в одном проекте.
1.1 Особенности монолитной архитектуры
1. Со временем будет упакован в самостоятельную единицу (уникальный пакет jar или военный пакет)
2. Будет работать как процесс
1.2 Преимущества и недостатки монолитной архитектуры
преимущество
- Проектами легко управлять
- Простота развертывания
недостаток
- Высокая стоимость тестирования
- Плохая масштабируемость
- низкая надежность
- Сложность повторения
- Плохое владение несколькими языками
- Сложно работать в команде
2. Микросервисная архитектура
2.1 Что такое микросервисы
Микросервисы — это архитектурный стиль. Большое сложное программное приложение, состоящее из одного или нескольких микросервисов. Каждая микрослужба в системе может быть развернута независимо, и каждая микрослужба слабо связана. Каждый микросервис фокусируется только на выполнении одной задачи и делает ее хорошо.
2.2 Общие архитектурные стили
- клиент и сервер
- Архитектура на основе компонентной модели (EJB)
- Многоуровневая архитектура (MVC)
- Сервис-ориентированная архитектура (SOA)
2.3 Характеристики микросервисов
- Система состоит из нескольких сервисов.
- Каждая служба может быть развернута независимо
- Каждая услуга слабо связана, с высокой степенью связанности внутри службы и низкой связанностью вне службы Высокая степень связанности означает, что проект фокусируется на выполнении функции.
2.4 Преимущества и недостатки микросервисов
преимущество:
- легко проверить
- Сильная масштабируемость
- Сильная надежность
- Больше гибкости на разных языковых уровнях
- Работать в команде легко
- Простая итерация системы
недостаток:
- Затраты на эксплуатацию и обслуживание слишком высоки, а количество развертываний велико.
- Интерфейс, совместимый с несколькими версиями
- Сложность распределенных систем
- Распределенная транзакция
Во-вторых, разница между MVC, RPC, SOA и микросервисными архитектурами.
1. Архитектура MVC
По сути, MVC — это традиционная монолитная архитектура.
Представляющие технологии: SpringMVC, Spring, MyBatis и др.
2. Архитектура RPC
RPC (удаленный вызов процедур): удаленный вызов процедур. Это протокол для запроса услуг от удаленной компьютерной программы по сети без знания базовой сетевой технологии.
Представляющие технологии: Thrift, Hessian и др.
3. SOA-архитектура
SOA (сервисно-ориентированная архитектура): сервис-ориентированная архитектура
ESB (Enterparise Service Bus): корпоративная служебная шина, сервис-посредник. В основном предоставляет сервис для взаимодействия между сервисами. ESB включает в себя такие функции, как: балансировка нагрузки, управление потоком, обработка шифрования, мониторинг сервисов, обработка исключений, аварийный мониторинг и так далее.
Репрезентативные технологии: Mule, WSO2
4. Микросервисная архитектура
Микросервисы — это упрощенное решение для управления сервисами.
Представляющие технологии: SpringCloud, dubbo и др.
3. Принципы проектирования микросервисов
- Принцип разделения AKF
- Принцип разделения переднего и заднего концов
- служба без гражданства
- Стиль общения RestFul
1. Раздельный принцип AKF
В отрасли существует простая концепция проектирования масштабируемой системной архитектуры, а именно: ** Проблемы производительности и доступности могут быть решены путем добавления машин. (если один не работает, то два)**
Эта концепция получила широкое признание сегодня, когда концепция «облачных вычислений» пользуется бешеной популярностью! Для быстрорастущей системы вопросы емкости и производительности, безусловно, стоят на первом месте. Однако с течением времени, с ростом масштаба системы, в дополнение к проблемам производительности и емкости, также необходимо решать проблемы сложности системы, вызванные увеличением количества функций и модулей, а также различия в обеспечении, вызванные изменениями в бизнесе, проблемы с обслуживанием. Однако для многих систем эти проблемы не учитываются в полной мере при архитектурном проектировании, что приводит к тому, что реконфигурация системы становится нормой, что влияет на способность к реализации бизнеса и тратит впустую человеческие и финансовые ресурсы! В связи с этим в книге «Искусство масштабирования» предлагается более систематическая и масштабируемая модель —Куб масштабируемости AKF. Настройки по трем координатным осям в этом кубе: X, Y, Z.
- Ось Y (функция) — основное внимание уделяется функциональному разделению в приложении на основе различных бизнес-разделений.
- Ось X (горизонтальное масштабирование) — акцент на горизонтальном масштабировании, также известном как «добавление машин для решения проблем».
- Ось Z (разделение данных) — акцент на приоритизации услуг и данных, например, по географическому признаку.
1.1 Ось Y (функция)
Масштабирование по оси Y разделит большое монолитное приложение на несколько сервисов. Каждый сервис реализует набор связанных функций, таких как управление заказами, управление клиентами и т.д. Распространенным решением в инженерии являетсяСервис-ориентированная архитектура (SOA). Например, для платформы электронной коммерции мы можем разделить ее на разные сервисы, чтобы сформировать следующую архитектуру:
Однако, наблюдая за приведенным выше рисунком, легко обнаружить, что при увеличении количества служб отношения вызова служб усложняются. Когда в систему добавляется новая функция, количество вызываемых служб становится неконтролируемым, что приводит к путанице в управлении службами. Следовательно, в общем случае необходимо использовать механизм регистрации службы для формирования шлюза службы для управления службами. Архитектура системы станет такой, как показано ниже:
1.2 Ось X (горизонтальное расширение)
Масштабирование по оси X согласуется с нашей предыдущей наивной концепцией решения проблем с емкостью и доступностью за счет абсолютно одинаковой репликации сервисов и данных. По сути, это запуск нескольких экземпляров микросервисов для работы в режиме кластера плюс балансировка нагрузки.
Чтобы повысить доступность и пропускную способность одной службы,Разделите расширение по оси X для каждой службы.
1.3 Ось Z (раздел данных)
Расширение по оси Z обычно относится к разделению системы на основе уникальных требований заказчиков или пользователей и созданию разделенных подсистем, изолированных друг от друга, но полных. Возьмем, к примеру, завод по производству автомобилей: чтобы развивать свой бизнес в Китае или использовать в своих интересах дешевую рабочую силу Китая, Форд создал в Китае целостный подзавод, отвечающий за полное производство автомобилей, как и американский. фабрика. Это расширение оси Z.
В инженерной сфере есть два распространенных расширения оси Z:
-
Единая архитектура
В области проектирования распределенных услуг ячейка представляет собой автономный замкнутый цикл, который выполняет все бизнес-операции в определенном разделе. Как упоминалось выше, в архитектуре SOA с расширением по оси Y выбор серверных узлов клиентом, как правило, является случайным, однако, если сюда добавить расширение по оси Z, выбор сервисных узлов больше не будет случайным. , каждая единица автономна. Как показано ниже:
-
раздел данных
Для обеспечения безопасности данных о производительности мы разделяем полный набор данных на разные подмножества в соответствии с определенным параметром. Осколок — это подмножество общего набора данных. Например, используя хвостовой номер для разделения пользователей, часть пользователей с одинаковым хвостовым номером можно рассматривать как раздел. Разделение данных обычно включает следующие методы разделения данных:
- Тип данных (например, тип бизнеса)
- Диапазон данных (например, период времени, идентификатор пользователя)
- Популярность данных (например, активность пользователей, популярность продукта)
- Оценка по чтению и письму (например, описание продукта, список продуктов)
2. Принцип разделения переднего и заднего концов
Чем отличается перед и зад? Разве перед и зад не разделены? Это начинается с неуклюжего jsp. Уточнение разделения труда всегда было принципом увеличения пирога.Лучше всего, чтобы инженеры в нескольких областях сотрудничали, не контактируя с другими областями знаний, чтобы эффективность стала выше, а обслуживание стало проще. Шаблонная технология jsp интегрирует код html и java, так что передняя и задняя части в традиционной разработке MVC здесь склеены вместе... Цель разделения передней и задней частей состоит в том, чтобы сломать эту неловкую ситуацию. Принцип разделения клиентской и серверной частей — это просто разделение кода на интерфейсную и серверную части.Рекомендуемый режим заключается в том, что лучше всего использовать физическое разделение для развертывания, чтобы еще больше способствовать более тщательному разделению. Если вы продолжаете напрямую использовать технологию шаблонов на стороне сервера, например: jsp, и складывать java, js, html и css на одну страницу, чуть более сложную страницу невозможно поддерживать.
Такое разделение имеет ряд преимуществ:
- Внешние и внутренние технологии разделены, и их соответствующие эксперты могут оптимизировать свои соответствующие области, чтобы эффект оптимизации пользовательского интерфейса был лучше.
- В режиме разделения интерфейс взаимодействия между интерфейсом и сервером более понятен, оставляя модель интерфейса, а интерфейс на сервере лаконичен и прост в обслуживании.
- Сценарий внешней многоканальной интеграции легче реализовать, внутренние службы не нужно менять, а унифицированные данные и модель можно использовать для поддержки нескольких внешних частей: например: WeChat h5 front-end , интерфейс ПК, интерфейс Android, интерфейс IOS.
3. Службы без сохранения состояния
Для сервисов без сохранения состояния, прежде всего, что такое состояние: если данные должны быть разделены несколькими сервисами для выполнения транзакции, то эти данные называются состоянием. В свою очередь, служба, которая опирается на эти данные о состоянии, называется службой с отслеживанием состояния, и наоборот — службой без сохранения состояния.
Тогда этот принцип службы без сохранения состояния не означает, что состояние не разрешено в архитектуре микрослужбы, но реальный смысл выражения состоит в том, чтобы изменить бизнес-службу с отслеживанием состояния на вычислительную службу без сохранения состояния, после чего данные о состоянии будут перенесены в соответствующий сервис. соответствующая «Служба данных с отслеживанием состояния».
Описание сценария. Например, кэш данных и кэш сеансов, которые мы ранее установили в локальной памяти, следует перенести в распределенный кэш для хранения в текущей архитектуре микрослужб, чтобы бизнес-служба стала вычислительным узлом без сохранения состояния. После миграции можно обеспечить динамическое масштабирование по запросу, а приложения микрослужб могут динамически добавлять или удалять узлы во время выполнения, поэтому нет необходимости думать, как синхронизировать кэшированные данные.
4. Стиль общения RestFul
В принципе, это должен быть "принцип общения без сохранения состояния". Здесь мы прямо рекомендуем предпочтительный стиль общения Restful, потому что он имеет много преимуществ:
- Протокол HTTP без сохранения состояния имеет присущие ему преимущества и высокую масштабируемость. Например, если требуется защитное шифрование, есть готовое зрелое решение HTTPS.
- Сериализация сообщений JSON, легкая и простая, читаемая как людьми, так и машинами, низкая стоимость обучения и дружественная поисковая система.
- Независимо от языка, все популярные языки предоставляют зрелые фреймворки Restful API, которые являются более полными, чем другие фреймворки RPC.
4. Введение в SpringCloud
1. Что такое SpringCloud
SpringCloud — это платформа управления услугами, которая предоставляет некоторые инфраструктуры услуг. Он включает в себя: регистрацию и обнаружение сервисов, центр конфигурации, центр сообщений, балансировку нагрузки, мониторинг данных и т. д.
Spring Cloud – это среда микросервисов. По сравнению с платформами RPC, такими как Dubbo, Spring Cloud предоставляет полный набор распределенных системных решений. **
Spring Cloud инкапсулирует несколько компонентов инфраструктуры микросервисов Netflix с открытым исходным кодом и в то же время интегрируется с облачной платформой и средой разработки Spring Boot.
Spring Cloud участвует в разработке микросервисной архитектурыУправление конфигурацией, управление услугами, автоматический выключатель, интеллектуальная маршрутизация, микроагент, управляющая шина, одноразовый токен, глобальная блокировка согласованности, выбор лидера, распределенный сеанс, управление состоянием кластераи т. д. обеспечивает простой способ разработки.
Spring Cloud предоставляет разработчикам быстрые сборкиИнструменты для распределенных систем, разработчики могут быстро запускать службы или создавать приложения, а также быстро подключаться к ресурсам облачной платформы.
2. Расположение проекта SpringCloud
SpringCloud — это проект Spring верхнего уровня, расположенный совместно с SpringBoot и SpringData.
3. Подпроекты SpringCloud
3.1 SpringCloud Config
Инструмент управления конфигурацией, поддерживает использование Git для хранения содержимого конфигурации, поддерживает внешнее хранилище конфигурации приложения, поддерживает обновление информации о конфигурации клиента, шифрование и расшифровку содержимого конфигурации и т. д.
3.2 SpringCloud Bus
Событие, шина сообщений для распространения изменений состояния в кластере (например, событий изменения конфигурации), которые можно комбинировать с Spring Cloud Config для горячего развертывания.
3.3 Spring Cloud Netflix>
** Наборы для разработки различных компонентов Netflix, включая Eureka, Hystrix, Zuul, Archaius и другие. **
-
Netflix Eureka
Компонент управления услугами, основанный на оставшейся службе, включая реализацию реестра служб, механизм регистрации служб и обнаружения служб, реализует балансировку облачной нагрузки и аварийное переключение серверов среднего уровня.
-
Netflix Hystrix
Инструмент управления отказоустойчивостью, реализующий режим прерывателя цепи и обеспечивающий более высокую отказоустойчивость в отношении задержек и сбоев за счет управления узлами службы.
-
Netflix Ribbon
Компонент вызова службы балансировки нагрузки на стороне клиента.
-
Netflix Feign
Компонент декларативного вызова службы на основе Ribbon и Hystrix.
-
Netflix Zuul
Шлюз микросервисов, обеспечивающий динамическую маршрутизацию, фильтрацию доступа и другие сервисы.
-
Нетфликс Архай:
API-интерфейсы управления конфигурацией, в том числе ряд API-интерфейсов управления конфигурацией, предоставляют такие функции, как свойства с динамическим типом, потокобезопасные операции конфигурации, структуры опроса и механизмы обратного вызова.
3.4 Spring Cloud for Cloud Foundry
Связывая сервисы с CloudFoundry через протокол Oauth2, CloudFoundry представляет собой облачную платформу PaaS с открытым исходным кодом, запущенную VMware.
3.5 Spring Cloud Sleuth
Набор инструментов для сбора журналов, который инкапсулирует операции Dapper, Zipkin и HTrace.
3.6 Spring Cloud Data Flow
Инструмент для работы с большими данными, который манипулирует потоками данных через командную строку.
3.7 Spring Cloud Security
Security Toolkit для добавления элементов управления безопасностью в ваше приложение, в основном относящихся к OAuth2.
3.8 Spring Cloud Consul
Инкапсулирует операции Consul.Consul — это инструмент для обнаружения и настройки сервисов, который можно легко интегрировать с контейнерами Docker.
3.9 Spring Cloud Zookeeper
Инструментарий для работы с Zookeeper, с регистрацией и обнаружением сервисов по методу zookeeper.
3.10 Весенний облачный поток:
Пакет разработки операций с потоком данных, инкапсулирующий Redis, Rabbit, Kafka и т. д. для отправки и получения сообщений.
3.11 Spring Cloud CLI
Основанный на Spring Boot CLI, он позволяет быстро создавать облачные компоненты из командной строки.
Пять, разница между SpringCloud и Dubbo
6. Описание версии Spring Cloud
1. Описание общих номеров версий
Номер версии программного обеспечения: 2.0.2.RELEASE
-
2: основной номер версии. При серьезном обновлении функционального модуля или изменении общей архитектуры основной номер версии будет обновлен.
-
0: дополнительный номер версии. Минорные версии указывают лишь на некоторые незначительные изменения.
-
2: Измените номер версии. Обычно исправления ошибок или небольшие изменения
-
ВЫПУСК: номер версии с греческими буквами. Дополнительный номер версии Пользователь указывает, на какой стадии разработки находится текущая версия программного обеспечения.
1.1 Номер версии с греческими буквами
- База: Стадия проектирования. Только соответствующий дизайн не имеет конкретной функциональной реализации
- Альфа: предварительная версия программы. Есть еще ошибки
- Bate: Указывает на значительный прогресс по сравнению с альфа-версией, серьезные ошибки были устранены, и все еще есть некоторые потенциальные ошибки.
- Релиз: этот релиз представляет собой окончательный релиз.
2. Описание номера версии Spring Cloud
2.1 Почему в версии Spring Cloud вместо цифр используются слова?
Цель дизайна — лучше управлять инвентаризацией каждого подпроекта Spring Cloud. Не путайте номер подверсии с номером версии подпроекта.
2.2 Правила определения слов номера версии
В качестве названия номера версии используется название станции метро в Лондоне.Номер версии отсортирован по первой букве, а более поздний номер версии в алфавитном порядке больше.
2.3 Описание плана выпуска версии
7. КроликMQ
1. Что такое RabbitMQ
MQ расшифровывается как Message Queue (очередь сообщений).Это способ связи между приложениями.Приложения могут обмениваться информацией, читая и записывая сообщения в очередь сообщений, а не вызывая друг друга между приложениями.общение.
2. Установите RabbitMQ
2.1 Пакеты зависимостей, необходимые для установки rabbitmq
yum install build-essential openssl openssl-devel unixODBC unixODBC-devel make gcc gcc-c++ kernel-devel m4 ncurses-devel tk tc xz
2.2 Загрузите установочный пакет (cd /usr/local/software)
wget www.rabbitmq.com/releases/erlang/erlang-18.3-1.el7.centos.x86_64.rpm
wget http://repo.iotti.biz/CentOS/7/x86_64/socat-1.7.3.2-5.el7.lux.x86_64.rpm
wget www.rabbitmq.com/releases/rabbitmq-server/v3.6.5/rabbitmq-server-3.6.5-1.noarch.rpm
2.3 Установить сервисную команду
#第一步:安装erlang语言环境
rpm -ivh erlang-18.3-1.el7.centos.x86_64.rpm
#第二步:安装socat加解密软件
rpm -ivh socat-1.7.3.2-5.el7.lux.x86_64.rpm
#第三步:最后安装rabbitmq
rpm -ivh rabbitmq-server-3.6.5-1.noarch.rpm
2.4 Изменить определение пользователя кластера и пульса соединения
**Обратите внимание на изменение файла vim /usr/lib/rabbitmq/lib/rabbitmq_server-3.6.5/ebin/rabbit.app **
Изменить: > в loopback_users оставить только гостя (доступ возможен только через локальный хост без изменений)
2.5 Изменить локальные системные файлы
#修改
vim /etc/rabbitmq/rabbitmq-env.conf
Добавить: NODENAME=кролик
#修改
vim /etc/hostname
#修改本地文件
vim /etc/hosts
#验证服务器是可用的
rabbitmq-server start &
** Плагин консоли выполнения **
rabbitmq-plugins enable rabbitmq_management
#检查端口
lsof -i:5672
#通过
ps -ef|grep rabbitmq
адрес:http://192.168.159.8: 15672
#下载延时插件:
wget https://dl.bintray.com/rabbitmq/communityplugins/3.6.x/rabbitmq_delayed_message_exchange/rabbitmq_delayed_message_exchange-20171215- 3.6.x.zip
#解压延时插件
unzip rabbitmq_delayed_message_exchange-20171215-3.6.x.zip
#把延时插件拷贝到指定目录下
cp rabbitmq_delayed_message_exchange-20171215-3.6.x.ez /usr/lib/rabbitmq/lib/rabbitmq_server-3.7.5/plugins
#启动延时插件
rabbitmq-plugins enable rabbitmq_delayed_message_exchange
3. Командная строка и консоль
**Откройте подключаемый модуль консоли rabbitmq-plugus rabbitmq_management, чтобы открыть консоль **
Проверьте соединение:http://ip:15672(для доступа) имя пользователя пароль гость/гость
3.1 Команды консоли управления
A. Запуск и остановка заказа на обслуживание
#启动服务
rabbitmqctl start_app
Запустите узел rabbitmq, чтобы убедиться, что узел виртуальной машины erlang должен быть готов к выполнению)
#停止服务
rabbitmqctl stop_app
Остановите узел rabbittimq, но не остановите узел erlang. Rabbitmqctl stop остановится.
#查看服务状态
rabbtimqctl status
б. Пользовательские команды управления
#查看所有用户列表
rabbitmqctl list_users
#添加用户
rabbitmqctl add_user luyi luyi
#设置rabbitmq用户的角色
rabbitmqctl set_user_tags luyi administrator
#为用户设置权限
rabbitmqctl set_permissions -p / luyi ".*" ".*" ".*"
rabbitmqctl set_permissions -p <虚拟机> <用户名> ".*" ".*" ".*"
#列出用户权限
rabbitmqctl list_user_permissions luyi
#清除用户权限
rabbitmqctl clear_permissions -p <虚拟机> <用户名>
rabbitmqctl clear_permissions -p / root
#删除用户
rabbitmqctl delete_user root #root是用户名
#修改密码
rabbitmqctl change_password 用户名 新密码
C. Операция виртуального хоста
rabbitmqctl add_vhost /cloudmall добавляет виртуальный хост
rabbitmqctl list_vhosts; просмотреть все виртуальные хосты
rabbitmqctl list_permissions -p /cloudmall Просмотр разрешений виртуального хоста
rabbitmqctl delete_vhost /cloudmall удалить виртуальный хост
г. Команда очереди операций
rabbitmqctl list_queues запрашивает все очереди
rabbitmqctl -p vhostpath purge_queue синий очищает сообщения очереди
е. Расширенные команды
Rabbitmqctl reset удаляет все данные. Эту команду необходимо выполнить после команды rabbitmqctl stop_app (то есть после остановки службы) r
abbitmqctl join_cluster [--ram] сформировать команду кластера
rabbitmqctl cluster_status Просмотр состояния кластера
rabbitmqctl change_cluster_node_type dist|ram Изменить режим хранения данных узла кластера
rabbitmqctl забудьте_кластер_узел [--offline] забыть узел (удалить узел)
rabbitmqctc rename_cluster_node oldnode1 newnode1 oldnode2 newnode2 Изменить имя узла
4. Зачем использовать RabbitMQ
4.1 Реализация асинхронности
4.2 Развязка
4.3 Ограничение пика потока
5. Основы очереди сообщений
5.1 Provider
Производитель сообщения, то есть программа, которая отправляет сообщение
5.2 Consumer
Потребитель сообщений, то есть программа, которая получает сообщение
5.3 Связь без использования очередей сообщений
5.4 Метод связи после использования очереди сообщений
5.5 Что такое очередь
Очередь похожа на магазин в жизни: производители продуктов — производители сообщений, покупатели — потребители сообщений, и они взаимодействуют друг с другом через магазин.
5.6 Связь между очередями и приложениями
Несколько производителей сообщений могут отправлять сообщения в одну и ту же очередь сообщений, а несколько потребителей сообщений могут извлекать сообщения из одной и той же очереди сообщений.
6. Начало работы с RabbitMQ
6.1 Создать проект
6.2 Добавить зависимости
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.amqp</groupId>
<artifactId>spring-rabbit-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
6.3 Настройка глобального конфигурационного файла
#设置应用的名称
spring.application.name=springcloud01-mq
#指定rabbitmq
spring.rabbitmq.host=192.168.234.128
spring.rabbitmq.port=5672
spring.rabbitmq.username=luyi
spring.rabbitmq.password=luyi
6.4 Создать класс конфигурации
/**
* Author: LuYi
* Date: 2019/11/3 14:03
* Description: 队列配置类
*/
@Configuration
public class QueueConfig {
/**
* 创建队列
* @return
*/
@Bean
public Queue createQueue(){
return new Queue("hello-queue");
}
}
6.5 Запись отправителя сообщения
/**
* Author: LuYi
* Date: 2019/11/3 14:06
* Description: 消息发送者
*/
@Component
public class Sender {
@Autowired
private RabbitTemplate rabbitTemplate;
/**
* 发送消息的方法
*/
public void send(String msg){
//向消息队列发送消息
//参数一: 队列名称
//参数二: 消息
rabbitTemplate.convertAndSend("hello-queue", msg);
}
}
6.6 Написание приемников сообщений
/**
* Author: LuYi
* Date: 2019/11/3 14:12
* Description: 消息接收者
*/
@Component
public class Receiver {
/**
* 接收消息的方法,采用消息队列监听机制
* @param msg
*/
@RabbitListener(queues = "hello-queue")
public void process(String msg){
System.out.println("Receiver : " + msg);
}
}
6.7 Тестирование
/**
* 消息队列测试类
*/
@RunWith(SpringRunner.class)
@SpringBootTest(classes = Springcloud01MqApplication.class)
class Springcloud01MqApplicationTests {
@Autowired
private Sender sender;
@Test
void contextLoads() {
}
/**
* 测试消息队列
*/
@Test
public void test1(){
sender.send("Hello RabbitMQ");
}
}
7. Схема RabbitMQ
1.Message (сообщение): сообщение является анонимным, оно состоит из заголовка сообщения и тела сообщения. Тело сообщения непрозрачно, а заголовок сообщения состоит из ряда необязательных атрибутов, включая: ключ маршрутизации (ключ маршрутизации), приоритет (приоритет по отношению к другим сообщениям), режим доставки (указывающий, что сообщение может быть постоянным), хранилище. ), и т.д.
2.Издатель (производитель): ввыключательОтправка сообщенияклиентская программа
3. Потребитель: клиентская программа, которая получает сообщения из очереди сообщений.
4.Exchange (обмен): используется для приема сообщений от клиентов и отправки этих сообщениймаршрутизацияв очередь сообщений на сервере
Три часто используемых переключателя:
a.direct (опубликовать и подписаться, точное соответствие)
b.fanout (трансляция)
c.topic (тема, соответствие правилам)
5.Binding: используется для связи между коммутатором и очередью сообщений, привязка основана наключ маршрутизацииПравила подключения бирж к очередям сообщений.
6.Queue (очередь сообщений): используется для хранения сообщений до тех пор, пока они не будут отправлены потребителям.
7. Ключ маршрутизации: RabbitMQ решает доставить сообщение в эту очередь сообщений.правило. Очередь привязана к коммутатору с помощью ключа маршрутизации. Когда сообщение отправляется на сервер MQ, сообщение будет иметь ключ маршрутизации. Даже если он пуст, RabbitMQ сопоставит его с ключом маршрутизации, используемым для привязки.
Если оно совпадает, сообщение будет отправлено в очередь сообщений, если нет, сообщение отправится в черную дыру.
8. Соединение (ссылка): TCP-соединение, установленное между сервером Rabbit и службой.
9. Канал: канал находится в TCPвиртуальная ссылка, например, кабель — TCP, а канал — независимый пучок волокон. Нет проблем с установлением нескольких каналов для одного соединения TCP.
После открытия TCP создается канал AMQP.Будь то публикация сообщений, получение сообщений или подписка на очереди, все эти действия выполняются через каналы..
10.Virtual Host (виртуальный хост): представляет собой коммутатор и очередь сообщений.Виртуальные хосты — это отдельные серверные домены, которые используют одну и ту же среду аутентификации и шифрования.,Каждый виртуальный хост по сути представляет собой мини-версию сервера RabbitMQ со своими собственными очередями, обменами, привязками и механизмами разрешений. vhost является основой концепции AMQP и должен быть указан во время компоновки.Vhost по умолчанию для RabbitMQ — /
11. Borker: сущность сервера, представляющая очередь сообщений.
Какая связь между коммутаторами и маршрутизаторами?
Коммутатор должен быть связан ключом маршрутизации и очередью сообщений.Если ключ маршрутизации один и тот же, сообщение будет направлено в соответствующую очередь сообщений, что можно понимать какКлючи маршрутизации — это правила, определяющие, в какую очередь сообщений отправляется сообщение.
Восемь, обмен RabbitMQ
1.Direct (публикация и подписка точно совпадают)
1.1 Требования
1.2 Создать проект
rabbitmq-direct-consumer
rabbitmq-direct-provider
1.3 Изменить файл глобальной конфигурации
файл конфигурации потребителя
#设置应用的名称
spring.application.name=springcloud01-mq
#指定rabbitmq
spring.rabbitmq.host=192.168.234.128
spring.rabbitmq.port=5672
spring.rabbitmq.username=luyi
spring.rabbitmq.password=luyi
#设置交换器的名称(处理日志的交换器)
mq.config.exchange=log.direct
#info级别的队列名称
mq.config.queue.info=log.info
#info的路由键
mq.config.queue.info.routing.key=log.info.routing.key
#error级别的队列名称
mq.config.queue.error=log.error
#error的路由键
mq.config.queue.error.routing.key=log.error.routing.key
конфигурационный файл провайдера
#设置应用的名称
spring.application.name=springcloud01-mq
#指定rabbitmq
spring.rabbitmq.host=192.168.234.128
spring.rabbitmq.port=5672
spring.rabbitmq.username=luyi
spring.rabbitmq.password=luyi
#设置交换器的名称(处理日志的交换器)
mq.config.exchange=log.direct
#info的路由键
mq.config.queue.info.routing.key=log.info.routing.key
#error的路由键
mq.config.queue.error.routing.key=log.error.routing.key
1.4 Напишите потребителя
InfoReceiver
/**
* Author: LuYi
* Date: 2019/11/3 14:12
* Description: 消息接收者
*
* @RabbitListener bindings:绑定队列
*
* @QueueBinding value:绑定队列名称
* exchange:配置交换器
*
* @Queue value:配置队列名称
* autoDelete:是否为可删除的临时队列
*
* @Exchange value:为交换器起名
* type:指定当前交换器的类型
*/
@Component
@RabbitListener(
bindings = @QueueBinding(
value = @Queue(value = "${mq.config.queue.info}", autoDelete = "true"),
exchange = @Exchange(value = "${mq.config.exchange}", type = ExchangeTypes.DIRECT),
key = "${mq.config.queue.info.routing.key}"
)
)
public class InfoReceiver {
/**
* 接收消息的方法,采用消息队列监听机制
* @param msg
*/
@RabbitHandler
public void process(String msg){
System.out.println("InfoReceiver : " + msg);
}
}
ErrorReceiver
/**
* Author: LuYi
* Date: 2019/11/3 14:12
* Description: 消息接收者
*
* @RabbitListener bindings:绑定队列
*
* @QueueBinding value:绑定队列名称
* exchange:配置交换器
*
* @Queue value:配置队列名称
* autoDelete:是否为可删除的临时队列
*
* @Exchange value:为交换器起名
* type:指定当前交换器的类型
*/
@Component
@RabbitListener(
bindings = @QueueBinding(
value = @Queue(value = "${mq.config.queue.error}", autoDelete = "true"),
exchange = @Exchange(value = "${mq.config.exchange}", type = ExchangeTypes.DIRECT),
key = "${mq.config.queue.error.routing.key}"
)
)
public class ErrorReceiver {
/**
* 接收消息的方法,采用消息队列监听机制
* @param msg
*/
@RabbitHandler
public void process(String msg){
System.out.println("ErrorReceiver : " + msg);
}
}
1.5 Запись провайдера
/**
* Author: LuYi
* Date: 2019/11/3 14:06
* Description: 消息发送者
*/
@Component
public class Sender {
@Autowired
private RabbitTemplate rabbitTemplate;
//交换器名称
@Value("${mq.config.exchange}")
private String exchange;
//路由键名称
@Value("${mq.config.queue.error.routing.key}")
private String routingKey;
/**
* 发送消息的方法
*/
public void send(String msg){
//向消息队列发送消息
//参数一: 交换器名称
//参数二: 路由键
//参数三: 消息
rabbitTemplate.convertAndSend(exchange, routingKey, msg);
}
}
1.6 Тестирование
/**
* 消息队列测试类
*/
@RunWith(SpringRunner.class)
@SpringBootTest(classes = Springcloud01MqApplication.class)
class Springcloud01MqApplicationTests {
@Autowired
private Sender sender;
@Test
void contextLoads() {
}
@Test
public void test1() throws InterruptedException {
while (true){
Thread.sleep(1000);
sender.send("Hello RabbitMQ");
}
}
}
2.Тематический обменник (тема, соответствие правилам)
2.1 Требования
2.2 Создать проект
rabbitmq-topic-consumer
rabbitmq-topic-provider
2.3 Изменить файл конфигурации
provider
#设置应用的名称
spring.application.name=springcloud01-mq
#指定rabbitmq
spring.rabbitmq.host=192.168.234.128
spring.rabbitmq.port=5672
spring.rabbitmq.username=luyi
spring.rabbitmq.password=luyi
#设置交换器的名称(处理日志的交换器)
mq.config.exchange=log.topic
consumer
#设置应用的名称
spring.application.name=springcloud01-mq
#指定rabbitmq
spring.rabbitmq.host=192.168.234.128
spring.rabbitmq.port=5672
spring.rabbitmq.username=luyi
spring.rabbitmq.password=luyi
#设置交换器的名称(处理日志的交换器)
mq.config.exchange=log.topic
#info级别的队列名称
mq.config.queue.info=log.info
#error级别的队列名称
mq.config.queue.error=log.error
#log级别的队列名称
mq.config.queue.all=log.all
2.4 Запись провайдера
UserSender
/**
* Author: LuYi
* Date: 2019/11/3 14:06
* Description: 消息发送者
*/
@Component
public class UserSender {
@Autowired
private RabbitTemplate rabbitTemplate;
//交换器名称
@Value("${mq.config.exchange}")
private String exchange;
/**
* 发送消息的方法
*/
public void send(String msg){
//向消息队列发送消息
//参数一: 交换器名称
//参数二: 路由键
//参数三: 消息
rabbitTemplate.convertAndSend(exchange, "user.log.debug", "user.log.debug "+msg);
rabbitTemplate.convertAndSend(exchange, "user.log.info", "user.log.info "+msg);
rabbitTemplate.convertAndSend(exchange, "user.log.warn", "user.log.warn "+msg);
rabbitTemplate.convertAndSend(exchange, "user.log.error", "user.log.error "+msg);
}
}
ProductSender
/**
* Author: LuYi
* Date: 2019/11/3 14:06
* Description: 消息发送者
*/
@Component
public class ProductSender {
@Autowired
private RabbitTemplate rabbitTemplate;
//交换器名称
@Value("${mq.config.exchange}")
private String exchange;
/**
* 发送消息的方法
*/
public void send(String msg){
//向消息队列发送消息
//参数一: 交换器名称
//参数二: 路由键
//参数三: 消息
rabbitTemplate.convertAndSend(exchange, "product.log.debug", "product.log.debug "+msg);
rabbitTemplate.convertAndSend(exchange, "product.log.info", "product.log.info "+msg);
rabbitTemplate.convertAndSend(exchange, "product.log.warn", "product.log.warn "+msg);
rabbitTemplate.convertAndSend(exchange, "product.log.error", "product.log.error "+msg);
}
}
OrderSender
/**
* Author: LuYi
* Date: 2019/11/3 14:06
* Description: 消息发送者
*/
@Component
public class OrderSender {
@Autowired
private RabbitTemplate rabbitTemplate;
//交换器名称
@Value("${mq.config.exchange}")
private String exchange;
/**
* 发送消息的方法
*/
public void send(String msg){
//向消息队列发送消息
//参数一: 交换器名称
//参数二: 路由键
//参数三: 消息
rabbitTemplate.convertAndSend(exchange, "order.log.debug", "order.log.debug "+msg);
rabbitTemplate.convertAndSend(exchange, "order.log.info", "order.log.info "+msg);
rabbitTemplate.convertAndSend(exchange, "order.log.warn", "order.log.warn "+msg);
rabbitTemplate.convertAndSend(exchange, "order.log.error", "order.log.error "+msg);
}
}
2.5 Написание потребителя
InfoReceiver
/**
* Author: LuYi
* Date: 2019/11/3 14:12
* Description: 消息接收者
*
* @RabbitListener bindings:绑定队列
*
* @QueueBinding value:绑定队列名称
* exchange:配置交换器
*
* @Queue value:配置队列名称
* autoDelete:是否为可删除的临时队列
*
* @Exchange value:为交换器起名
* type:指定当前交换器的类型
*/
@Component
@RabbitListener(
bindings = @QueueBinding(
value = @Queue(value = "${mq.config.queue.info}", autoDelete = "true"),
exchange = @Exchange(value = "${mq.config.exchange}", type = ExchangeTypes.TOPIC),
key = "*.log.info"
)
)
public class InfoReceiver {
/**
* 接收消息的方法,采用消息队列监听机制
* @param msg
*/
@RabbitHandler
public void process(String msg){
System.out.println("InfoReceiver : " + msg);
}
}
ErrorReceiver
/**
* Author: LuYi
* Date: 2019/11/3 14:12
* Description: 消息接收者
*
* @RabbitListener bindings:绑定队列
*
* @QueueBinding value:绑定队列名称
* exchange:配置交换器
*
* @Queue value:配置队列名称
* autoDelete:是否为可删除的临时队列
*
* @Exchange value:为交换器起名
* type:指定当前交换器的类型
*/
@Component
@RabbitListener(
bindings = @QueueBinding(
value = @Queue(value = "${mq.config.queue.error}", autoDelete = "true"),
exchange = @Exchange(value = "${mq.config.exchange}", type = ExchangeTypes.TOPIC),
key = "*.log.error"
)
)
public class ErrorReceiver {
/**
* 接收消息的方法,采用消息队列监听机制
* @param msg
*/
@RabbitHandler
public void process(String msg){
System.out.println("ErrorReceiver : " + msg);
}
}
AllReceiver
/**
* Author: LuYi
* Date: 2019/11/3 14:12
* Description: 消息接收者
*
* @RabbitListener bindings:绑定队列
*
* @QueueBinding value:绑定队列名称
* exchange:配置交换器
*
* @Queue value:配置队列名称
* autoDelete:是否为可删除的临时队列
*
* @Exchange value:为交换器起名
* type:指定当前交换器的类型
*/
@Component
@RabbitListener(
bindings = @QueueBinding(
value = @Queue(value = "${mq.config.queue.all}", autoDelete = "true"),
exchange = @Exchange(value = "${mq.config.exchange}", type = ExchangeTypes.TOPIC),
key = "*.log.*"
)
)
public class AllReceiver {
/**
* 接收消息的方法,采用消息队列监听机制
* @param msg
*/
@RabbitHandler
public void process(String msg){
System.out.println("AllReceiver : " + msg);
}
}
2.6 Тестирование
/**
* 消息队列测试类
*/
@RunWith(SpringRunner.class)
@SpringBootTest(classes = Springcloud01MqApplication.class)
class Springcloud01MqApplicationTests {
@Autowired
private UserSender userSender;
@Autowired
private ProductSender productSender;
@Autowired
private OrderSender orderSender;
@Test
void contextLoads() {
}
@Test
public void test1() {
userSender.send("UserSender...");
productSender.send("ProductSender...");
orderSender.send("OrderSender...");
}
}
3. Переключатель разветвления (трансляция)
3.1 Требования
3.2 Создать проект
rabbitmq-fanout-consumer
rabbitmq-fanout-provider
3.3 Изменить файл конфигурации
consumer
#设置应用的名称
spring.application.name=springcloud01-mq
#指定rabbitmq
spring.rabbitmq.host=192.168.234.128
spring.rabbitmq.port=5672
spring.rabbitmq.username=luyi
spring.rabbitmq.password=luyi
#设置交换器的名称
mq.config.exchange=order.fanout
#短信队列名称
mq.config.queue.sms=order.sms
#push队列名称
mq.config.queue.push=order.push
provider
#设置应用的名称
spring.application.name=springcloud01-mq
#指定rabbitmq
spring.rabbitmq.host=192.168.234.128
spring.rabbitmq.port=5672
spring.rabbitmq.username=luyi
spring.rabbitmq.password=luyi
#设置交换器的名称(处理日志的交换器)
mq.config.exchange=order.fanout
3.4 Напишите потребителя
SmsReceiver
/**
* Author: LuYi
* Date: 2019/11/3 14:12
* Description: 消息接收者
*
* @RabbitListener bindings:绑定队列
*
* @QueueBinding value:绑定队列名称
* exchange:配置交换器
*
* @Queue value:配置队列名称
* autoDelete:是否为可删除的临时队列
*
* @Exchange value:为交换器起名
* type:指定当前交换器的类型
*/
@Component
@RabbitListener(
bindings = @QueueBinding(
value = @Queue(value = "${mq.config.queue.sms}", autoDelete = "true"),
exchange = @Exchange(value = "${mq.config.exchange}", type = ExchangeTypes.FANOUT)
)
)
public class SmsReceiver {
/**
* 接收消息的方法,采用消息队列监听机制
* @param msg
*/
@RabbitHandler
public void process(String msg){
System.out.println("SmsReceiver : " + msg);
}
}
PushReceiver
/**
* Author: LuYi
* Date: 2019/11/3 14:12
* Description: 消息接收者
*
* @RabbitListener bindings:绑定队列
*
* @QueueBinding value:绑定队列名称
* exchange:配置交换器
*
* @Queue value:配置队列名称
* autoDelete:是否为可删除的临时队列
*
* @Exchange value:为交换器起名
* type:指定当前交换器的类型
*/
@Component
@RabbitListener(
bindings = @QueueBinding(
value = @Queue(value = "${mq.config.queue.push}", autoDelete = "true"),
exchange = @Exchange(value = "${mq.config.exchange}", type = ExchangeTypes.FANOUT)
)
)
public class PushReceiver {
/**
* 接收消息的方法,采用消息队列监听机制
* @param msg
*/
@RabbitHandler
public void process(String msg){
System.out.println("PushReceiver : " + msg);
}
}
3.5 Запись провайдера
/**
* Author: LuYi
* Date: 2019/11/3 14:06
* Description: 消息发送者
*/
@Component
public class OrderSender {
@Autowired
private RabbitTemplate rabbitTemplate;
//交换器名称
@Value("${mq.config.exchange}")
private String exchange;
/**
* 发送消息的方法
*/
public void send(String msg){
//向消息队列发送消息
//参数一: 交换器名称
//参数二: 路由键
//参数三: 消息
rabbitTemplate.convertAndSend(exchange, "", msg);
}
}
3.6 Тестирование
/**
* 消息队列测试类
*/
@RunWith(SpringRunner.class)
@SpringBootTest(classes = Springcloud01MqApplication.class)
class Springcloud01MqApplicationTests {
@Autowired
private OrderSender orderSender;
@Test
void contextLoads() {
}
@Test
public void test1() throws InterruptedException {
while (true){
Thread.sleep(1000);
orderSender.send("Hello RabbitMQ");
}
}
}
4. Используйте RabbitMQ для реализации слабосвязанного дизайна
4.1 Изменить файл конфигурации
#设置应用的名称
spring.application.name=springcloud01-mq
#指定rabbitmq
spring.rabbitmq.host=192.168.234.128
spring.rabbitmq.port=5672
spring.rabbitmq.username=luyi
spring.rabbitmq.password=luyi
#设置交换器的名称
mq.config.exchange=order.fanout
#短信队列名称
mq.config.queue.sms=order.sms
#push队列名称
mq.config.queue.push=order.push
#红包服务队列名称
mq.config.queue.red=order.red
4.2 Добавить приемник
RedReceiver
/**
* Author: LuYi
* Date: 2019/11/4 16:20
* Description: 消息接收者
*
* @RabbitListener bindings:绑定队列
*
* @QueueBinding value:绑定队列名称
* exchange:配置交换器
*
* @Queue value:配置队列名称
* autoDelete:是否为可删除的临时队列
*
* @Exchange value:为交换器起名
* type:指定当前交换器的类型
*/
@Component
@RabbitListener(
bindings = @QueueBinding(
value = @Queue(value = "${mq.config.queue.red}", autoDelete = "true"),
exchange = @Exchange(value = "${mq.config.exchange}", type = ExchangeTypes.FANOUT)
)
)
public class RedReceiver {
@RabbitHandler
public void process(String msg){
System.out.println("给用户发送10元红包 " + msg);
}
}
Девять, обработка сообщений RabbitMQ
1. Обработка сохраняемости сообщений RabbitMQ
1.1 Создать проект
rabbitmq-direct-durable-provider
rabbitmq-direct-durable-consumer
1.2 autoDelete
@Queue: следует ли автоматически удалять очередь, когда все клиенты-потребители отключены, если установлено значение true, означает удаление, false означает, что не удалять
@Exchange: следует ли автоматически удалять обмен, когда все связанные очереди не используются, true: удалить, false: не удалять
2. Механизм ACK подтверждения сообщения в RabbitMQ
-
Что такое подтверждение сообщения ACK
Если потребитель получает сообщение, у сервера есть исключение, и сообщение не может быть получено, что RabbitMQ может гарантировать, что сообщение не будет потеряно с помощью механизма ACK.
-
Механизм подтверждения сообщения ACK
Механизм ACK отправляется потребителем RabbitMQ после получения сообщения.Сообщение не будет удалено из очереди сообщений, пока RabbitMQ не получит ACK..
- Если RabbitMQ не получит идентификатор ACK потребителя, RabbitMQ поместит сообщение в очередь сообщений и отправит его снова.
- В случае кластера RabbitMQ отправит это сообщение другим потребителям в сети. Этот механизм гарантирует, что никакие сообщения не будут потеряны на сервере-потребителе в случае сбоя.
- Сообщения никогда не удаляются из RabbitMQ, будет удален только тогда, когда потребитель правильно отправит ACK, а RabbitMQ также подтвердит это.
- Механизм подтверждения ACK для сообщений включен по умолчанию.
-
Рекомендации по разработке механизма ACK
Если вы забудете ACK, то, когда Потребитель выйдет, Сообщение всегда будет отправлено повторно, чтоЗанимает много памяти RabbitMQ, потому что RabbitMQ будет работать долго, так что эта ситуация фатальна.