RabbitMQ, Python и Windows. Step By Step

Работа с шиной RabbitMQ, используя Python на Windows. Пошаговый быстрый старт.

Здравствуйте! Хочу поделиться своим опытом написания на языке Python служб для работы с шиной RabbitMQ. Видел много публикаций, в тч и на этом ресурсе, с реализацией на C#. Я решил пойти по более простому и короткому пути — не интегрировать отправку и получения сообщений в 1С. 1С у меня занимается только генерацией файлов обмена. Всю остальную работу уже делают службы Windows, написанные на Python.

Ну что ж, приступим…

Для начала установил я Python с оф сайта ссылка для Windows.

Далее с помощью системы управления пакетами pip нужно установить пакет для работы с RabbitMQ — pika. В командной строке CMD нужно ввести команду:

pip install pika

После установки пакета можно приступать к написанию скриптов на Python.

Сред для разработки на Python очень много. Лично я использовал JetBrains PyCharm Community Edition ссылка. После установки нужно создать проект и пару файлов .py. Один из файлов будет службой отправки сообщений, другой — получения из RabbitMQ.

1. Пример файла sender.py для службы отправки сообщения:

#!/usr/bin/env python
import pika, os, sys

# имя файла обмена для отправки в RMQ
fileName = "d:/to_rabbit.xml"

credentials = pika.PlainCredentials('user_name', 'password')
connection = pika.BlockingConnection(pika.ConnectionParameters('host_name',
5672,
'/',
credentials))
channel = connection.channel()

# создаем очередь с заданным именем для отправки
channel.queue_declare(queue='send_queue', durable=True)

while True:
# если файл существует, осуществляем отправку
if os.path.isfile(fileName):

file = open(fileName, "r", encoding="utf-8")
messageBody = file.read()
file.close()

channel.basic_publish(exchange='exchange',
routing_key='key',
body=messageBody,
properties=pika.BasicProperties(delivery_mode=2,)
)

#удалим файл после отправки
os.remove(fileName)

2. Пример файла consumer.py для получения сообщения:

#!/usr/bin/env python
import pika, time, sys

# имя файла, который будем забирать для обработки в 1С
fileName = "d:/from_rabbit.xml"

credentials = pika.PlainCredentials('user_name', 'password')
connection = pika.BlockingConnection(pika.ConnectionParameters('host_name',
5672,
'/',
credentials))
channel = connection.channel()

# забираем из очереди
channel.queue_declare(queue='consume_queue', durable=True)

def callback(ch, method, properties, body):
file = open(fileName, "w", encoding="utf-8")
file.write(body.decode("utf-8"))
file.close()
# время ожидания чтобы на стороне 1С успел обработаться файл
time.sleep(body.count(b'.')/100)
ch.basic_ack(delivery_tag = method.delivery_tag)

channel.basic_qos(prefetch_count=1)

channel.basic_consume(callback,
queue='consume_queue')

channel.start_consuming()

Параметры user_name, password, host_name, send_queueconsume_queueexchange и key нужно задать самостоятельно.

Лично я использовал 2 очереди для обмена сообщений: одна для отправки send_queue, другая для получения consume_queue. Так же в консоли RabbitMQ нужно не забыть забиндить (Bind) наши очереди на наш обмен exchange.

 

Все, скрипты готовы. Осталось совсем чуть-чуть — создать на их основании службы для отправки и получения. Для этого я использовал утилиту nssm ссылка.

Качаем, распаковываем и создаем службы:

1. Служба для отправки (команда в CMD):

d:
ssm-2.24win64>nssm.exe install SenderRMQ

2. Служба для получения (команда в CMD):

d:
ssm-2.24win64>nssm.exe install ConsumerRMQ

После нажатия Install service службы установлены. Наш обмен готов. Спасибо за внимание!

7 Comments

  1. s_vidyakin

    а если 1С не шмогла обработать файл, как сказать отдавшей стороне что надо его исправить и повторить выгрузку?

    Reply
  2. kuzyara

    (1) транспорт новый, а протокол то старый 😉

    И раз, и два.

    Reply
  3. w.r.

    (1)

    (2)

    Именно такая реализация у меня есть — обмен сделан через план обмена с контролем по номеру принятого и отправленного сообщений. То есть контроль работает на стороне 1С.

    RabbitMQ для меня просто транспорт сообщений между системами.

    Хотя можно реализовать аналогичный функционал (записывать номера принятого и отправленного сообщений) в свойство headres в properties

    Метод basic_publish для отправки:

    properties=pika.BasicProperties(delivery_mode=2,headers={‘MessageNo’:1, ‘ReceivedNo’:1})

    Метод callback для получения

    MessageNo = properties.headers[‘MessageNo’]
    ReceivedNo= properties.headers[‘ReceivedNo’]
    Reply
  4. minimajack
    time.sleep(body.count(b’.’)/100)

    — дичь

    А что будет если службу 1С приостановили?

    Reply
  5. w.r.

    (4) значит сообщение не обработается в 1С и система 2 отправит его снова вместе с новыми данными, потому что от 1С не придет ответа о его обработке

    Reply
  6. hazyaka

    Хочу понять чем обыкновенный ftp хуже? или почтовый сервер?

    Reply
  7. w.r.

    (6) поддержка очереди сообщений + можно одно сообщение нескольким потребителям отдавать

    Reply

Leave a Comment

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