Улучшение производительности многопоточных HttpWebRequests в .NET - PullRequest
29 голосов
/ 23 декабря 2008

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

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

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

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).

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

Ответы [ 6 ]

37 голосов
/ 12 января 2009

Вы должны установить параметр 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

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

Вы пытались увеличить максимальное количество подключений в настройках сети?

http://msdn.microsoft.com/en-us/library/fb6y0fyc.aspx

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

это может быть предел соединения, который был установлен недавно.

http://www.speedguide.net/read_articles.php?id=1497

и

http://www.mydigitallife.info/2007/04/09/windows-vista-tcpipsys-connection-limit-patch-for-event-id-4226/

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

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

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

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

0 голосов
/ 22 июня 2014

Есть два важных аспекта производительности:

  1. Один аспект, как предлагается всеми, количество TCP-соединений , использованных клиентом (как правило, лучше, если эти соединения сохраняются (keep alive = true)), подробности см. в: http://msdn.microsoft.com/en-us/library/system.net.servicepoint.connectionlimit(v=vs.110).aspx, Как и где было создано TCP-соединение в httpwebrequest и как оно связано с точкой обслуживания? , Почему System.Net.ServicePoint.ConnectionLimit использует «7FFFFFFF» (Int32.MaxValue / 2147483647), когда клиент подключается к службе на «localhost»? , System.Net.ServicePointManager. DefaultConnectionLimit и .MaxServicePointIdleTime )

  2. Второй аспект - это не использование нескольких новых потоков / или использование рабочих потоков для параллельной работы с использованием синхронных вызовов (например, httpwebrequest.getrequeststream) в фрагменте кода, полностью охватывающий асинхронную модель ( например, start / endrequeststream или новые варианты задач). Таким образом, процессор будет всегда занят, и пусть поток порта завершения ввода / вывода просто отправит ответ в рабочий поток (пул потоков), вызвав функцию обратного вызова. (Вы можете обратиться к: Как .NET использует потоки ввода-вывода или порты завершения ввода-вывода? , http://blog.marcgravell.com/2009/02/async-without-pain.html, HttpWebRequest и порты завершения ввода-вывода )

С уважением.

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...