Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Delphi Новый топик    Ответить
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
 Cервер обработки сообщений  [new]
чччД
Guest
Есть сотня клиентов, каждый из которых ~ сто раз в секунду что-то хочет от сервера.
Это "что-то" (чего хотят клиенты от сервера) небольшое и уже (почти) готовое - "только спроси, сразу отдам".

Протокол tcp.

Возможно, клиентов будет не сто, а тыща.
11 сен 14, 01:59    [16562010]     Ответить | Цитировать Сообщить модератору
 Re: Вжжжик!  [new]
чччД
Guest
Давно хотел ZeroMQ потрогать.

Кроме чтения описания и небольших тестов - не пробовал.

Только другим советы давал...


Для Delphi есть библиотека - оболочка: https://github.com/bvarga/delphizmq
11 сен 14, 02:12    [16562014]     Ответить | Цитировать Сообщить модератору
 Re: Вжжжик!  [new]
чччД
Guest
Засада:

The package contains a wrapper (zmq.pas), and a higher level api (zmqapi.pas). It should work with ZMQ 2.2.x, and with 3.2.x.


А последний Stable Release на сегодня - 4.0.4.

Берем предыдущую 3.2.4, от греха подальше: http://miru.hk/archive/ZeroMQ-3.2.4~miru1.0-x86.exe

Из всей инсталляции нужна только библиотека libzmq-v90-mt-3_2_4.dll (ядро системы обмена сообщения, скомпилированная MS VS 2008, "релизный" вариант) -> переименовываем в libzmq.dll и помещаем в каталог с будущими исполняемыми файлами.
11 сен 14, 02:26    [16562018]     Ответить | Цитировать Сообщить модератору
 Re: Вжжжик!  [new]
чччД
Guest
Не забываем, что для приложений, созданных в MS VS 2008, требуется "редистрибутабле пацк": http://www.microsoft.com/ru-ru/download/details.aspx?id=5582
Скорее всего, он у всех уже установлен, но мало ли.
11 сен 14, 02:31    [16562019]     Ответить | Цитировать Сообщить модератору
 Re: Вжжжик!  [new]
чччД
Guest
Инсталлер можно не грузить, а построить библиотечку самостоятельно, из исходников: http://download.zeromq.org/zeromq-3.2.4.zip

Для построения нужна MS VS 2008 Pro для С++. Можно обойтись и бесплатной Express версией MS VS, но тогда пакет библиотек для построения в Windows придется грузить отдельно.

В инструкции пишут, что можно обойтись и MinGW: http://zeromq.org/build:mingw Однако, лично мне этого сделать так и не удалось.

В общем, MS VS 2008. Можно и более новую студию но, пишут, что приложения не будет работать на Win2K и WinXP.

Распаковываем скаченные исходники, открываем каталог builds\msvc, открываем из MS VS "решение" msvc.sln
Выбираем конфигурация "Release" и даем команду "построить решение" (F7).
Идём пить чай, это не дельфи, это минут на десять.
...
11 сен 14, 02:42    [16562021]     Ответить | Цитировать Сообщить модератору
 Re: Вжжжик!  [new]
чччД
Guest
Готово.
В подкаталоге \lib появилась нужная библиотека: libzmq.dll. Какая-то она подозрительно маленькая (всего 186кБ), по сравнению с теми вариантами, что в инсталляторе были, но, надеюсь, это не беда :

К сообщению приложен файл (libzmq.7z - 65Kb) cкачать
11 сен 14, 02:48    [16562023]     Ответить | Цитировать Сообщить модератору
 Re: Вжжжик!  [new]
Judo
Member

Откуда:
Сообщений: 688
чччД - а зачем ты все это написал ?
11 сен 14, 02:59    [16562026]     Ответить | Цитировать Сообщить модератору
 Re: Вжжжик!  [new]
чччД
Guest
Кроме "любезно приложенной мной" () dll - ки, для дельфикодинга нужен фал, описывающих функции в этой библиотеке.
Это есть вот здесь: https://codeload.github.com/bvarga/delphizmq/zip/master

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

1. zmq.pas
2. zmq.inc

Если хочется работать не с функциями dll, а использовать дельфийские классы - обертки, то можно использоват еще два файлика:

3. zhelpers.pas
4. zmqapi.pas

Как работать - примерно описано в файле README.md.
11 сен 14, 02:59    [16562027]     Ответить | Цитировать Сообщить модератору
 Re: Вжжжик!  [new]
чччД
Guest
Всё! Будем писать сверхскоростной сервер обработки сообщений. :)

...пошел варить кофе.
11 сен 14, 03:01    [16562030]     Ответить | Цитировать Сообщить модератору
 Re: Вжжжик!  [new]
Judo
Member

Откуда:
Сообщений: 688
README
You should use the higher level api, which'll save you a lot of time, and incidentally
the code'll be easier to read.

Очередная реинкарнация )
11 сен 14, 03:03    [16562033]     Ответить | Цитировать Сообщить модератору
 Re: Вжжжик!  [new]
