我想开发一个软件来使用 GoLang 处理来自多个 tcp 连接的请求,并在具有 10Gb-nic 的服务器上运行。


看来性能不够单核recv/send数据。所以我想实现该软件以在多个 cpu 内核上接收/发送数据。


然后我做了一个简单的测试服务器来检查 GoLang 是否可以在多个 cpu 内核上接收/发送数据。它启动多个 (16) goroutines 在同一个监听器上启动 http 服务器,并使用 ab(Apache Benchmark) 作为客户端。


服务器启动后,我看到只有一个线程调用了EpollWait,但是服务器启动了18个线程,而当我启动ab测试时使用了16个并发,但服务器只占用一个核心。


所以问题是:有没有办法启动多个线程来处理来自 GoLang 中多个 tcp 连接的数据接收/发送。或者我应该调用 syscall.EpollWait 来制作一个网络框架,自己做吗?


服务器的测试代码:


package main


import (

  "io"

  "log"

  "net"

  "net/http"

  "runtime"

)


type HandlerFunction struct{}


func (self HandlerFunction) ServeHTTP(w http.ResponseWriter, req *http.Request) {

  data := "Hello"

  //fmt.Printf("data_len=%d\n", len(data))

  io.WriteString(w, string(data))

}


func RoutineFunction(hs *http.Server, l net.Listener) {

  runtime.LockOSThread()

  err := hs.Serve(l)

  if err != nil {

    log.Fatalf("serve fail, err=[%s]", err)

  }

}


func main() {

  runtime.GOMAXPROCS(16)


  l, err := net.Listen("tcp", "0.0.0.0:12345")

  if err != nil {

    log.Fatalf("listen fail, err=[%s]", err)

  }


  for i := 0; i < 15; i++ {

    hs := http.Server{}

    hs.Handler = HandlerFunction{}

    go RoutineFunction(&hs, l)

  }


  hs := http.Server{}

  hs.Handler = HandlerFunction{}

  RoutineFunction(&hs, l)

}