Сокеты не закрываются при использовании Node.js http.get
OS X 10.8.3
Node 0.10.0
Я использую модуль "http" для запросов API графиков Facebook.
Вот параметры, которые я передаю в 'http.get':
var options = {host: 'graph.facebook.com',
port: 80,
path: '/' + fb_id + '/picture'}; //fb_id is a Facebook user identifier
Мой код выглядит следующим образом:
http.get(options,
function(res) {
...some stuff...
DONE(RESULT); //DONE is a callback function
}).on('error', function(e) {
...some error handling...
});
Я наблюдаю, что я могу делать столько запросов, сколько значение http.globalAgent.maxSockets. Как только я дойду до этого множества запросов, следующий вызов http.get никогда (видимо) не подключается. Я проверял, что я не получаю ошибок в запросах.
Как будто сокеты не закрываются после ответа.
Есть ли что-то, что мне нужно сделать как часть обработчика ответа, чтобы убедиться, что сокет закрыт?
Являются ли эти сокеты не закрытыми из-за поведения keepalive по умолчанию?
Как мне отладить это?
Ответы
Ответ 1
Попробуйте установить agent: false
в параметрах. Поведение по умолчанию действительно должно поддерживать открытые соединения для HTTP keep-alive:
var options = {host: 'graph.facebook.com',
port: 80,
path: '/' + fb_id + '/picture',
agent: false};
Ответ 2
Node http-модуль утверждает, что агент по умолчанию использует глобальный агент: http://nodejs.org/api/http.html#http_http_globalagent, что означает, что keep-alive является общим, независимо от того, который инициирует запрос.
BTW, отвечая на комментарий Wes от 9 апреля 13 в 20:47: неважно, сколько раз вы загружаете модуль node, он будет загружаться только один раз и делиться всеми модулями.
То, что вы испытываете, - проблема исчерпания пула. Самый простой способ избежать этого - использовать новый агент (http://nodejs.org/api/http.html#http_class_http_agent) с вашими желаемыми maxSockets. Помните, что создаваемый вами агент может быть разделен между модулями, если вы поместите его в экспорт этого модуля (модули в node с сохранением состояния!!!).
Ответ 3
Я испытал такое же поведение, за исключением того, что мои соединения были, наконец, повторно использованы после периода ожидания. Проверьте, будут ли соединения повторно использоваться через определенный промежуток времени (пару минут), а также проверьте, содержат ли заголовки ответов "Connection: keep-alive".
Если в этом случае возможным решением было бы использовать заголовок "Соединение: Закрыть" вместо keep-alive, то пустые соединения можно было бы использовать повторно, как в обычной настройке. Я не уверен, что это приводит к любым проблемам производительности с использованием конечных точек facebook.
var options = {host: 'graph.facebook.com',
port: 80,
path: '/' + fb_id + '/picture',
headers: { 'Connection':'Close' }
};
Для меня использование агента: false не работает, потому что огромное количество запросов, которые я отправил, исчерпало ресурсы сервера.