我正试图在Go中强调测试一个http客户端。
首先,我只是尝试为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的这种组合。但是当goroutine和迭代的数量超过一定水平时,在我的情况下,对于单次迭代,当goroutines的数量超过634时,我收到此错误:
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个goroutines。在我的情况下,我做错了什么?如何在给定的迭代次数下测试客户端可以同时进行的最大GET或POST请求数量?
答案 0 :(得分:3)
您正在从http.Get和ioutil.ReadAll中丢弃错误,所以我并不感到惊讶,因为您获得了无指针取消引用;如果这不是一个有效的假设,那么你假设返回值是好的。服务器可能正在返回错误,因为您已超过服务器的最大吞吐量。
你还没有测试10次goroutines 10次迭代,你正在测试100个goroutines;并且在阅读完毕后,您并未关闭请求正文。最后,您可以获得多少吞吐量取决于服务器,服务器可用的资源量以及客户端可用的资源量;两者之间的竞争,因为您正在攻击localhost,客户端和服务器正在争夺相同的系统资源。
任何语言都没有静态性能特征;它取决于它运行的上下文。