2015-01-20 4 views
1

Я запускаю небольшой клиент в Go. На данный момент мы получаем несколько ложных тревог, которые, похоже, доходят до client.Do(), возвращая ошибку EOF, когда num>=1000.Голанг HTTP Параллельные запросы POST EOF

Это суть моего кода:

func DoCreate(js string, cli *http.Client) { 

    url2 := "http://xvz.myserver.com:9000/path/create" 

    postBytesReader := bytes.NewReader([]byte(js)) 
    request, _ := http.NewRequest("POST", url2, postBytesReader) 

    resp, err := cli.Do(request) 
    if err != nil { 
     fmt.Println(err) // Post http://xvz.myserver.com:9000/path/create: EOF 
     return 
    } 
    body, _ := ioutil.ReadAll(resp.Body) 
    fmt.Println(string(body)) 

    defer resp.Body.Close() 
} 

func main() { 
    client := &http.Client{ 
     CheckRedirect: nil, 
    } 

    for i := 0; i < num; i++ { 
     var pq CreateReqInfo 
     pq.Uid = strconv.Itoa(bid + i) 
     petstr, _ := json.Marshal(pq) 
     go DoCreate(string(petstr), client) 
    } 
} 

Проблема о количестве дескрипторов файлов или макс соединений?

+0

В какой ОС вы работаете? – fredrik

+0

Возможно, вы захотите изменить свой параллелизм, чтобы у вас был фиксированный набор goroutines, которые сотрудничают для завершения работы.На данный момент вы разворачиваете ряд горуций, равный общей сумме работы, которая может быть немного переборщицей. См. «Рабочие пулы»: https://gobyexample.com/worker-pools – dyoo

+0

Я проверю стабильность моего сервера. поэтому я хочу анализировать данные, когда сервер работает под высоким давлением. os is centos ~~ – nemo

ответ

1

Мне кажется, что у вас может возникнуть проблема, описанная в this answer. В основном, HTTP-клиент Go будет пытаться повторно использовать соединения, если вы не конкретно указано, что он не должен ни в Transport вы установите Client экземпляр для использования или на самом запросе с:

request.Close = true 

Этом становится проблемой, когда сервер на другом конце закрывает соединение, не указывая так с заголовком Connection: close в ответе. В коде net.http предполагается, что соединение все еще открыто, поэтому следующий запрос, который пытается использовать соединение далее, встречает EOF от закрытого соединения в другое время.

Вам нужно будет проверить, что происходит в связи с 1000-м запросом. Установлен ли сервер приема для ограничения количества подключений на одного клиента? Ваш код работает в тайм-аут соединения? В любом случае, если это так, соединение закрывается сервером таким образом, что код Go Client не может предсказать, тогда вы столкнетесь с EOF.

+0

Да, проблема в том, что количество соединений – nemo

0
  • Во-первых, что для вас экземпляр нового клиента каждый раз client := &http.Client{... внутри DoCreate() внутри цикла? Клиент может быть многоразового использования одновременно, поэтому вы можете его построить более глобально, мне кажется, говорит в main().
  • Тогда для меня такая ошибка выглядит как производства RoundTrip, поэтому по подключению, возможно, с сайта сервера. Можете ли вы проверить с насмешливым сервером?
  • Наконец, если все это не поможет, то да, некоторые системы имеют ограничение на число открытых FileDescriptors, которые каждый net.Conn хочет иметь собственный. Это ограничение может быть устранено только на уровне ОС.
+0

спасибо за вашу помощь, вы правы: «Клиент может быть повторно использован одновременно» – nemo

1

EOF обычно находится на сервере, который не возвращает полный заголовок (включая как CRLF s), так и соединение закрывается до завершения заголовка. Скорее всего, вы перегрузите свой сервер параллельными запросами, хотя вы должны убедиться, что у вас есть достаточные ресурсы локально для количества одновременных запросов, которые вы делаете. Если num достаточно велик, у вас что-то закончится.

Хотя ошибка на самом деле не описательна, больше не о чем беспокоиться, чем о любой другой ошибке запроса. Это условие ошибки, и обрабатывайте его так же, как и любые другие. Если вы хотите знать наверняка, скорее всего, вам понадобится пакетный захват соединения, вызывающего EOF.

Смежные вопросы