.NET Core 2.2 HttpClient / WebClient против Curl - .NET библиотеки очень медленно работают на некоторых серверах - PullRequest
5 голосов
/ 09 мая 2019

РЕДАКТИРОВАТЬ: добавлены образцы воспроизведения + Я запускаю это (на всех серверах) на Ubuntu 18.04 с .Net Core 2.2.203.

РЕДАКТИРОВАТЬ: протестировано из дома с моего ноутбука с Windows 10; те же результаты

У меня есть кусок очень простого кода для HttpClient (статический, как рекомендовано, но я также тестировал с использованием ()):

sw.Start(); // stopwatch
client.GetAsync(url).Result();
sw.Stop();

и затем для скручивания:

time curl -L "url" > /dev/null

и для рыси:

time lynx "url" > /dev/null

Разница ошеломляет; это действительно зависит от запрошенного сервера / URL, но я получаю различия в 2-50 раз медленнее от HttpClient, чем curl / lynx для запросов от того же сервера .

Я перепробовал все найденные исправления;

HttpHandler без прокси (UseProxy = false, Proxy = null)

Использование await вместо .Result (не то, что должно иметь значение, и это действительно не так)

WebClient

ModernHttpClient

и упаковщик Curl CurlThin

Последний вариант (очевидно) дал правильные результаты, остальные (параметры .NET) просто невероятно медленные.

Сейчас я использую обертки Curl, потому что результаты .NET просто неверны и замедляют работу нашего стека.

Кто-нибудь имел это раньше? Я попробовал (как вы можете видеть выше) все «исправления», предоставленные Googling, но ни одна из них не предоставила никакой помощи.

РЕДАКТИРОВАТЬ: от Мэтти в комментариях, если вы используете Windows с Powershell, это тоже воспроизводит;

(Measure-Command -Expression { $site = Invoke-WebRequest -Uri "reddit.com" }).Milliseconds

РЕДАКТИРОВАТЬ: Код для воспроизведения:

использовать с:

dotnet run -- https://reddit.com
using System;
using System.Diagnostics;
using System.Net.Http;

namespace Download.Playground
{
    class Program
    {
        static HttpClient client;


        static void Main(string[] args)
        {

            HttpClientHandler hch = new HttpClientHandler();
            hch.Proxy = null;
            hch.UseProxy = false;
            client = new HttpClient(hch);

            Stopwatch sw = new Stopwatch();

            sw.Start();
            var result = client.GetAsync(args[0]).Result; 
            sw.Stop();

            Console.WriteLine($"Spent {sw.ElapsedMilliseconds}ms"); 

        }

    }
}

Маленький скрипт для проверки 20 раз, запустите с:

./runbench https://reddit.com
#!/bin/bash

for i in {1..20}
do
    dotnet run -- $1
    time curl -L $1 > /dev/null
done

1 Ответ

0 голосов
/ 09 мая 2019

Проблемы были решены, просто сочетание факторов, которые привели к тому, что большая часть сайтов целевой аудитории не кэшировала свой контент.Ничего общего с HttpClient (кроме того, что он не отправляет агента пользователя).

Прочитайте комментарии для получения дополнительной информации.

...