Golang中高并发执行时的http.Client出现恐慌

huangapple go评论91阅读模式
英文:

Panic in Golang http.Client with high concurrent excecutions

问题

我正在创建一个基于golang的http服务器系统,它将根据每个请求向另一个API发送多个请求。

例如:

curl localhost:8080/users?ids=1,2,3,4

将同时向以下地址发送多个GET请求:

api.com/user/1

api.com/user/2

api.com/user/3

api.com/user/4

我遇到了一个问题,当http.Client同时处理大量请求时(例如使用AB工具以4个并发连接访问localhost:8080/users?ids=1,2,3,4...40,或者在浏览器中频繁刷新),会导致panic错误。

问题似乎出现在以下代码行(第159行):

resp, _ := client.Do(req)

我的代码在这里(不是很长...180行):
http://play.golang.org/p/olibNz2n1Z

panic错误信息如下:

goroutine 5 [select]:
net/http.(*persistConn).roundTrip(0xc210058f80, 0xc21000a720, 0xc210058f80, 0x0, 0x0)
	/usr/local/go/src/pkg/net/http/transport.go:879 +0x6d6
net/http.(*Transport).RoundTrip(0xc210058280, 0xc21005b1a0, 0x1, 0x0, 0x0)
	/usr/local/go/src/pkg/net/http/transport.go:187 +0x391
net/http.send(0xc21005b1a0, 0x590290, 0xc210058280, 0x0, 0x0, ...)
	/usr/local/go/src/pkg/net/http/client.go:168 +0x37f
net/http.(*Client).send(0xc21001e960, 0xc21005b1a0, 0x28, 0xc21001ec30, 0xc21005f570)
	/usr/local/go/src/pkg/net/http/client.go:100 +0xd9
net/http.(*Client).doFollowingRedirects(0xc21001e960, 0xc21005b1a0, 0x2ab298, 0x0, 0x0, ...)
	/usr/local/go/src/pkg/net/http/client.go:294 +0x671
net/http.(*Client).Do(0xc21001e960, 0xc21005b1a0, 0xa, 0x0, 0x0)
	/usr/local/go/src/pkg/net/http/client.go:129 +0x8f
main.buscarRecurso(0xc21000a650, 0xb, 0xc2100526c0)
	/Users/fscasserra/Documents/workspace/Luna/multiget-api/multiget.go:159 +0x131
created by main.obtenerRecursos
	/Users/fscasserra/Documents/workspace/Luna/multiget-api/multiget.go:106 +0x197

有人可以帮助我吗?

最好的祝愿,
Fer

英文:

I am creating a system which is a http server in golang that will perform several request to another API based in every request that come to it.

e.g

curl localhost:8080/users?ids=1,2,3,4

will perform several concurrent gets to:

api.com/user/1

api.com/user/2

api.com/user/3

api.com/user/4

I am having a problem, the http.Client is getting my a panic, when it has a heavy concurrent requests (if I hit localhost:8080/users?ids=1,2,3,4.....40 with AB with 4 concurrent, or hitting refresh in my browser)

The proglem appears to be with the sentence (line 159)

resp, _ := client.Do(req)

My code is here (Not so large... 180 lines):
http://play.golang.org/p/olibNz2n1Z

The panic error is this one:

goroutine 5 [select]:
net/http.(*persistConn).roundTrip(0xc210058f80, 0xc21000a720, 0xc210058f80, 0x0, 0x0)
	/usr/local/go/src/pkg/net/http/transport.go:879 +0x6d6
net/http.(*Transport).RoundTrip(0xc210058280, 0xc21005b1a0, 0x1, 0x0, 0x0)
	/usr/local/go/src/pkg/net/http/transport.go:187 +0x391
net/http.send(0xc21005b1a0, 0x590290, 0xc210058280, 0x0, 0x0, ...)
	/usr/local/go/src/pkg/net/http/client.go:168 +0x37f
net/http.(*Client).send(0xc21001e960, 0xc21005b1a0, 0x28, 0xc21001ec30, 0xc21005f570)
	/usr/local/go/src/pkg/net/http/client.go:100 +0xd9
net/http.(*Client).doFollowingRedirects(0xc21001e960, 0xc21005b1a0, 0x2ab298, 0x0, 0x0, ...)
	/usr/local/go/src/pkg/net/http/client.go:294 +0x671
net/http.(*Client).Do(0xc21001e960, 0xc21005b1a0, 0xa, 0x0, 0x0)
	/usr/local/go/src/pkg/net/http/client.go:129 +0x8f
main.buscarRecurso(0xc21000a650, 0xb, 0xc2100526c0)
	/Users/fscasserra/Documents/workspace/Luna/multiget-api/multiget.go:159 +0x131
created by main.obtenerRecursos
	/Users/fscasserra/Documents/workspace/Luna/multiget-api/multiget.go:106 +0x197

Can anyone help me?

Best regards,
Fer

答案1

得分: 2

我会将钱押在对空的resp.Body调用Close()引发恐慌上。

始终检查错误!

一般来说,如果一个函数返回一个值和一个错误,那么在出现非空错误的情况下,响应值可能无法使用。任何对此的例外情况都应该有很好的文档说明。

英文:

I will put money on the panic coming from calling Close() on a nil resp.Body.

Always check your errors!

In general, if a function returns a value and an error, the response value may not be usable in the case of a non-nil error. Any exceptions to this should be well documented.

huangapple
  • 本文由 发表于 2014年8月6日 12:01:05
  • 转载请务必保留本文链接:https://go.coder-hub.com/25152030.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定