чччД
Guest
Дополнение к ТЗ (16562010): сервер получает беззнаковое 32 - разрядное целое и возвращает квадрат этого числа в беззнаковом 64м целом.
11 сен 14, 03:04    [16562034]     Ответить | Цитировать Сообщить модератору
 Re: Вжжжик!  [new]
чччД
Guest
В общем, все вышеупомянутые .pas и inc файлы складываем в одно место и указываем Delphi, чтобы она это место знало (например, добавляем директорию в library path).

И так, сервер, готов:
program ConsoleServer;

{$APPTYPE CONSOLE}

uses
  SysUtils, ZMQ;
var
  fContext: Pointer;
  fResponder: Pointer;
  fStatus: Cardinal;
  fInValue: Cardinal;
  fOutValue: UInt64;

begin
  fContext := zmq_ctx_new();
  fResponder := zmq_socket(fContext, ZMQ_REP);
  fStatus := zmq_bind(fResponder, 'tcp://*:5555');
  assert(fStatus = 0);
  Writeln('Starting...');
  while (True) do begin
    zmq_recv(fResponder, fInValue, SizeOf(fInValue), 0);
    Writeln('Received: ', fInValue);
    fOutValue := fInValue * fInValue;
    zmq_send(fResponder, fOutValue, SizeOf(fOutValue), 0);
  end;

end.

Сервер в цикле слушает порт №5555, читает из порта число и пишет значение квадрата числа.

Надеюсь, он будет работать безупречно. А пока он только компилируется, стартует и выводит Starting...
11 сен 14, 03:32    [16562041]     Ответить | Цитировать Сообщить модератору
 Re: Вжжжик!  [new]
чччД
Guest
Клиент:

program ConsoleClient;

{$APPTYPE CONSOLE}

uses
  SysUtils, ZMQ;

const
  c_iter = 999999;
var
  context: Pointer;
  requester: Pointer;
  i: Integer;
  f_ScrValue: Cardinal;
  f_qValue: UInt64;

begin
  Writeln('Client starting...');
  Randomize();

  context := zmq_ctx_new();
  requester := zmq_socket(context, ZMQ_REQ);
  zmq_connect(requester, 'tcp://localhost:5555');

  for i := 0 to c_iter do begin
    f_ScrValue := Random(-1);
    Writeln('Sending ', f_ScrValue);
    zmq_send(requester, f_ScrValue, SizeOf(f_ScrValue), 0);
    zmq_recv(requester, f_qValue, SizeOf(f_qValue), 0);
    Writeln('Received ', f_qValue);
  end;

  zmq_close(requester);
  zmq_ctx_destroy(context);
end.


Судя по выводимым сообщениям, все работает правильно.
11 сен 14, 04:01    [16562066]     Ответить | Цитировать Сообщить модератору
 Re: Вжжжик!  [new]
чччД
Guest
Нужно убрать из циклов тормозящие Writeln(), запустить сервер на удаленном компе и оценить скорость работы с несколькими клиентами...
...
...завтра.
11 сен 14, 04:02    [16562067]     Ответить | Цитировать Сообщить модератору
 Re: Cервер обработки сообщений  [new]
чччД
Guest
Меряю.
Разное количество клиентов. Клиенты запускаются и ждут, пока запустится сервер.
Сервер выполняет 1 млн запросов и выводит сообщение о времени выполнения.
...
При попытке выполнить 1024 коннекта получил сообщение "assertion failed fds.size() <= fd_setsize"...
Посмотрел в исходниках dll на этот самый fd_setsize - он там действительно FD_SETSIZE равен 1024.
Просто уменьшил число клиентов до 1000.
...
11 сен 14, 06:14    [16562134]     Ответить | Цитировать Сообщить модератору
 Re: Cервер обработки сообщений  [new]
чччД
Guest
..

К сообщению приложен файл. Размер - 8Kb
11 сен 14, 06:15    [16562135]     Ответить | Цитировать Сообщить модератору
 Re: Cервер обработки сообщений  [new]
чччД
Guest
То есть, после двух сотен клиентов - на пределе, еле справляется.
Нужно попробовать разнести серверную части в несколько потоков.

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


 zmq_connect(requester, 'tcp://Host1:5555');
 zmq_connect(requester, 'tcp://Host2:5555');

- и все. Запросы будут поочередно отсылаться разным серверам.
Но хочется выжать все из одного процесса сервера.
11 сен 14, 06:19    [16562142]     Ответить | Цитировать Сообщить модератору
 Re: Cервер обработки сообщений  [new]
prog123
Guest
чччД
То есть, после двух сотен клиентов - на пределе, еле справляется.
Нужно попробовать разнести серверную части в несколько потоков.

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


 zmq_connect(requester, 'tcp://Host1:5555');
 zmq_connect(requester, 'tcp://Host2:5555');

- и все. Запросы будут поочередно отсылаться разным серверам.
Но хочется выжать все из одного процесса сервера.


Профилировщиком шмальни, где он супостат чешетца..
11 сен 14, 06:55    [16562180]     Ответить | Цитировать Сообщить модератору
 Re: Cервер обработки сообщений  [new]
