Ошибки при подключении многих клиентов к серверу Go - PullRequest
2 голосов
/ 11 ноября 2011

полный код можно скачать на https://groups.google.com/forum/#!topic/golang-nuts/e1Ir__Dq_gE

Может ли кто-нибудь помочь мне улучшить этот пример кода до нуля? Я думаю, что это поможет нам разработать бесплатный клиент / серверный код без ошибок.

мои шаги разработки:

  1. Создайте сервер, который может обрабатывать несколько соединений с помощью goroutine.
  2. Создайте клиент, который отлично работает с простым протоколом.
  3. Развернуть клиент для имитации нескольких клиентов (с параметром -n = 1000 клиентов по умолчанию)
  4. TODO: попытаться уменьшить блокировку сервера
  5. TODO: попробуйте использовать bufio для повышения пропускной способности

Я нашел этот код очень нестабильным, содержит три проблемы:

  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]
    

Здесь я вставляю свой более упрощенный код.

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 Ответ

1 голос
/ 06 января 2013

Этот ответ на serverfault [1] предполагает, что для серверов, которые могут обрабатывать большое количество соединений, установка более высокого ulimit - это то, что нужно сделать.Также проверьте утечки памяти в приложении или дескриптор файла, используя lsof.

ulimit -n 99999

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

...