2017-09-24 10 views
-4

Goでhttpクライアントをテストしようとしています。Go - 一定数以上のゴルーチンを作成しようとするとセグメンテーション違反が発生する

まず、10回の反復で10個の同時リクエストを実行しようとしました。

// stress.go 
package main 

import (
    "fmt" 
    "io/ioutil" 
    "net/http" 
    "time" 
) 

func MakeRequest(url string, ch chan<- string) { 
    start := time.Now() 
    resp, _ := http.Get(url) 

    secs := time.Since(start).Seconds() 
    body, _ := ioutil.ReadAll(resp.Body) 
    ch <- fmt.Sprintf("%.2f elapsed with response length: %d %s", secs, len(body), url) 
} 

func main() { 
    start := time.Now() 
    goroutines := 10 
    iterations := 10 
    ch := make(chan string) 
    url := "http://localhost:8000" 
    for i := 0; i < iterations; i++ { 
     for j := 0; j < goroutines; j++ { 
      go MakeRequest(url, ch) 
     } 
    } 
    for i := 0; i < goroutines*iterations; i++ { 
     fmt.Println(<-ch) 
    } 

    fmt.Printf("%.2fs elapsed\n", time.Since(start).Seconds()) 
} 

それは、反復とゴルーチンの組み合わせのために正常に動作します:

は、ここに私のクライアントコードです。しかし、ゴルーチンと反復回数が一定のレベルを超えたときにゴルーチンの数が634を超える行くとき、私の場合には、1回の反復のために、私はこのエラーが表示されます。

panic: runtime error: invalid memory address or nil pointer dereference 
[signal SIGSEGV: segmentation violation code=0x1 addr=0x48 pc=0x11eb9f0] 

goroutine 7099 [running]: 
main.MakeRequest(0x1271897, 0x15, 0xc420074120) 
     stress.go:16 +0xa0 
       created by main.main 
         stress.go:28 +0xb2 

thisによると、人は簡単に作成することができます10000のゴルーチン。私の場合、私は間違って何をしていますか?指定した回数の繰り返しでクライアントが同時に実行できるGETリクエストまたはPOSTリクエストの最大数をテストするにはどうすればよいですか?

+5

あなたは 'http.Get'と' ioutil.ReadAll'からエラーを破棄していますので、あなたはnilポインタ参照を得ていないことに驚くことはありません。あなたはそれが有効な前提でないときに戻り値が良いと仮定しています。 – Adrian

答えて

3

あなたはhttp.Getとioutil.ReadAllからエラーを破棄しているので、あなたはnilポインタを参照していないことに驚くことはありません。あなたはそれが有効な前提でないときに戻り値が良いと仮定しています。サーバの最大スループットを超えたため、サーバがエラーを返す可能性があります。

また、10回の繰り返しに対して10個のゴルーチンをテストしていないので、100個のゴルーチンをテストしています。あなたがそれらを読んだ後にあなたが要求団体を閉じているわけではありません。最後に、どの程度のスループットが得られるかは、サーバー、サーバーが使用できるリソースの量、およびクライアントが使用できるリソースの量によって異なります。クライアントとサーバーが同じシステムリソースに対して競合しているため、2つの間の競争が発生します。

どの言語でも静的なパフォーマンス特性はありません。実行されているコンテキストによって異なります。

+0

あなたの返信ありがとう! http.Getとioutil.ReadAllからのエラーを記録した後、「http:// localhost:8000:dial tcp:lookup localhost:そのようなホストはありません」というエラーが表示されます。 また、そうでない場合、10回の繰り返しに対して10回のルーチンをテストするにはどうすればよいですか? – heranglo

+0

これは、10回の10回のgoroutinesで10回の繰り返しを意味するかどうかによって異なります。10回同時に実行したい場合は、すべて終了するのを待ってから10回以上実行して、Go Tourで示されているように 'sync.WaitGroup'を確認します。 – Adrian

+0

もう一度おねがいします!私はDonovanとKernighanのThe Go Programming Languageのgoroutinesの章で説明します。 – heranglo

関連する問題