Есть некий сервис, написанный на Go, запущенный на Ubuntu 16.04.
Суть работы в том, что он опрашивает порядка 30 серверов.
После получения данных от сервера - должен в ответ послать информацию, что данные получены, в ответ на это сервер кинет еще порцию данных и так далее. Бывает так, что данные на сервере кончились, и тогда просто засыпаю на 60 секунд, затем все по-новой.
Так же бывает, что сервера не отвечают (обрыв сети или еще какие то проблема на стороне сервера (не важно)), в таких случаях закрываю соединение и пытаюсь подключиться по-новой, через определенный интервал.
Дак вот после запуска сервиса - наблюдаю следующую картину:
Затем, через какое то время (видимо когда произошли дисконнекты):
Что в последствии (часов через 6) приводит к ошибке:
go dial error on addr dial tcp socket: to many open files
т.е. создается socket? B соединение как бы остается в подвисшем состоянии?
Хотя соединение явно закрывается: conn.Close()
примерный код, чтобы понимать, что к чему:
//Сбор данных - вызов в гоурутине
func stantionListener(server Servers, p DataProducer) {
//Основной цикл для сервера
for {
conn, err := net.Dial("tcp", "адрес сервера")
if err != nil {
log.Fatal("dial error on addr:", addr, err)
return
}
defer conn.Close()
//Цикл, в котором происходит обмен с сервером данными
for {
if wr, err := conn.Write([]byte("Запрос к серверу")); //Запрос #1
wr == 0 || err != nil {
log.Println(addr, err)
break
}
err = conn.SetReadDeadline(time.Now().Add(5 * time.Second))
if err != nil {
log.Println(addr, err)
break
}
//Пытаемся получить данные в ответ
buff := make([]byte, 1024)
rd, err := conn.Read(buff)
if err != nil{
log.Println(addr, err)
}
err = res.Parser(buff[:rd])
if err != nil {
log.Println(err, stDesc)
} else {
//Отправляем запрос о том, что все ок
if wr, err := conn.Write([]byte("ok, данные получил")); //Запрос #4
wr == 0 || err != nil {
log.Println(err, stDesc)
}
}
d := time.Duration(kpi.current * float32(time.Second))
time.Sleep(d)
}//end for
log.Println("error, when connect or receive data", stDesc, "wait 60seconds")
time.Sleep(time.Minute) //Ждем 1 минуту, прежде чем выполнить повторное подключение
}
}
Как я понял, при повторном подключении к тому же серверу создается вместо TYPE: IPv4 - sock, device: 0x7