Что я получаю эту ошибку: EADDRINUSE, адрес уже используется при стресс-тестировании Node.js с помощью cradle и CouchDB? - PullRequest
1 голос
/ 12 сентября 2011

Я пытаюсь измерить пропускную способность простой программы Node.js с бэкэндом CouchDB, используя cradle в качестве драйвера БД. Когда я помещаю нагрузку на программу, я получаю следующую ошибку в течение 30 секунд:

EADDRINUSE, адрес уже используется

Вот моя программа:

var http = require ('http'),
    url = require('url'),
    cradle = require('cradle'),
    c = new(cradle.Connection)('127.0.0.1',5984,{cache: false, raw: false}),
    db = c.database('testdb'),
    port=8081;

http.createServer(function(req,res) {
    var id = url.parse(req.url).pathname.substring(1);  
    db.get(id,function(err, doc) {
      res.writeHead(200,{'Content-Type': 'application/json'});
      res.write(JSON.stringify(doc));
      res.end();
    });
}).listen(port);

console.log("Server listening on port "+port);

Я использую скрипт JMeter с 50 одновременными пользователями. Среднее время ответа составляет 120 мс, средний размер возвращаемого документа 3 КБ.

Как видите, я установил кеширование Cradle на false. Чтобы исследовать, я посмотрел на количество ожидающих сокетов: оно увеличивается примерно до 4000, и в этот момент происходит сбой (netstat | grep WAIT | wc -l)

Чтобы проверить другие параметры, я установил кеширование на true. В этом случае программа не аварийно завершает работу, но число ожидающих сокетов увеличивается с течением времени почти до 10000.

Я также написал ту же программу (без асинхронной части), что и сервлет Java, и она работает нормально, а число ожидающих сокетов не превышает 20.

У меня вопрос: почему я получаю сообщение об ошибке «EADDRINUSE, Адрес уже используется»? Почему так много ожидающих сокетов?

P.S .: Это фрагмент из вывода netstat | grep WAIT:

tcp4       0      0  localhost.5984         localhost.58926        TIME_WAIT
tcp4       0      0  localhost.5984         localhost.58925        TIME_WAIT
tcp4       0      0  localhost.58924        localhost.5984         TIME_WAIT
tcp4       0      0  localhost.58922        localhost.5984         TIME_WAIT
tcp4       0      0  localhost.5984         localhost.58923        TIME_WAIT

Ответы [ 2 ]

2 голосов
/ 12 сентября 2011

Вы уверены, что у вас нет процесса зомби на 8001?

    ps aux | grep node

может помочь

Также написал статью, чтобы помочь людям начать работу с node и couchdb, если вызаинтересованы вы можете проверить http://writings.nunojob.com/2011/09/getting-started-with-nodejs-and-couchdb.html

2 голосов
/ 12 сентября 2011

Обновление до колыбели 0.5.6. У него нет проблемы.

Предположение о проблеме

Ожидающие сокеты , вероятно, в состоянии CLOSE_WAIT . (Существуют другие состояния, которые соответствуют вашему grep, например TIME_WAIT. Можете ли вы подтвердить, что это CLOSE_WAIT, а не что-нибудь еще?)

В связанном посте есть полезная цитата:

RF793 говорит, что CLOSE_WAIT - это стек TCP / IP, ожидающий локального приложения. освободить розетку. Итак, он зависает, потому что он получил информацию что удаленный хост инициировал отключение и закрывает сокет, на что локальное приложение не закрыло свою сторону.

Поэтому, возможно, решение состоит в том, чтобы найти исправление ошибки для вашего приложения ...

Действительно. В вашем случае два соединения на запрос, одно от JMeter до Node, а другое от Node до CouchDB. Либо JMeter (более старое, более зрелое программное обеспечение) не закрывает соединение должным образом, либо Cradle (более новое, менее зрелое программное обеспечение) не закрывает соединение должным образом. Очевидно, что Cradle - наиболее вероятная ошибка. (Возможно, это сама HTTP-библиотека NodeJS, но Cradle кажется первым местом для проверки.)

У меня нет полного ответа, но, надеюсь, это будут полезные подсказки. Я думаю ошибка в использовании адреса из-за того, что больше нет исходных адресов для создания «исходящего» (даже для 127.0.0.1) соединения. Но я до сих пор не уверен, почему счетчик CLOSE_WAIT отличается в каждом испытании. (Возможно, он сильно колеблется, поскольку целые пулы соединений закрыты.)

Чтобы получить больше информации, возможно, попробуйте альтернативную клиентскую библиотеку CouchDB, такую ​​как request или nano и сравните результаты.

Пожалуйста, сообщите нам, что вы найдете, потому что было бы замечательно выявить и закрыть эту потенциальную ошибку Cradle (или ошибку где-то по крайней мере!). Спасибо.

...