Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум программистов > Python: Общие вопросы > Как лучше реализовать клиент-серверное приложение? |
Автор: Mihail2205 6.3.2012, 16:44 |
Здравствуйте, подскажите пожалуйста как лучше реализовать клиент-серверное приложение по удаленному мониторингу и контролю некоторых устройств: Есть сотни устройств, с которых нужно иметь возможность получать статусы и посылать им в ответ исполнительные команды - вопрос в том чтобы делать это с минимальным расходом трафика и небольшими задержками. Устройства подключаются через интернет к серверу, на котором запущен веб-интерфейс. Время от времени на сайт заходит оператор, смотрит состояние устройств и если нужно - отправляет команду. Нужно чтобы с момента отправки команды оператором она выполнялась на выбранном устройстве с минимальной задержкой (максимум пара секунд), но при этом чтобы целевое устройство не расходовало слишком много трафика, постоянно отправляя что-то на сервер. Оперативность нужна только в момент захода оператора на сайт, в остальное время достаточно просто отсылать свой статус раз в 10-15 минут. Как бы вы подошли к реализации такой задачи? Возможно ли использовать веб-сервер в качестве серверного приложения? Заранее спасибо за ваши ответы! |
Автор: Mihail2205 6.3.2012, 20:07 |
протокол уровня MAC это конечно круто, но не - давайте уточним: надо скоординировать сотни устройств через интернет, чтобы в любой момент можно было взять и начать управлять одним из них без лишних задержек, при этом нет возможности отправлять устройствам входящие соединения, они за NATом я пока вижу только 2 решения: 1. все устройства все время флудят на сервер что-то вроде "нет ли для меня новых команд?" (можно даже UDP пакетами) 2. все устройства постоянно держат открытую TCP-сессию до сервера и по ней получают команды и передают свое состояние Возможны ли еще варианты? - В случае с TCP соединением, можно ли использовать в качестве серверного приложения какой-нибудь apache+php\python, чтобы не писать свое приложение с сокетами блекджеком и шлюхами? Переварит ли апач одновременные несколько сотен подключений и какую технологию надо будет использовать (там же везде таймауты, не получится часами какой-нибудь http запрос держать)? Или все-таки придется что-то свое городить? |
Автор: rsm 7.3.2012, 16:08 | ||
Второй вариант будет потреблять больше трафика, т.к. всё равно нужно будет отправлять keep-alive пакеты чтобы соединение держалось стабильно. а) одноранговая сеть (p2p): тратится довольно много трафика, работает неторопливо, но зато высокая надёжность и отказоустойчивость; б) подобие ботнета, когда некоторые устройства (master) наделяются возможностью управления другими устройствами (slave): с центральным сервером общаются только master-устройства, транслируя данные в заданные slave-устройства. При такой схеме количество трафика снижается, нагрузка на центральный сервер снижается, но надёжность и отказоустойчивость так же снижаются - если master-устройство откажет, то исчезнет связь со всеми его slave-устройствами; в) комбинация а и б - распределённый ботнет, когда в случае выхода из строя одного master-устройства его подменяет другое master-устройство; Вообще, что ставится во главу угла - надежность и отказоустойчивость или время реакции и объем трафика? Это почти взаимоисключающие свойства.
Если использовать HTTP (много трафика!), то подойдет любой сервер, расчитанный на большие нагрузки - nginx, lighttpd и т.п. У этой задачи даже есть специальное название: http://www.kegel.com/c10k.html (проблема 10000 соединений). Готовые решения уже есть (например, тот же nginx), исходники открыты - можно достаточно легко (особенно если выпилить HTTP) адаптировать под собственные нужды. У HTTP нет понятия "держать состояние". Это протокол без состояния, работающий по принципу "запрос-ответ". В целом, если не требуется высокая надёжность, то вполне хватит центрального сервера, которому через некоторый интервал времени по протоколу UDP будут приходить сигнальные пакеты от устройств. А если ещё и разнести отправку этих пакетов по времени, то и устройства, и сервер получатся лёгкими и простыми. Во-первых, UDP значительно проще в реализации, хотя и имеет недостаток: не гарантирует доставку и целостность данных. Что, к слову, ничуть не мешает его использованию в http://en.wikipedia.org/wiki/Network_File_System_%28protocol%29, которая работает очень быстро и надёжно. Во-вторых, сервер не "утонет" в потоке данных от устройств, если их передача будет распределена по времени (а она будет распределена в любом случае, даже если не реализовывать это намерено). |
Автор: Mihail2205 7.3.2012, 19:03 |
Я не силен в TCP/IP стеке, все-таки считаете что протокол на основе UDP будет меньше нагружать сервер и потреблять меньше трафика, чем постоянно открытое TCP соединение от каждого клиента? Напомню что устройства UDP пакетами должны будут каждые несколько секунд передавать свое состояние и в случае необходимости получать от сервера команды. При этом клиентские устройства имеют серый ИП и находятся за NATом, следовательно входящие соединения принимать не имеют возможности - могут только сами что-то отправлять на сервер. |
Автор: rsm 8.3.2012, 08:44 | ||
В принципе для UDP через NAT можно сделать общий тоннель. Однако это уже нетривиально. Поэтому лучше делать проще - брать за основу TCP, поддерживать и тщательно контролировать соединение. И, разумеется, изначально предусмотреть возможность параллельной обработки данных в случае, если клиентов станет больше, чем в самых смелых предположениях. |