์๋ ์ฝ๋๊ฐ ์๊ณ iptables -A OUTPUT -p tcp --dport 6379 -j REJECT
์ฌ์ฉํ์ฌ ์ฐ๊ฒฐ ๋๊น์ ๋ชจ๋ฐฉํ๋ ค๊ณ ํฉ๋๋ค.
self.client = redis.createClient(self.cfg.port, self.cfg.host, {
retry_strategy: function (options) {
console.log('retry strategy check');
console.log(options);
if (options.error) {
if (options.error.code === 'ECONNREFUSED') {
// End reconnecting on a specific error and flush all commands with a individual error
return new Error('The server refused the connection');
}
if (options.error.code === 'ECONNRESET') {
return new Error('The server reset the connection');
}
if (options.error.code === 'ETIMEDOUT') {
return new Error('The server timeouted the connection');
}
}
if (options.total_retry_time > 1000 * 60 * 60) {
// End reconnecting after a specific timeout and flush all commands with a individual error
return new Error('Retry time exhausted');
}
if (options.attempt > 5) {
// End reconnecting with built in error
return new Error('Retry attempts ended');
}
// reconnect after
return 1000;
}
});
self.client.on('ready', function () {
log.trace('Redis client: ready');
});
self.client.on('connect', function () {
log.trace('Redis client: connect');
});
self.client.on('reconnecting', function () {
log.trace('Redis client: reconnecting');
});
self.client.on('error', function (err) {
log.error({err: err}, 'Listener.redis.client error: %s', err);
process.exit(1);
});
self.client.on('end', function () {
log.trace('Redis client: end');
});
self.client.on('warning', function () {
log.trace('Redis client: warning');
});
๋ชจ๋ redis ์ค๋ฅ๋ error ์ด๋ฒคํธ์์ ๋ฐ์ํ๋ค๊ณ ๊ฐ์ ํฉ๋๋ค. ํ์ง๋ง ๋ค์์ ์ฝ์ ์ถ๋ ฅ์ ์๋ ๋ด์ฉ์ ๋๋ค.
21:00:14.666Z TRACE ์คํฌ๋ฆฝํธ: Redis ํด๋ผ์ด์ธํธ: ์ฐ๊ฒฐ
21:00:14.695Z TRACE ์คํฌ๋ฆฝํธ: Redis ํด๋ผ์ด์ธํธ: ์ค๋น๋จ
21:10:23.837Z TRACE ์คํฌ๋ฆฝํธ: Redis ํด๋ผ์ด์ธํธ: ์ข ๋ฃ
์ฌ์๋ ์ ๋ต ํ์ธ
{ ์๋: 1,
error: { [์ค๋ฅ: redis.callision์ ๋ํ Redis ์ฐ๊ฒฐ. ์ ๋ณด:6379 ์คํจ - ECONNRESET ์ฝ๊ธฐ] ์ฝ๋: 'ECONNRESET', errno: 'ECONNRESET', ์์คํ ํธ์ถ: '์ฝ๊ธฐ' },
total_retry_time: 0,
times_connected: 1 }/node_modules/q/q.js:155
๋์ง๋ค ์ ์;
^^
AbortError: ์คํธ๋ฆผ ์ฐ๊ฒฐ์ด ์ข ๋ฃ๋๊ณ ๋ช ๋ น์ด ์ค๋จ๋์์ต๋๋ค. ์ฒ๋ฆฌ๋์์ ์ ์์ต๋๋ค.
RedisClient.flush_and_error์์ (/node_modules/redis/index.js:350:23)
RedisClient.connection_gone์์ (/node_modules/redis/index.js:612:18)
RedisClient.on_error์์ (/node_modules/redis/index.js:398:10)
์์ผ์์.(/node_modules/redis/index.js:272:14)
emitOne์์ (events.js:90:13)
Socket.emit์์(events.js:182:7)
emitErrorNT์์ (net.js:1255:8)
nextTickCallbackWith2Args์์ (node.js:474:9)
process._tickCallback์์ (node.js:388:17)
๊ทธ๋ฆฌ๊ณ ์ง๋ฌธ์ผ๋ก: ์ฐ๊ฒฐ์ด ๋์ด์ง ๊ฒ์ ๊ฐ์งํ๋ ๋ฐ ์ฝ 10๋ถ์ด ๊ฑธ๋ฆฌ๋ ์ด์ ๋ ๋ฌด์์ ๋๊น? 10์ด ์ด๋ด์ ์๋ต์ด ์์ ๋ ์ค๋ฅ๋ฅผ ๋ฐ์์ํค๋ ๋ฐฉ๋ฒ์ด ์์ต๋๊น? response_timeout ๋ฑ๊ณผ ๊ฐ์ ์ต์ ์ผ ์ ์์ต๋๋ค.
@pavelsc ๋๋ ์ด๊ฒ์ ์ฌํํ๋ ค๊ณ ์๋ํ์ง๋ง ์ง๊ธ๊น์ง๋ ํ ์ ์์์ต๋๋ค.
ํ์ฌ ๋ชจ๋ ์์ด ๋ฌธ์ ๋ฅผ ์ฌํํด ๋ณด์ญ์์ค. ํ์ฌ ์ต์ํ q
์ฌ์ฉํ๋ ๊ฒ ๊ฐ์ต๋๋ค.
๊ฐ์ ์ค๋ฅ๊ฐ ๋ฐ์ํ์ต๋๋ค. ์๋์ ์ผ๋ก Redis ํด๋ผ์ด์ธํธ์ ์๋ชป๋ URL์ ์ ๊ณตํ๋ฉด on.error ๋ฉ์๋๊ฐ ํธ์ถ๋์ง ์์ต๋๋ค. ๋ค์์ ๊ฐ๋จํ ์์ ๋๋ค.
var redis = require("redis");
exports.handler = function (event, context, callback) {
console.log("Executing test lambda for diagnosing redis issues");
var redisInfo = {
HOST: process.env.REDIS_HOST,
PORT: process.env.REDIS_PORT
};
console.log(process.env.REDIS_HOST);
console.log(process.env.REDIS_PORT);
console.log("Connecting to Redis...");
var client = redis.createClient({
host: redisInfo.HOST,
port: redisInfo.PORT,
retry_strategy: function (options) {
if (options.total_retry_time > 2000) {
console.log("throwing an error...");
return new Error('Retry time exhausted');
}
return 200;
}
});
// if you'd like to select database 3, instead of 0 (default), call
// client.select(3, function() { /* ... */ });
client.on("error", function (err) {
console.log("Error " + err);
callback(null, "Error with Redis");
});
client.on('connect', function() {
console.log("Connected to Redis");
});
client.on('end', function() {
console.log("Redis end");
});
client.set("string key", "string val", redis.print);
client.hset("hash key", "hashtest 1", "some value", redis.print);
client.hset(["hash key", "hashtest 2", "some other value"], redis.print);
client.hkeys("hash key", function (err, replies) {
console.log(replies.length + " replies:");
replies.forEach(function (reply, i) {
console.log(" " + i + ": " + reply);
});
client.quit();
});
client.quit();
callback(null, "Success");
};
์ง๊ธ์ ์ฐ๊ฒฐ ์ ํ ์๊ฐ์ด ๋ง๋ฃ๋ ํ ์ฌ๋ฐ๋ฅด๊ฒ '์ค๋ฅ'๊ฐ ๋ฐ์ํ๋ connect_timeout์ ์ฌ์ฉํ๋๋ก ๋๋๋ฆฌ๊ณ ์์ต๋๋ค.
๋์ผํ ๋ฌธ์ ๊ฐ ์์ต๋๋ค. ์๋ชป๋ ๋์ ์ด ์๋ ์ฌ์ฉ์ ์ง์ retry_strategy๋ฅผ ์ฌ์ฉํ๋ฉด "AbortError:"๊ฐ ๋ฐ์ํฉ๋๋ค.
์ด๊ฒ์ ์ค๋๋ ๋๋ฅผ ์ฌ๋ก์ก์๋ค. ์ฝ๋๋ฅผ ๊ฐ๋จํ ์ดํด๋ณด๋ฉด ์ด๊ฒ์ ์๋์ ์ธ ๋์์ผ๋ก ๋ณด์
๋๋ค. https://github.com/NodeRedis/node_redis/blob/79558c524ff783000a6027fb159739770f98b10e/index.js#L405 ๋ retry_strategy
๊ฐ ์ค์ ๋๋ฉด ์ค๋ฅ๋ฅผ ๋ด๋ณด๋ด์ง ์๊ณ ๋์ ๊ณ์ ๋์ง๋ค๊ณ ๋ช
์์ ์ผ๋ก ๋ช
์ํ๊ณ ์์ต๋๋ค. ์ ์ด๋ฌ๋์ง ๊ถ๊ธํ๊ธด ํ๋ฐ, ํํ ๋์ง๋ค๊ธฐ ๋ณด๋ค๋ ๋ฐ์ฐํ์ง ๋ชปํ๋ ์ด์ ๊ฐ ์๋ ๊ฒ ๊ฐ์ต๋๋ค. ์ด ์กฐ๊ฑด๋ฌธ์ด ์ ๊ฑฐ๋์ง ์์ ํญ์ ์ค๋ฅ๊ฐ ๋ฐ์ํ๋ ์ด์ ๊ฐ ์์ต๋๊น?
์ ๋ ์ด ๋ฌธ์ ๋ฅผ ์ง์์ ์ผ๋ก ๊ฒช๊ณ ์์ต๋๋ค.
๋๋ ENOTFOUND
๋ฐ์ ๋ ์ค๋ฅ๋ฅผ ์ก์ ์ ์์ต๋๋ค.
{
host: "foo",
retry_strategy: function (options) {
if (options.error && options.error.code === "ENOTFOUND") {
return new Error("The server was not found");
}
// reconnect after
return 1000;
}
์ ํจ๊ป:
redis.on("error", err => {
console.error("Cache Error: " + err);
});
์์ฉ ํ๋ก๊ทธ๋จ์ ๋๋ฒ๊น
ํ ๋ retry_strategy
์์ ์์์ ์ธ๊ธํ ๋๋ก ENOTFOUND
๊ฒ์ฌ์ ๋ค์ด๊ฐ๊ณ ์์ง๋ง ์ค๋ฅ ์ด๋ฒคํธ ์ฒ๋ฆฌ๊ธฐ๋ฅผ ํธ์ถํ์ง ์์ต๋๋ค.
๋์ผํ ๋ฌธ์ ๊ฐ ์์ต๋๋ค. ์์ค ์ฝ๋๋ฅผ ์กฐ์ฌํ ํ ๋ณ๊ฒฝํ๋ฉด
์ด ์ค(๋๋ ๋๋ฒ๊ทธ ๋ชจ๋ ํ์ฑํ)
https://github.com/NodeRedis/node_redis/blob/009479537eb920d2c34045026a55d31febd1edd7/index.js#L381 -L382
๊ทธ๋ฆฌ๊ณ ์ฌ๊ธฐ์ ์ด โโ์ฝ๋๋ฅผ ์ฝ์
ํ์ญ์์ค(์ฆ์ ๋ฐฐ์ด์ ์ค๋ฅ๋ฅผ ์ถ๊ฐํ์ญ์์ค)
https://github.com/NodeRedis/node_redis/blob/009479537eb920d2c34045026a55d31febd1edd7/index.js#L352 -L353
if (options.error) {
aggregated_errors.push(options.error);
}
์ ๋๋ก ์๋ํ๊ณ '์ค๋ฅ'๊ฐ ๋ฐ์ํฉ๋๋ค.
ํด๋น ํจ์์ ์ค์ฒฉ ๋ฃจํ๋ ์คํ๋์ง ์์ต๋๋ค. 'command_queue'๊ฐ ๋น์ด ์๊ณ error never get์ด ๋ฐฐ์ด์ ์ถ๊ฐ๋์ด ๋ฐฉ์ถ๋์ง ์๊ธฐ ๋๋ฌธ์ ๋๋ค. ๋ด๊ฐ ์ฌ๋ฐ๋ฅด๊ฒ ์ดํดํ๋ค๋ฉด ๊ฝค ์ค๋๋ ์ฝ๋์ด๋ฏ๋ก ์ ์ง ๊ด๋ฆฌ์ ๋๋ @BridgeAR์ ์ ๋ ฅ์ด ํ์ํฉ๋๋ค.
๋๋ ๋ํ ์ฒซ ๋ฒ์งธ ์คํจํ ์ฐ๊ฒฐ์์ 'end' ์ด๋ฒคํธ๋ฅผ ๋ด๋ณด๋ด๋ ๊ฒ์ ๋ณด์์ต๋๋ค. ์ด๋ ๋ฌด์ธ๊ฐ๋ฅผ ์๋ฏธํ ์ ์์ต๋๋ค(๋๋ ๊ทธ๋ ์ง ์์ ์๋ ์์). ์ดํ ์ ์ Redis๋ฅผ ์ง์ด ๋ค์๊ธฐ ๋๋ฌธ์ ๋ด๋ถ๊ฐ ์์ง ์ด๋ป๊ฒ ์๋ํ๋์ง ์ ๋ชจ๋ฅด๊ฒ ์ต๋๋ค. ์๊ฐ์ด ์์ ๋ ํฌํฌํ๊ณ ์กฐ๊ธ ๋ ํํค์ณ๋ณด๋ ค๊ณ ํฉ๋๋ค.
๊ทธ๋ฆฌ๊ณ ๋ง ๊ทธ๋๋ก ๋ค์ ๋ฌธ์ ๋ ์ด ๋ฌธ์ #1198๊ณผ ์ฐ๊ฒฐ๋ ๊ฒ ๊ฐ์ต๋๋ค.
@v1adko ์ ๋ ํ์ฌ ์ฌํ ์ค์ด์ง๋ง ์ค๋์ด๋ ๋ด์ผ(Ruben์ด ์ ๋ฅผ
์ค๋ฅ ์๋๋ฆฌ์ค๋ฅผ ํ ์คํธํ๊ธฐ ์ํด ์๋์ ์ผ๋ก ์๋ชป๋ redis URL์ด ์์ง๋ง redis์ ์ฐ๊ฒฐํ๋ ค๊ณ ํ ๋ retry_strategy๊ฐ ํธ์ถ๋์ง ์๋ ๊ฒ์ ๋ด ๋๋ค. retry_strategy๋ ์ฐ๊ฒฐ์ด ๋ซํ ๋๋ง ํธ์ถ๋ฉ๋๋ค.
`const redis = require('redis');
const ๋ก๊ทธ = require('./logUtil').logger;
module.exports.connect = () => {
var redisRetryStrategy = function(options) {
if (options.error && options.error.code === 'ECONNREFUSED') {
// End reconnecting on a specific error and flush all commands with
// a individual error
log.error('The redis server refused the connection');
return new Error('The redis server refused the connection');
}
log.info(`Already spent ${options.total_retry_time} milliseconds to re-establish connection with redis`);
if (options.total_retry_time > 2000) {
// End reconnecting after a specific timeout and flush all commands
// with a individual error
log.error('Retry time exhausted');
return new Error('Retry time exhausted');
}
log.info(`Attempting ${options.attempt} time to establish connection with redis`);
if (options.attempt > 5) {
// End reconnecting with built in error
log.error('Exhausted the retry attempts to establish connection to redis');
return undefined;
}
// reconnect after
return 100;
}
log.info(`Redis connection url is :${process.env.REDIS_URL}`);
var redisClient = redis.createClient(qualifyUrl(process.env.REDIS_URL), {
retry_strategy: redisRetryStrategy
});
redisClient.offline_queue_length = 3;
redisClient.on('connect', function() {
console.log('Connected to Redis');
});
redisClient.on('reconnecting', function() {
console.log('Re-Connecting to Redis');
});
redisClient.on('error', (err)=> {
console.log(`Error trying to create redis connection: ${JSON.stringify(err)}`);
});
return redisClient;
}
const qualifyUrl = (URL) => {
return '//' + url.replace(/^\/+/,"");
};
`
๋๊ตฐ๊ฐ๊ฐ์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ๋ฐ ๋์์ ์ค ์ ์์ต๋๊น?
์ฌ๊ธฐ๋ ๋ง์ฐฌ๊ฐ์ง์ ๋๋ค. ์ด ๋ถ์พํ ํดํน์ ์์๋๋ ๋์์ ์์ฑํ๋ ๊ฒ ๊ฐ์ง๋ง ๋ ๋์ ์๋ฏธ๊ฐ ์๋์ง ํ์คํ์ง ์์ต๋๋ค.
const client = redis.createClient({
retry_strategy: ({error}) => client.emit('error', error)
});
client.on('error', console.error);
๋๋ ํ์ฌ ๊ฐ์ ๋ฌธ์ ๋ฅผ ๊ฒช๊ณ ์์ต๋๋ค. retry_strategy๋ฅผ ์ฌ์ฉํ์ฌ Readme์ ์์ ์ ํ์๋ ๋๋ก ์ค๋ฅ๋ฅผ ๋ฐํํ์ง๋ง ํด๋ผ์ด์ธํธ์์ ์ค๋ฅ๊ฐ ๋ฐ์ํ์ง ์์ต๋๋ค. @v1adko๊ฐ ์ ์ํ ์์ ์ฌํญ์ ์ ์ด๋ ์ก๋ฉด ๊ทธ๋๋ก ๋ฌธ์ ๋ฅผ ํด๊ฒฐํฉ๋๋ค.
์ฌ๊ธฐ์ ์ธ๊ธ๋ ์ด์ ๋ฒ์ ๊ณผ์ ๋นํธํ์ฑ์ด ๋ฌด์์ธ์ง ๊ถ๊ธํฉ๋๋ค.
https://github.com/NodeRedis/node_redis/blob/009479537eb920d2c34045026a55d31febd1edd7/index.js#L380
@maael์ด ์ง์ ํ ๊ฒ์ฒ๋ผ ๋์์ retry_strategy๊ฐ ์ค์ ๋ ๊ฒฝ์ฐ ์๋์ ์ธ ๊ฒ์ผ๋ก ๋ณด์ ๋๋ค. ์์๋๋ ๋์์ด์ง๋ง ๋ฌธ์๊ฐ ์ฌ๋ฐ๋ฅด์ง ์์ต๋๊น? @c24w์์ ์ ์ํ ๋๋ก ์๋์ผ๋ก ํด๋ผ์ด์ธํธ์ ๋ํ ์ค๋ฅ๋ฅผ ๋ด
ํธ์ง: ํจํค์ง๋ฅผ ํํค์น๋ฉด์ ์๋์ผ๋ก ๋ฐฉ์ถํ๋ ๊ฒ์ด ์๋ง๋ ์์ผ๋ก ๋์๊ฐ ๊ธธ์ด ์๋๋ผ๋ ๊ฒ์ ๊นจ๋ซ๊ณ ์์ต๋๋ค. ์ธ๊ธ๋ ์ฃผ์ ๋ณ๊ฒฝ ์ฌํญ์ ์ดํดํด์ผ ํ๋ ๊ฒ ๊ฐ์ต๋๋ค.
์ด๋ค ์์์ด ์์ต๋๊น? ๋๋ ๊ฐ์ ๋ฌธ์ ๋ฅผ ๊ฐ์ง๊ณ ์๋ค.
์์์ด ์๋์?
ํ๋ ๊ฒ์ ์๋ชป๋ ์๊ฐ์
๋๋ค.
js
if (options.error && options.error.code === 'ECONNREFUSED') {
// End reconnecting on a specific error and flush all commands with
// a individual error
return Math.min(options.attempt * 100, 3000);
}
๋์ผํ ๋ฌธ์ ๊ฐ ์๋๋ฐ retry_Strategy๊ฐ ์ค๋ฅ ์ด๋ฒคํธ๋ฅผ ํธ๋ฆฌ๊ฑฐํ์ง ์๊ณ ์์ง ์์ ๋์ง ์์์ต๋๊น?
์ฑ๊ณตํ์ ๋ถ ๊ณ์ ๊ฐ์?
๋์ ๊ตฌํ์ https://github.com/luin/ioredis ๋ก ์ ํํ์ฌ ๋ช ๊ฐ์ง ๊ฐ์ ์ฌํญ์ ๊ฐ์ ธ์์ต๋๋ค(๋ค์ดํฐ๋ธ Promises, lazyConnect(redis ํด๋ผ์ด์ธํธ๋ฅผ ์ธ์คํด์คํํ ๋ ์ฐ๊ฒฐ์ ์ด์ง ์๊ณ ํ์ํ ์์น์์ ์ค๋ฅ๋ฅผ ์ ํํ๊ฒ ์ฒ๋ฆฌํ๋ ๋ฐ ๋์์ด ๋จ)). ๋ค์ ์ฝ๋๋ฅผ ์คํํ ์ ์์ต๋๋ค.
let cachedItem;
try {
logger.debug(`Fetching GraphCMS query in redis cache...`);
// XXX If fetching data from redis fails, we will fall back to running the query against GraphCMS API in order to ensure the client gets the data anyway
cachedItem = await redisClient.get(body);
} catch (e) {
logger.debug(`An exception occurred while fetching redis cache.`);
logger.error(e);
epsagon.setError(e);
}
๋ค์ utils/redis.js
:
import { createLogger } from '@unly/utils-simple-logger';
import Redis from 'ioredis';
import epsagon from './epsagon';
const logger = createLogger({
label: 'Redis client',
});
/**
* Creates a redis client
*
* <strong i="11">@param</strong> url Url of the redis client, must contain the port number and be of the form "localhost:6379"
* <strong i="12">@param</strong> password Password of the redis client
* <strong i="13">@param</strong> maxRetriesPerRequest By default, all pending commands will be flushed with an error every 20 retry attempts.
* That makes sure commands won't wait forever when the connection is down.
* Set to null to disable this behavior, and every command will wait forever until the connection is alive again.
* <strong i="14">@return</strong> {Redis}
*/
export const getClient = (url = process.env.REDIS_URL, password = process.env.REDIS_PASSWORD, maxRetriesPerRequest = 20) => {
const client = new Redis(`redis://${url}`, {
password,
showFriendlyErrorStack: true, // See https://github.com/luin/ioredis#error-handling
lazyConnect: true, // XXX Don't attempt to connect when initializing the client, in order to properly handle connection failure on a use-case basis
maxRetriesPerRequest,
});
client.on('connect', function () {
logger.info('Connected to redis instance');
});
client.on('ready', function () {
logger.info('Redis instance is ready (data loaded from disk)');
});
// Handles redis connection temporarily going down without app crashing
// If an error is handled here, then redis will attempt to retry the request based on maxRetriesPerRequest
client.on('error', function (e) {
logger.error(`Error connecting to redis: "${e}"`);
epsagon.setError(e);
});
return client;
};
๊ทธ๋ฆฌ๊ณ utils/redis.test.js
ํ์ผ:
import { getClient } from './redis';
let redisClient;
let redisClientFailure;
describe('utils/redis.js', () => {
beforeAll(() => {
redisClient = getClient();
redisClientFailure = getClient('localhost:5555', null, 0); // XXX This shouldn't throw an error because we're using lazyConnect:true which doesn't automatically connect to redis
});
afterAll(async () => {
await redisClient.quit();
await redisClientFailure.quit();
});
describe('should successfully init the redis client', () => {
test('when provided connection info are correct', async () => {
// Environment variables are from the .env.test file - This tests a localhost connection only
expect(redisClient.options.host).toEqual(process.env.REDIS_URL.split(':')[0]);
expect(redisClient.options.port).toEqual(parseInt(process.env.REDIS_URL.split(':')[1], 10));
expect(redisClient.options.password).toEqual(process.env.REDIS_PASSWORD);
});
test('when connection info are incorrect', async () => {
expect(redisClientFailure.options.host).toEqual('localhost');
expect(redisClientFailure.options.port).toEqual(5555);
});
});
describe('should successfully perform native operations (read/write/delete/update)', () => {
test('when using async/await (using native node.js promises)', async () => {
const setResult = await redisClient.set('key-1', 'value-1');
expect(setResult).toEqual('OK');
const result = await redisClient.get('key-1');
expect(result).toEqual('value-1');
const delResult = await redisClient.del('key-1');
expect(delResult).toEqual(1);
const setResultB = await redisClient.set('key-1', 'value-1b');
expect(setResultB).toEqual('OK');
const resultB = await redisClient.get('key-1');
expect(resultB).toEqual('value-1b');
const setResultC = await redisClient.set('key-1', 'value-1c');
expect(setResultC).toEqual('OK');
const resultC = await redisClient.get('key-1');
expect(resultC).toEqual('value-1c');
});
});
describe('should allow to catch an error when failing to open a connection to redis, in order to gracefully handle the error instead of crashing the app', () => {
test('when connection info are incorrect', async () => {
expect(redisClientFailure.options.host).toEqual('localhost');
expect(redisClientFailure.options.port).toEqual(5555);
try {
await redisClientFailure.set('key-1', 'value-1'); // This should throw an error, because the connection to redis will be made when executing the
expect(true).toBe(false); // This shouldn't be called, or the test will fail
} catch (e) {
expect(e).toBeDefined();
expect(e.message).toContain('Reached the max retries per request limit');
}
await redisClientFailure.quit();
});
});
});
ํ๊ฒฝ ๋ณ์:
REDIS_URL=localhost:6379
REDIS_PASSWORD=mypasswordissostrong
๊ฐ์ฅ ์ ์ฉํ ๋๊ธ
์ด๋ค ์์์ด ์์ต๋๊น? ๋๋ ๊ฐ์ ๋ฌธ์ ๋ฅผ ๊ฐ์ง๊ณ ์๋ค.