【问题标题】:Scaling webscocket connections using golang使用 golang 扩展 webscocket 连接
【发布时间】:2018-10-01 03:05:36
【问题描述】:
   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 内存

4 核 CPU

2.5 GHz 英特尔酷睿 i5

它是否适用于大量连接而不影响性能?

【问题讨论】:

标签: go websocket gorilla


【解决方案1】:

让我们做一些数学运算:

理论上: 每个 go-routine 消耗 8KB 的内存。 因此,对于一百万个套接字,需要 8GB 的​​内存。

现在,让我们将范式转向实用性。 由于您使用的是 Web 套接字,因此您正在寻找两种方式的通道通信。因此,您必须保留一个缓冲区来从每个套接字读取数据。 因此,另外 8 GB 的 RAM 仅用于侦听来自套接字的数据。 这些数字仅表示旋转和生成一百万个连接所需的资源,不包括其他重要因素(为其他任务保留的资源、内核保留空间、操作系统保留空间等)

结论:这种方法很简单,但是超出一定限度就无法扩展。

您肯定需要更多的 RAM,才能按照建议的数字进行扩展。

您可以通过实现 kQueue/ePoll 之类的东西来最小化内存消耗。通过这种方法,你可以实现一个回调,而不是一直等待数据被消耗,浪费缓冲内存,它会在套接字准备好读/写数据时得到通知,然后你可以创建一个缓冲区并进行读取/write 对文件描述符的操作。这将帮助您重用缓冲区,从而减少资源消耗。

希望有帮助!

【讨论】:

  • 无论如何,没有一台服务器可以处理 1M 连接(至少在 2018 年不会)。您将有多个(很多!)实例来处理这种级别的流量。
  • github.com/eranyanay/1m-go-websockets,go能搞定,erlang能搞定..
猜你喜欢
  • 2016-09-24
  • 2023-03-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多