Подтвердить что ты не робот

Повышение производительности многопоточных HttpWebRequests в .NET.

Я пытаюсь измерить пропускную способность веб-службы.

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

Содержимое внутреннего цикла каждого потока выглядит следующим образом:

public void PerformRequest()
{
  WebRequest webRequest = WebRequest.Create(_uri);

  webRequest.ContentType = "application/ocsp-request";
  webRequest.Method = "POST";
  webRequest.Credentials = _credentials;
  webRequest.ContentLength = _request.Length;
  ((HttpWebRequest)webRequest).KeepAlive = false;

  using (Stream st = webRequest.GetRequestStream())
    st.Write(_request, 0, _request.Length);

  using (HttpWebResponse httpWebResponse = (HttpWebResponse)webRequest.GetResponse())
  using (Stream responseStream = httpWebResponse.GetResponseStream())
  using (BufferedStream bufferedStream = new BufferedStream(responseStream))
  using (BinaryReader reader = new BinaryReader(bufferedStream))
  {
    if (httpWebResponse.StatusCode != HttpStatusCode.OK)
      throw new WebException("Got response status code: " + httpWebResponse.StatusCode);

    byte[] response = reader.ReadBytes((int)httpWebResponse.ContentLength);
    httpWebResponse.Close();
  }      
}

Кажется, что все в порядке, за исключением того, что что-то, кажется, ограничивает инструмент. Если я запускаю два экземпляра инструмента с каждым 40 потоками, я получаю значительно большую пропускную способность, чем один экземпляр с 80 потоками.

Я нашел свойство ServicePointManager.DefaultConnectionLimit, которое я установил для 10000 (и это не имеет значения, если я установил его через app.config как было предложено Jader Dias).

Есть ли другие настройки в .NET или на моей машине, которые могут влиять на производительность? (Я запускаю Vista, но я вижу ту же проблему в Windows Server 2003).

Возможно, некоторые ограничения на количество соединений, которые может сделать один процесс?

4b9b3361

Ответ 1

Вы должны установить параметр maxconnection в файле app.config или web.config:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <system.net>
    <connectionManagement>
      <add address="*" maxconnection="80"/>
    </connectionManagement>
  </system.net>
</configuration>

Значения до 100 отлично работают с Windows XP.

Обновление: Я только узнал, что приведенный выше метод является альтернативным способом установки System.Net.ServicePointManager.DefaultConnectionLimit

Ответ 4

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

Если вы действительно получаете лучшую производительность с помощью 2 40 потоков exes, чем 1 80 thread exe, вам нужно начать расследование с помощью общих ресурсов. И если это так, код, который вы указали, гораздо менее интересен, чем код, который создает и управляет потоками.

Другая вещь, которую я бы выбрал, есть несколько инструментов, которые вы можете получить, которые будут делать это для вас в целом. См. http://support.microsoft.com/kb/231282. Также включен в Visual Studio (я не уверен, что skus) - это новое поколение инструментов тестирования производительности веб-приложений. И я уверен, что если бы вы посмотрели, вы могли бы найти не-MS-материал тоже.

Ответ 5

Существует два важных аспекта производительности w.r.t:

С уважением.

Ответ 6

Как вы создаете свои темы? Я предполагаю, что, поскольку вы знаете, что у вас есть 80 потоков, вы не используете диспетчер threadpool, потому что с помощью диспетчера threadpool вы можете запрашивать столько потоков, сколько хотите, и вы получите только 25 активных потоков за раз. Если вы создаете потоки вручную с помощью массива, то вы фактически получите столько, сколько вам нужно, однако они все еще находятся в одном и том же пространстве процессов, что может ограничить их потоками, запущенными в отдельных процессах.

Вы также можете посмотреть, в каком стиле квартиры создаются потоки, я считаю, что класс Thread ctor использует STA по умолчанию. Попробуйте MTA и посмотрите, влияют ли они на производительность.