Всегда открывать канал публикации RabbitMQ

Я пытаюсь интегрировать snmptrapd и RabbitMQ для доставки уведомлений о ловушках во внешнюю систему.

Моя система состоит из 3 компонентов:

  • Виртуальная машина Linux с snmptrapd и RabbitMQ (Publisher);
  • Виртуальная машина Linux с RabbitMQ (Consumer);
  • Голый металл Linux с докером, поэтому у меня может быть много контейнеров, отправляющих ловушки (используя nping)

Часть snmptrapd проста:

authCommunity execute mycom
traphandle default /root/some_script

В моих первых попытках some_script был написан на Python, но производительность была не идеальной (20 контейнеров, отправляющих 1 ловушку в секунду в течение 10 секунд, я получил только 160 сообщений в потребителе).

#!/usr/bin/env python

import pika
import sys

message = ""

for line in sys.stdin :
        message += (line)

credentials = pika.PlainCredentials('test', 'test')

parameters  = pika.ConnectionParameters('my_ip', 5672, '/', credentials)

connection  = pika.BlockingConnection(parameters)
channel     = connection.channel()

channel.queue_declare(queue='snmp')

channel.basic_publish(exchange='',
                      routing_key='snmp',
                      body=message)
connection.close()

Я перешел на Perl и теперь могу получить 200 ловушек/сообщений.

Мой Perl-скрипт использует Net::AMQP::RabbitMQ

#!/usr/bin/perl

use Net::AMQP::RabbitMQ;

foreach my $line ( <STDIN> ) {
    chomp( $line );
    $message = "$message\n$line";
}

my $mq = Net::AMQP::RabbitMQ->new();

$mq->connect("my_ip", {
    user     => "test",
    password => "test",
    vhost    => "/"
});

$mq->channel_open(1);
$mq->publish(1, "snmp", $message);
$mq->disconnect();

Но я хочу лучше. Я попробовал 200 контейнеров, отправляющих 1 ловушку в секунду, и это с треском провалилось, получая только около 10% сообщений в потребителе.

Я думаю, что это связано с накладными расходами на открытие, публикацию и закрытие канала в RabbitMQ для каждой полученной ловушки, потому что на сетевом уровне я получаю все сообщения (проверено через tcpdump).

Есть ли способ сохранить всегда открытый канал публикации, чтобы мне не приходилось повторно открывать/создавать соединение с очередью?


person Fernando Costa    schedule 29.12.2016    source источник


Ответы (1)


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

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

В любом случае, проблема не в издателе. Это потребитель глючит, если он теряет сообщения.

person ikegami    schedule 29.12.2016
comment
Привет, икегами, я спрашиваю, как я могу поддерживать канал всегда открытым. Я не пытаюсь отправлять сообщения на закрытый канал. Не обращайся со мной так, как будто я глуп. Нет, проблема в издателе. Все сообщения, которые я отправляю издателю, поступают к потребителю. Компьютер, на котором находится издатель, изо всех сил пытается отправить все сообщения, и это не проблема ресурсов, поскольку ни один из процессов не использует весь ЦП/память. - person Fernando Costa; 30.12.2016
comment
Канал — это просто номер, который отправляется с каждым сообщением. - person ikegami; 30.12.2016
comment
Если бы basic_publish не работал, вы бы получили исключение. Проблема не в издателе. - person ikegami; 30.12.2016
comment
Как вы сказали, на сетевом уровне я получаю все сообщения. - person ikegami; 31.12.2016