我正在创建一个系统,它是golang中的http服务器,它将根据收到的每个请求向另一个API执行多个请求。

例如

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

将执行多个并发操作以:

1
2
3
4
5
6
7
api.com/user/1

api.com/user/2

api.com/user/3

api.com/user/4

我有一个问题,当HTTP.Client有大量并发请求时(如果我用AB命中localhost:8080 / users?ids = 1,2,3,4 ..... 40,我就会感到恐慌) 并发4次,或在浏览器中刷新)

这个问题似乎与句子一起出现(第159行)

1
resp, _ := client.Do(req)

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

紧急错误是这样的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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

谁能帮我?

最好的祝福,
费尔

  • 恐慌在状态为running的goroutine中发生。 状态为select的人只是睡觉。
  • ...不是惊慌失措吗? ...
  • 您已经展示了goroutine 5s堆栈的外观。 那其他所有的goroutines呢? 您确定goroutine 5感到惊慌吗?
  • 紧急消息是什么?
  • 对于初学者:检查http.NewRequest和client.Do返回的错误。 您的应用程序将忽略它们并继续。
  • 检查所有其他错误。 您还忽略了ioutil.ReadAll。 (并且编写"普通" godoc注释将使阅读代码更愉快:-)
  • 谢谢,问题出在defer函数中,在关闭它之前我没有检查响应是否为nil。

我将把钱花在因在nil resp.Body上调用Close()而引起的恐慌。

始终检查您的错误!

通常,如果函数返回一个值和一个错误,则在非null错误的情况下,响应值可能不可用。 对此的任何例外都应有据可查。

  • 是的,我发现错误是由defer函数中的resp.Body在Close()上产生的。:panic:运行时错误:无效的内存地址或nil指针取消引用[信号0xb代码= 0x1 addr = 0x40 pc = 0x3295]
  • 我把if resp!= nil {resp.Body.Close()}放到了完美的位置
  • @Fersca:不要那样做。 如果存在错误,则响应无效,因此即使resp != nilBody(或其他属性)可能仍包含nil指针。