许多客户端连接到Go服务器时出错

时间:2011-11-11 02:04:16

标签: sockets go goroutine

完整代码可以在https://groups.google.com/forum/#!topic/golang-nuts/e1Ir__Dq_gE

下载

有没有人可以帮我改进这个示例代码来归零? 我认为它将帮助我们开发一个无错误的客户端/服务器代码。

我的发展步骤:

  1. 创建一个可以通过goroutine处理多个连接的服务器。
  2. 使用简单的协议构建一个工作正常的客户端。
  3. 展开客户端以模拟多个客户端(默认选项为-n = 1000个客户端)
  4. TODO:尝试减少服务器锁定
  5. TODO:尝试使用bufio来提高吞吐量
  6. 我发现这段代码非常不稳定包含三个问题:

    1. 启动1000个客户端,其中一个客户端在从服务器读取时出现EOF。
    2. 启动1050个客户端,很快就打开了太多文件(没有任何客户打开)。
    3. 启动1020个客户端,使用长跟踪堆栈获得运行时错误。

      Start pollServer: pipe: too many open files
      panic: runtime error: invalid memory address or nil pointer dereference
      
      [signal 0xb code=0x1 addr=0x28 pc=0x4650d0]
      
    4. 在这里,我粘贴了更简化的代码。

      const ClientCount = 1000
      func main() {
          srvAddr := "127.0.0.1:10000"
          var wg sync.WaitGroup
          wg.Add(ClientCount)
          for i := 0; i < ClientCount; i++ {
              go func(i int) {
                  client(i, srvAddr)
                  wg.Done()
              }(i)
          }
          wg.Wait()
      }
      func client(i int, srvAddr string) {
          conn, e := net.Dial("tcp", srvAddr)
          if e != nil {
              log.Fatalln("Err:Dial():", e)
          }
          defer conn.Close()
          conn.SetTimeout(proto.LINK_TIMEOUT_NS)
          defer func() {
              conn.Close()
          }()
      
          l1 := proto.L1{uint32(i), uint16(rand.Uint32() % 10000)}
          log.Println(conn.LocalAddr(), "WL1", l1)
          e = binary.Write(conn, binary.BigEndian, &l1)
          if e == os.EOF {
              return
          }
          if e != nil {
              return
          }
          // ...
      }
      

1 个答案:

答案 0 :(得分:1)

关于serverfault [1]的这个答案表明,对于可以处理大量连接的服务器,设置更高的ulimit是可以做的。还使用lsof检查应用程序内存泄漏或文件描述符泄漏。

ulimit -n 99999

[1] https://serverfault.com/a/48820/110909