История вопроса / проблема
У меня есть приложение node.js, которое я унаследовал сегодня. Мы замечаем, что на сервере ... "что-то" ускоряет несколько подключений в локальной базе данных Redis ... и я подозреваю, что приложение node.js, которое у нас работает.
Это node.js приложение использует следующие библиотеки:
https://github.com/NodeRedis/node-redis https://github.com/moaxaca/async-redis#readme
Код
Вот как выглядит частично рассматриваемый код:
1
2 const axios = require('axios');
3 const redis = require('redis');
4 const asyncRedis = require("async-redis");
5 const xml2js = require('xml2js');
6
7
8 const redisOptions = {};
9 const redclient = redis.createClient(redisOptions);
10
18 async function onMessage(channel, message) {
19 console.log('Sub Msg:', channel, message);
20 if( channel === 'started' ){
21 setTimeout(() => {getStats(message.split(':')[0])}, 20000);
22 } else {
23 triggerUpdate();
24 }
25 }
26
38 async function triggerUpdate() {
39 const now = Date.now();
40 const diff = now - lastUpdate;
41 if( diff < TIMER_MIN && timer ) {
42 clearTimeout(timer);
43 timer = setTimeout(triggerUpdate, TIMER_MIN-diff);
44 return;
45 };
46 if( timer ){
47 clearTimeout(timer);
48 }
49 lastUpdate = now;
50
51
52 rc = asyncRedis.createClient(redisOptions);
53
54 const buStreams = [];
55
56 await scanHelper(rc, ['match', 's:*', 'count', '100'], async (keys) => {
57 for (const key of keys) {
58 const keyParts = key.split(':');
59 const a = keyParts[1];
60 const b = keyParts[2];
61 const c = await rc.get('widgetid:' + name + ':' + token);
62
63 const stream = {
64 a,
65 b,
66 c,
67 clients: [],
68 };
69
70 const match = 'c:' + name + ':' + token + ':*';
71 await scanHelper(rc, ['match', match, 'count', '100'], async (ckeys) => {
72 for( const ckey of ckeys ){
73 const obj = await rc.hgetall(ckey);
74
75 const ckeyParts = ckey.split(':');
76 obj.b = ckeyParts[4];
77 obj.c = ckeyParts[3];
78 stream.clients.push(obj);
79 }
80 });
81
82 if (stream.clients.length > 0) {
83 buStreams.push(stream);
84 }
85 }
86 });
87
88 if (buStreams.length > 0) {
89 const payload = { streams: buStreams };
90
91 console.log('Update Payload', new Date(), JSON.stringify(payload));
92 const res = await axios.post('http://localhost/statsapi/bbclients', payload);
93 if( res.status !== 200 ){
94 console.log('Update Fail', res.status, res.data);
95 }
96 }
97
98 timer = setTimeout(triggerUpdate, TIMER_MAX);
99 }
И вот как запускается скрипт:
154 function main() {
155
156 redclient.on('message', onMessage);
157 redclient.subscribe('started');
158 redclient.subscribe('stopped');
159 redclient.subscribe('new');
160 triggerUpdate();
161 }
162
163 main();
Как Вы можете видеть, что в строке 52 мы создаем новое подключение asyncRedis к базе данных без установленных параметров (фактически, redisOptions - это пустой массив)
Нужно ли явно уничтожать этот объект? Я хочу добавить после строки 98 r c .quit () Но я где-то читал, что с помощью redis вам не нужно «чистить» соединения. Извините, просто нуб с redis, node и очередями сообщений. Любая помощь будет принята.
РЕДАКТИРОВАТЬ 1
Итак, изначально я пропустил включение строк 1 - 9 кода.
Теперь, когда мы смотрим на полная картина, кажется, что мы:
- создаем «обычное» соединение в строке 9. Используя это соединение, мы подписываемся на различные очереди сообщений в строке 155 - 159.
- Внутри логики c, которая должна запускаться при каждой публикации события (triggerUpdate ()), похоже, они создают new соединение с базой данных, называемое r c, используя асин c -redis library.
Я добавил строку в конце функции triggerUpdate для вызова
"r c .quit ()"
Это, похоже, исправило проблему, когда мы видим все больше и больше слушателей на порту 6379 для redis. Теперь он просто стабильно сидит на 5-6 соединениях. и я проверил, поместив сообщение в одну из очередей ... и это приложение node.js, похоже, забирает его.
Любые другие комментарии / предложения будут оценены