Эффективно и эффективно управлять многими TCP-соединениями - PullRequest
4 голосов
/ 23 декабря 2010

Мне любопытно, если кто-нибудь может дать мне какие-либо идеи или предложения о том, как эффективно управлять множеством TCP-соединений.Я говорю о 1000 соединений TCP (может быть, больше).Приложение, управляющее всеми этими соединениями, должно периодически извлекать информацию из клиента (другого конца соединения).Например, может быть, каждые 30 секунд.Я бы использовал .NET 4.0 для этого.Есть ли что-то встроенное, чтобы помочь с этим или специальным способом структурировать все, чтобы управлять всеми этими соединениями, не заставляя это приложение быть настолько увлеченным, что оно бесполезно?

Ответы [ 6 ]

7 голосов
/ 23 декабря 2010

Я могу дать вам одну небольшую подсказку:

Даже не думайте о порождении потока для каждого соединения. Вместо этого используйте встроенные в каркас асинхронные / задачи каркасы для управления соединениями. То есть; пусть пул потоков сделает это.

Кроме того, внимательно следите за тем, что делают ваши темы; Убедитесь, что вы никогда не сможете читать / записывать поток соединения из нескольких потоков одновременно. Но в то же время, будьте осторожны с тем, как вы используете механизмы блокировки для этого, чтобы у вас не было процесса с 1000 активных соединений и пула потоков, заполненного потоками, ожидающими получения блокировок, которые они никогда не получат.

3 голосов
/ 23 декабря 2010

Обрабатывать тысячи соединений не сложно, если вы используете только асинхронные API. Концепция «один поток на соединение» не только не масштабируется, но и (в общем случае протокола) неверна. Обратите внимание, что асинхронные API отличаются от использования ThreadPool.

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

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

Любые ошибки сокета должны привести к закрытию соединения и очистке состояния.

И лог. Все. TraceSource твой друг; узнайте, как использовать трассировку .NET, которую можно включить (даже в производственной среде), отредактировав app.config.

2 голосов
/ 23 декабря 2010

Я не помню какой-либо встроенной поддержки для этого конкретного сценария. Но в основном вот как я бы это сделал и в целом известен как хорошая практика:

1) Иметь пул потоков (небольшой по размеру - возможно, около 5), отвечающий за соединения. Это будет считывать из очереди заданий (открытых или закрытых) и управлять открытием и закрытием соединений.

2) Иметь пул потоков (среднего размера) для управления связью и операциями. Я думаю, что пул 50 должен быть в порядке.

3) У вас будет один поток, отвечающий за организацию всей операции, но это не должно быть связано с какой-либо операцией, а только операции с очередями для других потоков.

1 голос
/ 23 декабря 2010

Просто, чтобы добавить "незначительную" вещь к и без того великим ответам здесь.

Одной из часто забываемых областей являются возможности самих сетевых карт. Убедитесь, что сетевой адаптер на вашем сервере поддерживает TCP Offloading. В связи с этим, заплатите за хороший и убедитесь, что драйверы самые последние / лучшие.

Механизм TCP Offloading, встроенный в адаптер, работает на более низком уровне, чем ваш код, и будет обрабатывать всю работу по перетасовке данных с клиентов. Это может оказать огромное влияние на производительность и масштабируемость вашего программного обеспечения.

0 голосов
/ 23 декабря 2010

Во-первых, используйте асинхронные методы, как говорили другие.1000 соединений не должны быть проблемой с разумным оборудованием и разумным дизайном.

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

Я пишу о поддержке большого количества одновременных соединений здесь:http://www.serverframework.com/asynchronousevents/2010/10/how-to-support-10000-or-more-concurrent-tcp-connections---part-2---perf-tests-from-day-0.html важно, ИМХО, с самого начала убедиться, что вы тестируете этот тип нагрузки, чтобы вы могли быстро находить, когда добавляете некачественные решения, которые не масштабируются.

0 голосов
/ 23 декабря 2010
...