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 服务器。由于 native go websocket 包缺乏支持,我正在使用 https://github.com/gorilla/websocket 。
对于每个连接,都会生成一个 goroutine 来处理对其的写入。用于扩展大量连接。假设我有 1M 个并发连接,那么服务器上应该运行 1M 个 goroutine。
硬件规范:
16 GB 内存
4核CPU
2.5 GHz 英特尔酷睿 i5
它可以在大量连接的情况下工作而不影响性能吗?
最佳答案
让我们做一些数学计算:
理论上: 每个 go-routine 消耗 8KB 内存。 因此,对于一百万个套接字,需要 8GB 的内存。
现在,让我们将范式转向实用性。 由于您正在使用网络套接字,因此您正在寻找双向 channel 通信。因此,您必须保留一个缓冲区来从每个套接字读取数据。 因此,另外 8 GB RAM 仅用于监听来自套接字的数据。 这些数字仅表示旋转和生成一百万个连接所需的资源,不包括其他重要因素(为其他任务保留的资源、内核保留空间、操作系统保留空间等)
结论:这种方法很简单,但超出一定限制后就无法扩展。
您肯定需要更多的 RAM,才能达到建议的数字。
您可以通过实现 kQueue/ePoll 之类的方法来最大限度地减少内存消耗。通过这种方法,您可以实现一个回调,而不是不断等待数据被消耗并浪费缓冲区内存,该回调会通知套接字是否准备好读/写数据,然后您可以创建一个缓冲区并执行读取操作对文件描述符的/write 操作。这将帮助您重用缓冲区,从而减少资源消耗。
希望有帮助!
关于go - 使用 golang 扩展 websocket 连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41258268/