Как спроектировать клиент-серверную архитектуру

Мне нравится знать архитектуру сервера (на основе TCP) для поддержки большого количества клиентов (не менее 10 КБ) для реализации Fix server. Мои пункты, как мы это проектируем. Как слушать на открытом порту? Используйте выбор или опрос или любую другую функцию. Как обработать ответ клиента? В больших масштабах мы не можем создать один поток для каждого клиента. Если обработка ответа выполняется в другом исполняемом файле, то необходимо совместно использовать запрос и ответ на исполняемый файл сервера через IPC. На нем гораздо больше. Буду признателен, если кто объяснит или даст ссылку. Спасибо


person CrazyC    schedule 28.12.2010    source источник
comment
Вы проверили структуру потоков, используемую в библиотеке quickfix?   -  person DumbCoder    schedule 28.12.2010


Ответы (3)


Архитектура зависит от того, что вы хотите делать с входящими данными клиентов. Я предполагаю, что для каждого входящего сообщения вы будете выполнять некоторые вычисления и, возможно, также возвращать ответ.

В этом случае я бы создал 1 основной поток прослушивателя, который получает все входящие сообщения (на самом деле, если ваше оборудование имеет более 1 физического сетевого устройства, я бы использовал поток прослушивателя для каждого устройства и убедился, что каждый из них прослушивает определенное устройство) . Получите количество процессоров, которые у вас есть на вашем компьютере, и создайте рабочие потоки для каждого процессора и привяжите их каждый поток к одному процессору (возможно, количество рабочих потоков должно быть num_of_cpu-1, чтобы оставить доступный процессор для слушателя и диспетчера).

У каждого потока есть очередь и семафор, основной поток слушателя просто помещает входящие данные в эти очереди. Есть много способов выполнить балансировку нагрузки (мы поговорим об этом позже).

Каждый рабочий поток просто обрабатывает переданные ему запросы и ставит ответ в другую очередь, которую читает диспетчер.

Диспетчер — здесь есть 2 варианта: использовать поток для диспетчера (или поток для каждого сетевого устройства, как для слушателей) или сделать так, чтобы диспетчер был тем же потоком, что и слушатель. Есть некоторое преимущество в том, чтобы поместить их обоих в один и тот же поток, поскольку это упрощает обнаружение потерянного соединения сокета и использование одних и тех же fds для чтения и записи без синхронизации потоков. Однако может случиться так, что использование двух разных потоков даст лучшую производительность, это необходимо протестировать.

Примечание о балансировке нагрузки: это отдельная тема. Проще всего использовать 1 очередь для всех рабочих потоков, но проблема в том, что они должны блокироваться, чтобы извлекать элементы, а блокировка может снизить производительность. (Но вы получаете максимально сбалансированную нагрузку).

Другим довольно простым подходом было бы иметь частную очередь для каждого работника и выполнять циклический перебор при вставке. Через каждые X циклов проверяйте размер всех очередей. Если некоторые очереди намного больше других, оставьте их на следующие X циклов, а затем перепроверьте еще раз. Это не лучший подход, но он прост в реализации и обеспечивает некоторую балансировку нагрузки, при этом блокировка не требуется.

Кстати - есть способ реализовать очередь между 2 потоками без блокировки - но это тоже другая тема.

Я надеюсь, что это поможет, Гай

person Guy Nir    schedule 28.12.2010
comment
Нир, спасибо за информацию. Было бы хорошо, если бы вы также написали что-нибудь здесь, это способ реализовать очередь между двумя потоками без блокировки. - person CrazyC; 29.12.2010
comment
Я сделаю, мне нужно некоторое время, чтобы организовать код, который у меня есть, постараюсь сделать это в ближайшие несколько дней. - person Guy Nir; 29.12.2010
comment
Это не мой код, и я должен сказать, что сам его не проверял, но я видел эту ссылку, размещенную кем-то другим на этом форуме по другому вопросу: liblfds.org Он должен включать очередь, стек и некоторые другие структуры данных, которые не блокируются. - person Guy Nir; 29.12.2010

Отличным источником информации по этой теме является Проблема C10K. Хотя размеры там кажутся немного старыми, методы все еще применимы сегодня.

person Greg Hewgill    schedule 28.12.2010

Если клиент и сервер находятся в защищенной сети, то аспект безопасности должен быть минимальным — до такой степени, что передача зашифрована. Если клиенты и сервер не находятся в защищенной сети, сначала нужно, чтобы сервер и клиент аутентифицировали друг друга, а затем инициировали зашифрованную передачу данных. Для передачи данных достаточно аутентификации на стороне сервера. В конце этой аутентификации используйте ключ сеанса для создания зашифрованного потока данных (симметричного). рассмотрите возможность использования TFTP, он прост в реализации и достаточно хорошо масштабируется.

person Abhi    schedule 28.12.2010