Предпосылки создания своей компоненты
- Мы активно развиваем свой проект Адаптер (о нем мы уже писали на инфостарте), в котором реализован обмен через RabbitMQ
- Т.к. 1С напрямую не поддерживает протокол AMQP (а для обмена с брокером RabbitMQ через http есть ограничения) нам потребовалась внешняя компонента
- Раньше мы использовали стороннюю компоненту Yellow RabbitMQ, но для некоторых наших заказчиков было важно избежать зависимости от конкретного поставщика, и наличие закрытого кода (в виде скомпилированной компоненты) являлось важным аргументом против использования Yellow RabbitMQ
- Технически создание своей компоненты нам казалось не сложным
- У нас уже был весь набор тестов для Адаптера, который позволил нам быть уверенными, что наша компонента работает
- Хотелось получить возможность самостоятельного развития компоненты
Наши цели публикации исходных кодов компоненты Pink RabbitMQ:
- Она у нас все равно есть, и для нас это "ничего не стоит"
- Мы хотим улучшить код компоненты
- Мы хотим "продвинуть кролика в массы", как "среду" обмена данными, и как средство для построения событийно-ориентированных интеграций
- Мы надеемся, что это будет полезно и для нашего Адаптера, как инструмента организации обмена
Особенности компоненты Pink RabbitMQ:
- Описание API компоненты содержится в https://github.com/BITERP/PinkRabbitMQ/blob/master/README.md
- Представляет собой Native API компоненту для 1С Предприятия 8 (Windows 32bit и 64bit). Для Linux мы не компилировали, но радикальных препятствий для этого нет (примерно понятно, какие нужно для этого сделать доработки)
- С точки зрения API компонента практически полностью совместима с Yellow RabbitMQ т.е. в Адаптер мы просто замени компоненту на нашу, но те механизмы, которые не нужны в Адаптере мы не реализовывали
- В основе компоненты лежат "свежие" библиотеки
- Для обеспечения совместимости с Yellow RabbitMQ мы внутри компоненты превратили асинхронные методы библиотеки в синхронные, что немного повлияло на производительность
- При разработке исходный код компоненты проверяются Sonar Cube и тестируются BDD тестами Адаптера (см. бэджи в репозитории)
Вопросы производительности
Поскольку мы использовали ранее Yellow RabbitMQ, то и сравнивали с ней:
Простой синтетический тест
Метод |
Yellow RabbitMQ |
Pink RabbitMQ |
---|---|---|
Последовательная отправка 1000 сообщений (сек) |
28.30 |
57.54 |
Последовательное получение 1000 сообщений (с отправкой 2000 логов) (сек) | 220.41 | 390.70 |
Тест на реальном проекте где в Адаптере компонента Yellow RabbitMQ была заменена на Pink RabbitMQ.
У нас не было цели провести отдельный чистый тест, мы просто хотели убедиться, что на одном из наших проектов, на котором мы недавно перешли с обмена БСП (не типового) на обмен через RabbitMQ при переходе на компоненту Pink RabbitMQ не будет проблем с производительностью.
В рамках теста из базы УТ10.3 в базу ERP переносился 1241 документ и проводился в ERP (реализации товаров превращались в поступления)
Метод |
Yellow RabbitMQ |
Pink RabbitMQ |
План обмена из БСП в формате КД2 |
---|---|---|---|
Длительность отправки из УТ 10.3 (час) | 1:47 | 2:19 | 1:38 |
Длительность загрузки в ERP (час) | 3:10 | 2:48 | 3:36 |
Общая длительность от момента как начали отправлять до момента, что все получили (час) | 3:12 | 2:51 | 3:47 |
т.е. мы видим, что на реальном проекте
- Меньшая скорость работы самой компоненты "теряется" во времени записи и проведения реальных загруженных документов
- Общая длительность обмена зависит от прочих факторов гораздо больше, чем от скорости работы самой компоненты
по этому пока мы не считаем меньшую производительность Pink RabbitMQ проблемой
API
Компонента имеет ряд методов для работы из встроенного языка 1С. Параметры с тегом [НЕ РЕАЛИЗОВАНО] имеют пустую реализацию, но передавать их все равно требуется. Параметры с тегом [НЕОБЯЗАТЕЛЬНЫЙ] можно не передавать. Список методов:
Connect - устанавливает соединение с сервером RabbitMQ
Параметры:
- host - Строка - Адрес сервера RabbitMQ
- port - Число - Порт работы через tcp (обычно 5672)
- login - Строка - Имя пользователя
- pwd - Строка - Пароль пользователя
- vhost - Строка - Vhost пользователя
- pingRate - Число - [НЕ РЕАЛИЗОВАНО][НЕОБЯЗАТЕЛЬНЫЙ]. Частота пульса
DeclareExchange - Объявить точку обмена
Параметры:
- name - Строка - Имя exchange
- type - Строка - Тип точки обмена. Поддерживаются "direct", "fanout", "topic"
- onlyCheckIfExists - Булево - [НЕ РЕАЛИЗОВАНО] Не создавать новую, выбросить исключение, если такой точки нет.
- durable - Булево - Сохранять сообщения на диске на случай рестарта RMQ (не рекомендуется)
- autodelete - Булево - Удалить после того, как от точки будут отвязаны все очереди.
DeleteExchange - Удаляет очередь с сервера
Параметры:
- name - Строка- Имя точки обмена.
- ifunused - Булево - Удаление будет выполнено, только если точка обмена не используется.
DeclareQueue - Объявить очередь
Параметры:
- name - Строка - Имя объявляемой очереди.
- onlyCheckIfExists - Булево - [НЕ РЕАЛИЗОВАНО] Не создавать очередь с таким именем, использовать существующую
- save - Булево - Кешировать сообщения на диске, на случай падения RMQ.
- exclusive - Булево - [НЕ РЕАЛИЗОВАНО] Только текущее соединение может иметь доступ к этой очереди.
- autodelete - Булево - Удалить очередь если к ней был подключен, а затем отключен читающий клиент.
Возвращаемое значение:
- Имя очереди, заданное явно в 1-м параметре.
DeleteQueue - Удаляет очередь с сервера
Параметры:
- name - Строка - Имя очереди
- onlyIfIdle - Булево - Удаление будет выполнено, только если очередь не используется
- onlyIfEmpty - Булево - Удаление будет выполнено, только если очередь пуста
BindQueue - Установить связь очереди. Создает маршрут от точки обмена до очереди.
Параметры:
- queue - Строка - Имя очереди
- exchange - Строка - Имя точки обмена
- routingKey - Строка - Rлюч маршрутизации.
UnbindQueue - Отсоединяет очередь от точки обмена.
Параметры:
- queue - Строка - Имя очереди
- exchange - Строка - Имя точки обмена
- routingKey - Строка - Rлюч маршрутизации.
BasicPublish - Отправить сообщение
Параметры:
- exchange - Строка - Имя точки в которую отправляется сообщение
- routingKey - Строка - Ключ маршрутизации (см. руководство RMQ)
- message - Строка - Тело сообщения
- livingTime - Число - [НЕ РЕАЛИЗОВАНО] Время жизни сообщения в миллисекундах
- persist - Булево - [НЕ РЕАЛИЗОВАНО] Сбрасывать сообщение на диск
BasicReject - Отказывается от последнего полученного сообщения. Работает по принципу Ack, но в обратную сторону.
Параметры отсутствуют
BasicConsume - Начать чтение. Регистрирует потребителя сообщений для очереди.
Параметры:
- queue - Строка - Очередь из которой будем читать сообщения.
- consumerId - Строка - [НЕ РЕАЛИЗОВАНО] имя потребителя. Если не задан, то имя потребителя сгенерирует сервер и вернет из метода
- noConfirm - Булево - [НЕ РЕАЛИЗОВАНО] не ждать подтверждения обработки. Сообщения будут удалены из очереди сразу после отправки на клиента.
- exclusive - Булево - [НЕ РЕАЛИЗОВАНО] монопольно захватить очередь
- selectSize - Число - [НЕ РЕАЛИЗОВАНО] количество сообщений единовременно отправляемых клиенту. Оптимизационный параметр, если > 1 усложняет программирование клиента
Возвращаемое значение:
- Строка. Имя потребителя, сгенерированное сервером или переданное в параметре ИмяПотребителя.
BasicConsumeMessage - Получить сообщение
Параметры:
- consumerId - Строка - [НЕ РЕАЛИЗОВАНО] Имя зарегистрированного потребителя
- outdata - Строка - Выходной параметр. Тело сообщения.
- timeout - Число - Таймаут ожидания сообщения в миллисекундах. 0 означает без ожидания
BasicCancel - Закрывает канал для чтения сообщений
Параметры:
- channelId - Строка - Имя созданного ранее потребителя.
BasicAck Отсылает серверу подтверждение (ack), что сообщение обработано и его можно удалить. Подтвердить можно только последнее прочитанное сообщение.
Параметры отсутствуют
GetLastError - получает информацию о последней ошибке
Параметры отсутствуют
Возвращаемое значение:
- Строка - Последнее сообщение ошибки
Наши ближайшие планы:
- Мы собираемся поддерживать компоненту, т.к. она является частью нашего решения Адаптер
- С точки зрения функционала ходим добавить в компоненту асинхронные методы (как в 1С), что увеличит скорость работы и немного упростит алгоритмы Адаптера
Как начать использовать Pink RabbitMQ:
- Скачать демонстрационную обработку, приложенную к статье (компонента находится в ней в виде макета)
- Скачать из репозитория исходники и воспользоваться инструкцией из readme.md
Интересные технические особенности:
- Источником вдохновения послужила статья https://habr.com/ru/post/253317/
- Сборка компоненты осуществляется как через sln проект на VS Studio 2019, так и через cmake (см. readme.md)
- Все зависимости проекта (в частности POCO и AMQP) поставляются прекомпилированными либами для простоты сборки (поэтому репозиторий много весит, но проект собирается элементарно )
Как стать контрибьютером:
- Репозиторий проекта https://github.com/BITERP/PinkRabbitMQ
- Как обычно, создавайте issues, делайте форки, вносите доработки, собирайте и проверяйте компоненту и делайте пулл-реквест
- Мы со своей стороны будем принимать пулл-реквесты после
- прохождения проверок Sonar Cube и BDD тестами Адаптера
- оценки соответствия предлагаемых изменений концепции/планам развития Pink RabbitMQ
Ждем ваших вопросов/замечаний/предложений