Отправка 100 000+ запросов / с с помощью WebClient?

Я написал простой http-клиент в.Net, который должен выдавать 100 тыс. (Или около того) http-запросов в секунду для стресс-тестирования веб-службы. Веб-сервис работает на той же машине, что и клиент.

Кажется, я столкнулся со скоростью 20 тыс. Запросов / с на 4-х ядерном компьютере для разработки. Загрузка процессора составляет всего 50%.

Кроме того, кажется, что он плохо масштабируется - я получаю только 50 тыс. Запросов в секунду на 12-ядерном сервере с 25% -ной загрузкой процессора. Сервер примерно в 5 раз более производительный в GFlops, чем машина dev.

В обоих случаях служба сервера работает примерно на 1/3 от использования ЦП клиентом, отправляющим запросы, поэтому мне кажется, что я только стресс-тестирую клиента...

Я попытался запустить плотные циклы в нескольких потоках, используя асинхронные запросы (хотя я не уверен, что использовал их правильно). Если я увеличу количество потоков слишком высоко, производительность фактически упадет, предположительно из-за переключения контекста.

Есть ли образец для достижения цели? Или я просто не собираюсь достичь этого с помощью WebClient?

Примечание: приведенный ниже код не является полным и не будет компилироваться, для ясности я пропустил много

Class MainWindow

    Public Sub Init() Handles MyBase.Loaded

        ServicePointManager.DefaultConnectionLimit = 1000
        ServicePointManager.Expect100Continue = False
        ServicePointManager.MaxServicePoints = 1000
        ServicePointManager.UseNagleAlgorithm = False

        ApiInterface.HostDomain = Me.HostDomain
        ApiInterface.Authenticate("SomeUsername", "Password")

        For i As Integer = 1 To Environment.ProcessorCount * 4

            Dim Thread As New System.Threading.Thread(AddressOf ApiInterface.RandomApiCall)
            Thread.Start()

        Next

    End Sub

End Class




Public Class ApiCalls


    Public ApiCalls As New List(Of ApiCallDelegate)


    Public Sub New()

        ApiCalls.Add(AddressOf Me.ForumRequest)
        ApiCalls.Add(AddressOf Me.SessionListRequest)
        ApiCalls.Add(AddressOf Me.MemberSearchRequest)
        ApiCalls.Add(AddressOf Me.ChatRequest)

    End Sub


    Public Delegate Sub ApiCallDelegate()


    Public Sub MemberSearchRequest()

        Dim Request As New Api.Search.MemberSearchRequest
        Request.StartAt = ThreadSafeRandom.Next(0, 999)
        Request.Auth = Me.Auth
        Request.Count = ThreadSafeRandom.Next(0, 100)
        Request.Country = Countries.GetRandomCountryCode

        ApiCall(Me.HostDomain & "/api/search/members", Request)

    End Sub



    Private Sub ApiCall(Uri As String, Data As Object)

        Dim Client As New WebClient
        AddHandler Client.UploadStringCompleted, AddressOf OnRequestComplete
        Client.UploadStringAsync(New System.Uri(Uri), JsonConvert.SerializeObject(Data))

    End Sub



    Public Sub OnRequestComplete(Sender As Object, Args As UploadStringCompletedEventArgs)

        If Args.Error Is Nothing Then

            Interlocked.Increment(Status200Count)

        Else

            Select Case CType(CType(Args.Error, WebException).Response, HttpWebResponse).StatusCode

                Case HttpStatusCode.InternalServerError
                    Interlocked.Increment(Status500Count)

                Case HttpStatusCode.BadRequest
                    Interlocked.Increment(Status400Count)

                Case HttpStatusCode.Unauthorized
                    Interlocked.Increment(Status401Count)

                Case Else
                    Interlocked.Increment(StatusOtherCount)

            End Select

        End If

        If Not Me.Stopping Then RandomApiCall()

    End Sub


    Public Sub RandomApiCall()

        Me.ApiCalls(Rand.Next(0, Me.ApiCalls.Count)).Invoke()

    End Sub



End Class

0 ответов

Другие вопросы по тегам