gpt4 book ai didi

java - Redis中不同的连接异常

转载 作者:可可西里 更新时间:2023-11-01 11:36:44 29 4
gpt4 key购买 nike

我在服务器模式而不是集群模式下使用 Redis。我有 3 个正在运行的 Redis 服务器实例,3 个从属服务器对应于这 3 个主服务器。我还有 3 个哨兵,每个哨兵监视所有三个主控。

为了连接到我的 Sentinels 并创建一个池,我正在使用 ShardedJedisSentinelPool .现在我的类从这个池中获取连接看起来像这样

public class RedisServerConnectionDAL 
{
private RedisServerConnectionDAL()
{

}

private static ShardedJedisSentinelPool pool;
private static ShardedJedis jedis;
private static ShardedJedisPipeline pipeline;
private static Set<String> redissentinels;
private static List<String> redismasters;
private static int redistimeout;
private static RedisServerConnectionDAL redisdal;
private static Map<String,String> redisconfmap;
public static int WAIT_IF_FAIL;
public static int RETRIES;

public synchronized static RedisServerConnectionDAL getInstance()
{
if(redisdal==null)
{
Properties redisprops = new Properties();

redisprops = ConfigReader.ReadConfig(Constant.REDIS_CONNECTION_CONFIG_FILE);

GenericObjectPoolConfig config = new GenericObjectPoolConfig();

redisconfmap = new HashMap(redisprops);

redisdal = new RedisServerConnectionDAL();

String redisNodesString = redisconfmap.get(Constant.REDIS_SENTINELS);

redissentinels = new HashSet<String>(Arrays.asList(redisNodesString.split(Constant.CONFIGURATION_FILE_MULTIVALUE_SEPERATOR)));

String redisMastersString = redisconfmap.get(Constant.REDIS_MASTERS);

redismasters = new ArrayList<String>();

redismasters.addAll(Arrays.asList(redisMastersString.split(Constant.CONFIGURATION_FILE_MULTIVALUE_SEPERATOR)));

redistimeout = Integer.parseInt(redisconfmap.get(Constant.REDIS_TIMEOUT));

WAIT_IF_FAIL = Integer.parseInt(redisconfmap.get(Constant.REDIS_WAIT_IF_FAIL));

RETRIES = Integer.parseInt(redisconfmap.get(Constant.REDIS_RETRIES));

pool = new ShardedJedisSentinelPool(redismasters, redissentinels, config, redistimeout);

jedis = pool.getResource();

pipeline = jedis.pipelined();

}
return redisdal;
}

public ShardedJedis getJedisResource()
{
jedis = pool.getResource();
return jedis;
}

public ShardedJedisPipeline getPipelineResource()
{
pipeline = jedis.pipelined();
return pipeline;
}

public ShardedJedisPipeline getPipeline()
{
return pipeline;
}

public ShardedJedis getJedis()
{
return jedis;
}

public static void resetRedisServerConnectionDal()
{
pipeline = null;
jedis = null;
redisdal = null;
}
}

所以,现在无论我想与 Redis 交互,我都会做这样的事情

Jedis jedis = RedisServerConnectionDAL.getInstance.getJedis();

try
{
//code.....
}
catch(JedisConnectionException jce)
{
log.error(jce.getMessage());
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
jce.printStackTrace(pw);
log.error("Error:" + sw.toString());
if(retrycount < RedisServerConnectionDAL.RETRIES)
{
retrycount++;
log.error("Waiting for " + RedisServerConnectionDAL.WAIT_IF_FAIL + ", after which it will reconnect to Redis.");
try
{
Thread.sleep(RedisServerConnectionDAL.WAIT_IF_FAIL);
}
catch (InterruptedException e)
{
log.error(e.getMessage());
e.printStackTrace(pw);
log.error("Error:" + sw.toString());
log.error("Error while Sleeing!!!");
}
RedisServerConnectionDAL.resetRedisServerConnectionDal();

jedis = RedisServerConnectionDAL.getInstance();.getJedisResource();
pipeline = redisserverconnectiondal.getPipelineResource();
}
else
{
log.error("Redis retries exhausted");
log.error(jce.getMessage());
StringWriter sw1 = new StringWriter();
PrintWriter pw1 = new PrintWriter(sw1);
jce.printStackTrace(pw1);
log.error("Error:" + sw1.toString());
log.error("Error while executing pipeline in Redis!");
retrycount = 0;;
}
}
catch(Exception e)
{
log.error(e.getMessage());
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
e.printStackTrace(pw);
log.error("Error:" + sw.toString());
log.error("Error while executing pipeline in Redis!");
}

但我不断收到连接拒绝异常、连接关闭异常等异常。

有时我也会在行的catch block 中得到空指针异常

jedis = RedisServerConnectionDAL.getInstance();.getJedisResource();

典型的异常日志如下所示

ERROR  com.cleartrail.entityprofiling.rediscachecomponent.InMemoryDataAccessLayer -     Error:redis.clients.jedis.exceptions.JedisConnectionException: java.net.SocketException: Connection reset
at redis.clients.jedis.Protocol.sendCommand(Protocol.java:94)
at redis.clients.jedis.Protocol.sendCommand(Protocol.java:74)
at redis.clients.jedis.Connection.sendCommand(Connection.java:78)
at redis.clients.jedis.BinaryClient.hexists(BinaryClient.java:257)
at redis.clients.jedis.Client.hexists(Client.java:174)
at redis.clients.jedis.Jedis.hexists(Jedis.java:705)
at redis.clients.jedis.ShardedJedis.hexists(ShardedJedis.java:213)
at com.cleartrail.entityprofiling.rediscachecomponent.InMemoryDataAccessLayer.checkForNewEntity(InMemoryDataAccessLayer.java:339)
at com.cleartrail.entityprofiling.rediscachecomponent.InMemoryDataAccessLayer.writeInMemoryData(InMemoryDataAccessLayer.java:215)
at com.cleartrail.entityprofiling.rediscachecomponent.InMemoryDataAccessLayer.run(InMemoryDataAccessLayer.java:715)
at java.lang.Thread.run(Thread.java:745)
Caused by: java.net.SocketException: Connection reset
at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:113)
at java.net.SocketOutputStream.write(SocketOutputStream.java:153)
at redis.clients.util.RedisOutputStream.flushBuffer(RedisOutputStream.java:31)
at redis.clients.util.RedisOutputStream.writeIntCrLf(RedisOutputStream.java:186)
at redis.clients.jedis.Protocol.sendCommand(Protocol.java:81)
... 10 more

我知道我没有以正确的方式使用连接池。请建议正确的方法。此外,我使用的 jedis 是多线程环境,其中两个线程将调用 RedisServerConnectionDAL.getInstance().getJedisResource() 方法并与 Redis 交互。 Jedis 线程安全吗?

最佳答案

Jedis 实例不是线程安全的,但您可以使用 JedisPool 为每个线程获取连接并确保您从池中获得有效连接。

lettuce client是线程安全的,并为您管理自动重新连接。由于重新连接/连接重置,您不会在代码中看到任何异常。生菜也适用于 Redis Sentinel。

关于java - Redis中不同的连接异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32141933/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com