去http.Request.Context.ActiveConn是一个映射,会不会有并发映射问题?
如果有许多连接,我将打印包含request.Context
的{{1}},它会不会同时出现读写地图问题?
ActiveConn(map)
我使用Webench进行压力测试,由于并发地图问题,它将失败。那么,有没有人遇到同样的问题呢?因此,我搞砸了核心服务... ...
答案 0 :(得分:1)
Go的http服务器实现的全部目的是处理并发连接,因此我怀疑您会在实现本身中看到并发问题。
这里发生的事情是,在那里打印整个r.Context()
时,您最终访问了Go的Server
对象的内部字段,而没有同步对其的访问。
这会导致您最终看到的concurrent map read and map write
错误。
最简单的解决方案是替换为:
fmt.Fprintf(w, "r.ctx: %#v, %+v", r.Context(), r.Context())
使用一些自定义函数,您可以编写一个Context
对象,并提取与您相关的值(例如,将自己添加到上下文中的任何自定义键/值)。
有关该activeConn字段的详细说明
在打印整个activeConn
时看到的r.Context()
来自Go的Server
类型。
在准备监听连接时,Server
创建一个基础上下文,在其中添加对Server
本身的引用:
https://github.com/golang/go/blob/master/src/net/http/server.go#L2894
func (srv *Server) Serve(l net.Listener) error {
....
ctx := context.WithValue(baseCtx, ServerContextKey, srv)
....
}
因此,在打印整个上下文时,您最终要打印activeConn
字段:
https://github.com/golang/go/blob/master/src/net/http/server.go#L2582
activeConn map[*conn]struct{}
Server
实现在需要使用该地图时将其同步访问,例如:
https://github.com/golang/go/blob/master/src/net/http/server.go#L2997
...
s.mu.Lock()
defer s.mu.Unlock()
if s.activeConn == nil {
s.activeConn = make(map[*conn]struct{})
}
if add {
s.activeConn[c] = struct{}{}
} else {
delete(s.activeConn, c)
}
....