Мне нравится знать архитектуру сервера (на основе TCP) для поддержки большого количества клиентов (не менее 10 КБ) для реализации Fix server. Мои пункты, как мы это проектируем. Как слушать на открытом порту? Используйте выбор или опрос или любую другую функцию. Как обработать ответ клиента? В больших масштабах мы не можем создать один поток для каждого клиента. Если обработка ответа выполняется в другом исполняемом файле, то необходимо совместно использовать запрос и ответ на исполняемый файл сервера через IPC. На нем гораздо больше. Буду признателен, если кто объяснит или даст ссылку. Спасибо
Как спроектировать клиент-серверную архитектуру
Ответы (3)
Архитектура зависит от того, что вы хотите делать с входящими данными клиентов. Я предполагаю, что для каждого входящего сообщения вы будете выполнять некоторые вычисления и, возможно, также возвращать ответ.
В этом случае я бы создал 1 основной поток прослушивателя, который получает все входящие сообщения (на самом деле, если ваше оборудование имеет более 1 физического сетевого устройства, я бы использовал поток прослушивателя для каждого устройства и убедился, что каждый из них прослушивает определенное устройство) . Получите количество процессоров, которые у вас есть на вашем компьютере, и создайте рабочие потоки для каждого процессора и привяжите их каждый поток к одному процессору (возможно, количество рабочих потоков должно быть num_of_cpu-1, чтобы оставить доступный процессор для слушателя и диспетчера).
У каждого потока есть очередь и семафор, основной поток слушателя просто помещает входящие данные в эти очереди. Есть много способов выполнить балансировку нагрузки (мы поговорим об этом позже).
Каждый рабочий поток просто обрабатывает переданные ему запросы и ставит ответ в другую очередь, которую читает диспетчер.
Диспетчер — здесь есть 2 варианта: использовать поток для диспетчера (или поток для каждого сетевого устройства, как для слушателей) или сделать так, чтобы диспетчер был тем же потоком, что и слушатель. Есть некоторое преимущество в том, чтобы поместить их обоих в один и тот же поток, поскольку это упрощает обнаружение потерянного соединения сокета и использование одних и тех же fds для чтения и записи без синхронизации потоков. Однако может случиться так, что использование двух разных потоков даст лучшую производительность, это необходимо протестировать.
Примечание о балансировке нагрузки: это отдельная тема. Проще всего использовать 1 очередь для всех рабочих потоков, но проблема в том, что они должны блокироваться, чтобы извлекать элементы, а блокировка может снизить производительность. (Но вы получаете максимально сбалансированную нагрузку).
Другим довольно простым подходом было бы иметь частную очередь для каждого работника и выполнять циклический перебор при вставке. Через каждые X циклов проверяйте размер всех очередей. Если некоторые очереди намного больше других, оставьте их на следующие X циклов, а затем перепроверьте еще раз. Это не лучший подход, но он прост в реализации и обеспечивает некоторую балансировку нагрузки, при этом блокировка не требуется.
Кстати - есть способ реализовать очередь между 2 потоками без блокировки - но это тоже другая тема.
Я надеюсь, что это поможет, Гай
Отличным источником информации по этой теме является Проблема C10K. Хотя размеры там кажутся немного старыми, методы все еще применимы сегодня.
Если клиент и сервер находятся в защищенной сети, то аспект безопасности должен быть минимальным — до такой степени, что передача зашифрована. Если клиенты и сервер не находятся в защищенной сети, сначала нужно, чтобы сервер и клиент аутентифицировали друг друга, а затем инициировали зашифрованную передачу данных. Для передачи данных достаточно аутентификации на стороне сервера. В конце этой аутентификации используйте ключ сеанса для создания зашифрованного потока данных (симметричного). рассмотрите возможность использования TFTP, он прост в реализации и достаточно хорошо масштабируется.