У меня есть серверный компонент, который работает через Zeroc-ICE. Когда я захотел загрузить его, я подумал, что с помощью параллельной библиотеки для создания нескольких запросов это можно сделать. Но это не в конечном итоге так. Использовать библиотеку Parallel (Parallel.For) из C #, по-видимому, было проще, но, похоже, она не генерирует все параллельно в одно и то же мгновение. Так что это не может быть определение для создания N запросов в секунду. Как я должен это делать ? Я предполагаю, что любой, кто хочет сделать нагрузочное тестирование первым, действительно подумает об этом.
Какой эффективный способ на самом деле создавать N запросов в секунду?
Другой миф о параллельном программировании. Пожалуйста, сообщите нам, если вы использовали шаблоны параллельного программирования в C # или .Net в целом. Представь, у меня 5 процессов. Как запустят все пять процессов одновременно. Что это значит для моего потребления ресурсов? Я попытался прочитать многие материалы, доступные через Интернет, но я получаю все больше и больше вопросов, чем они, являясь ответом на мои вопросы.
Я использовал Parallel.For и создал N потоков и измерил время. Затем я попробовал то же самое, используя Task.Factory.start для перечисления задач. Измеренное время было другим. Так в чем же разница между их использованием? Когда мне следует использовать соответствующие классы и для каких целей именно? У нас часто бывает много богатств, но мы просто не знаем, как отличить одно от другого. Это один из таких случаев для меня, я не могу понять, почему я не должен использовать одно из другого.
Я использовал класс секундомера, чтобы измерить это время, которое считается лучшим. В моем сценарии нагрузочного тестирования компонента, какой будет способ измерения времени отклика. Секундомер, кажется, лучшее решение для меня. Любые мнения приветствуются.
PS: Есть много инструментов нагрузочного тестирования для веб-приложений. Мой - индивидуальный случай серверных компонентов. И мой вопрос больше касается создания N потоков в секунду.
Все мнения приветствуются. Только не думайте, что это не вопрос программирования. Это конечно. Любому программисту, который хочет самому поучаствовать в QE, должно быть приятно слышать о производительности своего продукта, из первых рук. Я перепробовал много вариантов, а затем должен был остановиться на том, как я должен это делать?
источник
Ответы:
У меня нет всех ответов. Надеюсь , я могу пролить некоторый свет на это.
Чтобы упростить мои предыдущие утверждения о моделях потоков .NET, просто знайте, что Parallel Library использует Tasks, а TaskScheduler по умолчанию для Tasks использует ThreadPool. Чем выше вы идете в иерархии (ThreadPool находится внизу), тем больше накладных расходов при создании элементов. Эти дополнительные накладные расходы, конечно, не означают, что они медленнее, но приятно знать, что они есть. В конечном итоге производительность вашего алгоритма в многопоточной среде сводится к его дизайну. То, что работает хорошо последовательно, может не так хорошо работать параллельно. Здесь слишком много факторов, чтобы дать вам жесткие и быстрые правила, они меняются в зависимости от того, что вы пытаетесь сделать. Поскольку вы имеете дело с сетевыми запросами, я постараюсь привести небольшой пример.
Позвольте мне заявить, что я не специалист по розеткам, и я почти ничего не знаю о Zeroc-Ice. Я немного знаю об асинхронных операциях, и это то, где это действительно поможет вам. Если вы отправите синхронный запрос через сокет, то при вызове
Socket.Receive()
ваш поток будет блокироваться до получения запроса. Это не хорошо Ваш поток не может делать больше запросов, так как он заблокирован. Используя Socket.Beginxxxxxx (), запрос ввода-вывода будет сделан и помещен в очередь IRP для сокета, и ваш поток продолжит работу. Это означает, что ваш поток может фактически сделать тысячи запросов в цикле без какой-либо блокировки!Если я вас правильно понимаю, вы используете вызовы через Zeroc-Ice в своем тестовом коде, а не пытаетесь достичь конечной точки http. Если это так, я могу признать, что я не знаю, как работает Zeroc-Ice. Я бы, однако, предложить после консультаций , перечисленных здесь , в частности , часть:
Consider Asynchronous Method Invocation (AMI)
. Страница показывает это:Что похоже на то, что я описал выше с использованием сокетов .NET. Могут быть и другие способы улучшить производительность при попытке сделать много посылок, но я бы начал здесь или с любого другого предложения, перечисленного на этой странице. Вы были очень расплывчаты в отношении дизайна вашего приложения, поэтому я могу быть более конкретным, чем я был выше. Только помните, не используйте больше потоков, чем это абсолютно необходимо, чтобы получить то, что вам нужно, иначе вы, скорее всего, обнаружите, что ваше приложение работает намного медленнее, чем вы хотите.
Несколько примеров в псевдокоде (попытался сделать его максимально приближенным к ледяному, без необходимости его изучения):
Лучший способ:
Имейте в виду, что больше потоков! = Лучшая производительность при попытке отправить сокеты (или действительно что-то делать). Потоки не волшебны в том, что они автоматически решат любую проблему, над которой вы работаете. В идеале вам нужно 1 поток на ядро, если поток не тратит много времени на ожидание, тогда вы можете оправдать наличие большего. Выполнение каждого запроса в своем собственном потоке - плохая идея, поскольку произойдет переключение контекста и потеря ресурсов. (Если вы хотите увидеть все, что я написал об этом, нажмите «Изменить» и посмотрите последние редакции этого поста. Я удалил его, поскольку казалось, что он лишь затуманивает основную проблему.)
Вы можете определенно сделать эти запросы в потоках, если вы хотите делать большое количество запросов в секунду. Однако, не переусердствуйте с созданием потока. Найдите баланс и придерживайтесь его. Вы получите лучшую производительность, если будете использовать асинхронную модель по сравнению с синхронной.
Надеюсь, это поможет.
источник
Я собираюсь пропустить вопрос 1) и перейти сразу к # 2, поскольку это, как правило, приемлемый способ выполнить то, что вы ищете. В прошлом для достижения n сообщений в секунду вы могли создать отдельный процесс, который затем будет запускать p доменов приложений. Каждый домен приложений в основном просто запускает цикл запроса, как только достигнут определенный момент времени (с использованием таймера). Это время должно быть одинаковым для каждого домена приложений, чтобы гарантировать, что они начинают попадать на ваш сервер в один и тот же момент времени.
Примерно так должно работать для отправки ваших запросов:
Это, вероятно, снизит производительность на любой машине, на которой вы его используете, поэтому вы всегда можете реализовать цикл с одинаковым типом на нескольких разных машинах, если у вас есть ресурсы (использующие процессы вместо доменов приложений).
Для вашего третьего вопроса, дайте эту ссылку читать http://www.albahari.com/threading/
Наконец, секундомер должен быть в паре со счетчиком посещений, чтобы отслеживать как длительность, так и уникальные попадания на ваш сервер. Это должно позволить вам выполнить некоторый анализ после факта.
источник
Не беспокойтесь о нитях, если N достаточно мало. Чтобы сгенерировать N запросов в секунду, используйте время настенных часов (
DateTime.Now
). Потратьте время как до, так и после запроса, затем добавьте a,Sleep
чтобы отложить следующий запрос.Например, с N = 5 (200 мс):
Это не идеально; Вы можете обнаружить, что
Sleep
это не точно. Вы можете вести текущий подсчет отклонений (до X-го запроса время должно быть X-1 / N позже) и соответствующим образом корректировать период ожидания.Как только N становится слишком большим, вы просто создаете M потоков и позволяете каждому потоку генерировать N / M запросов одинаково.
источник
Самый простой способ выполнить нагрузочное тестирование для любого проекта .NET - это приобрести версию Visual Studio Ultimate. Это идет с интегрированными инструментами тестирования, чтобы помочь преформовать все виды тестов, включая нагрузочные тесты. Нагрузочные тесты могут быть предварительно сформированы путем создания виртуальных пользователей либо на одном ПК, либо распределенных по нескольким для большего числа пользователей, также есть небольшая программа, которая может быть установлена на целевых серверах, чтобы возвращать дополнительные данные в течение теста.
Это дорого, хотя, но окончательная версия поставляется с большим количеством функций, поэтому, если бы все было использовано, это было бы более разумной ценой.
источник
Если вы просто хотите, чтобы все потоки X обращались к вашему ресурсу в одно и то же время, вы можете поместить каждый поток за защелку обратного отсчета и указать короткий период ожидания между проверками семафоров.
C # имеет реализацию (http://msdn.microsoft.com/en-us/library/system.threading.countdownevent(VS.100).aspx).
В то же время, если вы проводите стресс-тестирование своей системы, вы, возможно, захотите проверить также и условия гонки, и в этом случае вы захотите установить периоды ожидания потока в каждом потоке, которые со временем изнашиваются со случайной частотой и пиками / потерями.
Точно так же вы, возможно, на самом деле не хотите просто быстро отправлять несколько запросов, у вас может быть больший успех при переводе вашего сервера в плохое состояние / тестировании его реальной производительности путем настройки меньшего числа потоков, которые тратят больше времени на потребление и отправку сообщений обратно. и далее по сокету, поскольку вашему серверу, скорее всего, потребуется ускорить собственные потоки для обработки медленных текущих сообщений.
источник