go - 使用 golang 扩展 websocket 连接

标签 go websocket gorilla

   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/

相关文章:

go sql driver + context canceled 似乎是 "leak"goroutines?

for-loop - 如果我将 golang 中的增量相乘,for 循环不会递增

javascript - 在 javascript 中测量 websockets 数据输入/输出的大小

javascript - WebSocket,即使在触发 onopen 事件后,仍处于 CONNECTING 状态

go - 是否可以从 websocket 连接访问 HTTP 请求?

go - 无法导入 gorilla/mux(github.com/gorilla/mux@v1.7.4 : is explicitly required in go. mod,但在 vendor/modules.txt 中未标记为显式)

file - 无法解析HCL文件中的变量

unix - 将 Unix 纪元作为字符串转换为 time.Time on Go

javascript - 具有动态服务器 IP 的 TLS

go - 在 go 中,如何使用带有 gorilla/mux 子路由器的闭包?