LINUX.ORG.RU

Мультисерверный IPC

 , , ,


0

3

Пусть у нас есть несколько демонов, которые исполняют один и тот же бинарник (например some_d), хоть 50, все они запущены на одной системе.

Нужно сделать так, чтобы можно было послать им всем какие либо-команды через консоль по-типу systemctl, т.е:

  1. Запустили 50 some_d в фоновом режиме
  2. Запустили с консоли some_d -s ps с консоли, чтобы получить на консоль список всех этих запущенных модулей.
  3. Все 50 модулей получают сообщение и посылают обратную инфу о себе клиенту.
  4. Клиент получает 50 или меньше сообщений и выводит инфу в консоль, завершает работу.

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

То есть тут обратная задача: У нас 50 серверов и один клиент, который должен их всех опросить.

Но как такое сделать так, чтобы не пришлось клиенту указывать все 50 портов, куда послать запрос, а сделать всё через один, желательно захардкоженный, TCP порт?



Последнее исправление: OlegUP (всего исправлений: 1)

message queue, pub/sub

на mqtt реализуется несложно, но можно и на zmq

1 «Запустили 50 some_d в фоновом режиме» каждый создал себе топик со своими данными. и задал посмертный weel «удалить топик». Каждый по мере обновляет свои данные

2. «Запустили с консоли some_d -s ps с консоли, чтобы получить на консоль список всех этих запущенных модулей.» - просто отдал список существующих топиков

3. «Все 50 модулей получают сообщение и посылают обратную инфу о себе клиенту». модули могут читать общий топик и исполнять групповые команды

4. «Клиент получает 50 или меньше сообщений и выводит инфу в консоль, завершает работу.» клиент запросил данные в дереве mqtt и их вывел ;-)

можно и через redis :-)

в любом случае, с готовым посредником сильно проще и надёжнее

MKuznetsov ★★★★★
()
Последнее исправление: MKuznetsov (всего исправлений: 1)

Пусть демоны слушают запросы на одном и том же TCP порту, но на разных IP-адресах. Для запуска на одном хосте подойдут адреса 127.0.0.2, 127.0.0.3, … Чтобы их не нужно было добавлять на интерфейс lo, можно использовать опцию IP_FREEBIND.

int fd;
int opt;
struct sockaddr_in local;

fd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);

opt = 1;
setsockopt(fd, SOL_IP, IP_FREEBIND, &opt, sizeof(opt));

memset(&local, 0, sizeof(local));
local.sin_family = AF_INET;
local.sin_port = htons(12345);
local.sin_addr.s_addr = htonl(INADDR_LOOPBACK + 1); /* 127.0.0.2 */
bind(fd, (struct sockaddr *)&local, sizeof(local));
listen(fd, 128);

Демон при запуске может пробовать сбиндиться на адреса из списка 127.0.0.2…127.0.0.100, сядет на первый незанятый. А cli утилита пусть пытается сконнектиться со всеми адресами 127.0.0.2…127.0.0.100, и общается со всеми демонами, до которых удалось установить коннект.

iliyap ★★★★★
()
Последнее исправление: iliyap (всего исправлений: 1)

multicast очень хорошо подходит для таких целей в условиях хоста и локальной сети.

Единственная проблема - оно udp-шное со всеми вытекающими проблемами.

vel ★★★★★
()

не надо так делать, пусть демоны раз в секунду/минуту/год апдейтят инфу о себе в каком-либо стораже (mq/db/prometheus/logstash/tmpfs/whatever), а утилита уже читает из этого стоража. как расшарить стораж по сети придумаешь потом, ну или сразу возьмёшь заточенный под сеть

peacelove
()

Сервер сообщений. Перед запуском демонов запускается сервер сообщений. Дальше запускаются демоны и каждый из них подключается к серверу сообщений, сервер сообщений ведёт список активных демонов. Пользователь будет посылать команду на сервер сообщений, который уже передаст ее́ на демоны и вернёт ответ при необходимости.

u5er ★★
()

Есть разные варианты. Можно взять zookeeper или что-то подобное. А можно сразу k8s, например minikube или kind.

потому что в будущем возможно это распространится не на систему, а на кластер

Тем более.

no-such-file ★★★★★
()
Последнее исправление: no-such-file (всего исправлений: 1)