2017-09-24 1 views
-4

Go에서 HTTP 클라이언트를 테스트하려고합니다.Go - 특정 개수의 goroutine을 만들려고 할 때 세분화 위반이 발생했습니다.

처음에는 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()) 
} 

그것은 반복하고 goroutines의 조합을 위해 잘 작동 :

여기 내 클라이언트 코드입니다.

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에 따르면, 하나는 쉽게 만들 수 있습니다 goroutines와 반복 횟수가 일정 수준을 넘어 가면 goroutines의 수는 634 이상으로 갈 때, 내 경우에는, 단일 반복을 위해, 나는이 오류가 10000 개의 골 루틴. 내 경우에 내가 뭘 잘못하고 있니? 클라이언트가 지정된 반복 횟수 동안 동시에 만들 수있는 GET 또는 POST 요청의 최대 수를 테스트하려면 어떻게합니까?

+5

당신은'http.Get'와'ioutil.ReadAll'에서 오류를 버리고 있습니다. 그래서 당신은 nil 포인터 역 참조를 얻고있는 것이 놀랍지는 않습니다; 유효한 가정이 아닌 경우 반환 값이 좋다고 가정합니다. – Adrian

답변

3

당신은 http.Get과 ioutil.ReadAll에서 오류를 버리므로, 당신이 nil 포인터 역 참조를 얻고있는 것은 놀랍지는 않습니다. 유효한 가정이 아닌 경우 반환 값이 좋다고 가정합니다. 서버의 최대 처리량을 초과 했으므로 서버에서 오류를 반환 할 수 있습니다.

또한 10 개의 goroutines를 10 회 반복 테스트하지 않고 100 개의 goroutines를 테스트하고 있습니다. 요청 본문을 읽은 후에 요청 본문을 닫지 않을 것입니다. 마지막으로 얻을 수있는 처리량은 서버, 서버에서 사용할 수있는 리소스의 양 및 클라이언트가 사용할 수있는 리소스의 양에 따라 다릅니다. 그리고 둘 사이의 경쟁은 클라이언트와 서버가 같은 시스템 자원을 위해 경쟁하고있는 localhost를 치고 있기 때문에 가능합니다.

모든 언어에 대한 정적 성능 특성은 없습니다. 실행중인 컨텍스트에 따라 다릅니다.

+0

답장을 보내 주셔서 감사합니다! http.Get 및 ioutil.ReadAll에서 오류를 기록한 후에 "http : // localhost : 8000 : dial tcp : lookup localhost : no such host"오류가 표시됩니다. 또한이 방법이 아니면 10 회 반복 10 루틴을 테스트 할 수 있습니까? – heranglo

+0

"10 개의 goroutines for 10 iterations"의 의미에 따라 달라집니다. - 동시에 10을 실행하고 모두 끝내기를 기다린 다음 10 번 더 진행하면 Go Tour에 나와있는 것처럼 sync.WaitGroup을 봅니다. – Adrian

+0

다시 한번 감사드립니다! 도노반 (Donovan)과 커니건 (Kernighan)의 "Go Programming Language"의 goroutines 장을 살펴 보겠습니다. – heranglo

관련 문제