s62
Member

Откуда: Жуковский
Сообщений: 911
чччД,
А написать сервер на портах завершения ввода/вывода (IO completion ports)? Пишут, что это чуть не лучший вариант под Windows для обработки многих запросов.
http://msdn.microsoft.com/ru-ru/library/windows/desktop/aa365198(v=vs.85).aspx
http://habrahabr.ru/post/145140/
11 сен 14, 09:51    [16562549]     Ответить | Цитировать Сообщить модератору
 Re: Cервер обработки сообщений  [new]
fd00ch
Member

Откуда: Нижний Новгород
Сообщений: 5913
чччД, не пробовал в тот же сценарий запрячь что-либо из этого набора, чтобы потом можно было как-то сравнить результаты?
11 сен 14, 13:35    [16563662]     Ответить | Цитировать Сообщить модератору
 Re: Cервер обработки сообщений  [new]
чччД
Guest
Интересно, что длина сообщений может быть любой (почти: Integer), просто короткие сообщения доставляются прямо в теле сообщения, а для длинных специально автоматически выделяется память и в сообщении - адрес начала блока.
После чтения следующего сообщения предыдущее "пропадает".
17 сен 14, 05:10    [16583807]     Ответить | Цитировать Сообщить модератору
 Re: Cервер обработки сообщений  [new]
чччД
Guest
...в общем, выяснилось, что клиентов не будет больше сотни, и скорость обработки вполне приемлима.

...
~~~~~~~~~~~~~~~~~~~~~~~~

Таким образом, был рассмотрен режим обмена сообщениями по схеме "Запрос-Ответ" (Request-Reply).
Схема работы "Запрос-Ответ": сервер слушает сокет, принимает сообщения от всех желающих, и отвечает на запросы.

...
~~~~~~~~~~~~~~~~~~~~~~~~

Бывает, что нужно по-другому. Сервер должен оповестить клиентов о каком-то событии.
Клиенты отправляют серверу заявку, что они готовы получать сообщения о наступившем событии ("подписываются" на событие).
Одних клиентов могут интересовать одни события, других - другие.
А сервера вообще не волнует, кому из клиентов что нужно. Сервер - это как бы радиоприемник, вещающий в эфир. Кто слушает - молодец. А кто не слушает - тот ССЗБ.

Такая схема называется "Издатель - Подписчик" (Publisher-Subscriber).

Пример.

Автоматическая метеостанция измеряет температуру, атмосферное давление и скорость ветра. Результаты измерений время от времени (например, после завершения цикла измрений) передаются "всем заинтересованным лицам".
Кого-то интересует всё, кому-то нужна температура, кого-то волнует только скорость ветра.

Пишем код метеостанции (), то есть, сервер-издатель :
17 сен 14, 06:08    [16583825]     Ответить | Цитировать Сообщить модератору
 Re: Cервер обработки сообщений  [new]
dred2k
Member

Откуда: Подольск
Сообщений: 341
Через сокеты не тестил ? Synapse, к примеру.
Интересно, сильно уступит по скорости.
17 сен 14, 10:15    [16584285]     Ответить | Цитировать Сообщить модератору
 Re: Cервер обработки сообщений  [new]
Dimitry Sibiryakov
Member

Откуда:
Сообщений: 47373

чччД
А сервера вообще не волнует, кому из клиентов что нужно. Сервер - это как бы
радиоприемник, вещающий в эфир. Кто слушает - молодец. А кто не слушает - тот ССЗБ.

В смысле, используешь UDP broadcast или TCP multicast?

Posted via ActualForum NNTP Server 1.5

17 сен 14, 12:16    [16584944]     Ответить | Цитировать Сообщить модератору
 Re: Cервер обработки сообщений  [new]
чччД
Guest
Dimitry Sibiryakov
чччД
А сервера вообще не волнует, кому из клиентов что нужно. Сервер - это как бы
радиоприемник, вещающий в эфир. Кто слушает - молодец. А кто не слушает - тот ССЗБ.

В смысле, используешь UDP broadcast или TCP multicast?

ZeroMQ вроде точно не использует UDP.
Как реализовано - можно посмотреть в исходниках libzmq.dll. Картинка с другого сайта.
Прикладной программист выбирает транспортный уровень для сокета с помощью zmq_bind:

  zmq_connect(requester, 'tcp://localhost:5555');

...

Заявлено, что ZeroMQ позволяет обмениваться между разными системами "в сети", между процессами и между потоками в рамках процесса.

Я ничего, кроме tcp пока не пробовал.

В документации пишут, что в данны момент поддерживается работа на базе TCP, IPC (на POSIX), inproc, TIPC ("Transparent IPC" от Ericsson), SCTP, PGM, NORM и SOCKS5 (насчет последнего упоминают особо - типа, теперь ZeroMQ может и через сеть Tor ходить)
17 сен 14, 15:59    [16586347]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2   вперед  Ctrl      все
Все форумы / Delphi Ответить