func handleConn(w http.ResponseWriter, r *http.Request) {
ws, err := upgrader.Upgrade(w, r, nil)
if err != nil {
if _, ok := err.(websocket.HandshakeError); !ok {
log.Println(err)
}
return
}
go writer(ws)
reader(r, ws)
}
func main() {
http.HandleFunc("/", handleConn)
}
我正在尝试使用golang构建一个高扩展的websocket服务器。由于本地go websocket包中缺少支持,我使用的是https://github.com/gorilla/websocket。
对于每个连接,都会产生一个goroutine来处理它的写入。用于扩展大量连接。让我们说如果我有1M并发连接,那么服务器上应该运行1M goroutines。
硬件规格:
16 GB Ram
4核心CPU
2.5 GHz Intel Core i5
它会在不影响性能的情况下适用于大量连接吗?
答案 0 :(得分:2)
让我们做一些数学:
理论上: 每个例程都会占用8KB的内存。 因此,对于一百万个插槽,需要8GB的内存。
现在,让我们将范式转换为实用性。 由于使用Web套接字,因此您正在寻找双向通道通信。因此,您将必须保留一个缓冲区以从每个套接字读取数据。 因此,又有8 GB的RAM仅用于侦听套接字中的数据。 这些数字仅表示旋转和产生一百万个连接所需的资源,并且不包括其他重要因素(为其他任务保留的资源,内核保留的空间,操作系统保留的空间等)
结论:这种方法很简单,但不能扩展到一定的限制。
您肯定需要更多的RAM,才能按建议的数字进行扩展。
您可以通过实现kQueue / ePoll之类的方法来最大程度地减少内存消耗。通过这种方法,您可以实现一个回调,该回调将通知您套接字是否准备好读取/写入数据,然后您可以创建一个缓冲区并进行读取,而不是一直等待数据被消耗和浪费缓冲区内存。对文件描述符的/ write操作。这将帮助您重用缓冲区,从而减少资源消耗。
希望有帮助!