我只是跟golang有点关系,我构建了一个小负载测试程序来玩看起来很酷的并发内容。
我的测试者应用程序启动了一堆线程,每个线程尽可能快地向一些端点执行一堆http请求。几秒钟后,我收到以下错误:
connectex:通常只允许使用每个套接字地址(协议/网络地址/端口)。
我之前在dotnet中遇到过这个问题,它与Windows(https://aspnetmonsters.com/2016/08/2016-08-27-httpclientwrong/)分配的端口耗尽有关。 HttpClient(dotnet)通过在请求之间重用端口来解决这个问题。
是否有类似的方法在http请求之间重用操作系统分配的端口?
要重现的代码:
package main
import (
"fmt"
"io/ioutil"
"net/http"
"time"
)
const numberOfCallsPerThread = 100
const numberOfThreads = 128
func main() {
var chans [numberOfThreads]chan time.Duration
for i := range chans {
chans[i] = make(chan time.Duration, 5) //only let one thread get 5 calls ahead
go callGet(numberOfCallsPerThread, chans[i])
}
var durations [numberOfCallsPerThread * numberOfThreads]time.Duration
for i := 0; i < numberOfCallsPerThread; i++ {
for j := range chans {
durations[(i*numberOfThreads)+j] = <-chans[j]
}
}
}
func callGet(numberOfTimes int, responseTime chan time.Duration) {
for i := 0; i < numberOfTimes; i++ {
start := time.Now()
response, httpError := http.Get("http://google.com")
if httpError != nil {
close(responseTime)
panic(httpError)
}
responseBody, _ := ioutil.ReadAll(response.Body)
response.Body.Close()
elapsed := time.Since(start)
fmt.Println(len(responseBody), " in ", elapsed)
responseTime <- elapsed
}
}
(抱歉没有游乐场链接,因为它不支持http内容)
注意:此问题仅发生在Windows上(osx不可重现)