java - 将 Lettuce 与 RedisTemplate 一起使用会引发异常
问题描述
我试图弄清楚为什么生菜在我进行性能测试时会给我带来这么多问题,并将其与 Jedis 进行比较。
我正在使用 spring-data-redis 1.8.11.RELEASE 并为接口创建自定义代理 bean,以通过 RedisTemplate 访问 redis。Redis 在 AWS 中运行,我使用 AWS 提供的集群配置端点作为具有 3 个主节点和 3 个从节点的节点。在性能测试期间没有什么特别的事情发生。我只是调用一个使用 RedisTemplate 从 redis 读取值的服务。
使用 JedisConnectionFactory 时,测试总是无一例外地通过,但是当我切换到 LettuceConnnectionFactory 时,我无法完成任何测试,因为通道初始化总是超时。我将超时时间增加到 30 秒,并像在遇到线程中断异常之前一样调整了关闭计时器。但是,即使是 30 多岁,它仍然会超时。我尝试过使用共享本机连接并且没有和许多不同的超时值,它们都会导致相同的问题。
连接工厂 bean 的代码:
@Bean
public RedisConnectionFactory lettuceConnectionFactory() {
RedisClusterConfiguration clusterConfig = new RedisClusterConfiguration(Arrays.asList(cacheProps.nodes));
clusterConfig.setMaxRedirects(6);
LettuceConnectionFactory factory = new LettuceConnectionFactory(clusterConfig);
factory.setTimeout(30000);
factory.setShutdownTimeout(20000);
return factory;
}
我尝试调整 ClientResources 的线程数,但我仍然继续收到超时错误:
ClientResources res = DefaultClientResources.builder()
.ioThreadPoolSize(10)
.computationThreadPoolSize(10)
.build();
访问 Redis 的代码只需通过 RedisTemplate:
BoundHashOperations<Object, Object, Object> hashOps = redisTemplate.boundHashOps(request.getHashKey());
String data = (String) hashOps.get(request.getSubKey());
long timeout = request.getTtl();
try {
if (timeout != 0) {
hashOps.expire(timeout, request.getTimeUnit());
}
return mapper.readValue(data, request.getType());
} catch (Exception e) {
logger.error("Exception for hash value read.", e);
}
测试时出现异常的根本原因:
Caused by: io.netty.channel.ConnectTimeoutException: connection timed out: /x.x.x.x:6379
at io.netty.channel.nio.AbstractNioChannel$AbstractNioUnsafe$1.run(AbstractNioChannel.java:216)
at io.netty.util.concurrent.PromiseTask$RunnableAdapter.call(PromiseTask.java:38)
at io.netty.util.concurrent.ScheduledFutureTask.run(ScheduledFutureTask.java:120)
at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:408)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:402)
at io.netty.util.concurrent.SingleThreadEventExecutor$2.run(SingleThreadEventExecutor.java:140)
at io.netty.util.concurrent.DefaultThreadFactory$DefaultRunnableDecorator.run(DefaultThreadFactory.java:144)
我在这里想念什么?从我阅读的所有内容来看,每个人似乎都更喜欢生菜,但从我的测试中我看不出为什么。
解决方案
尝试连接池和管道
private GenericObjectPoolConfig getPoolConfig() {
GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig();
//All below should use the propertysources;
poolConfig.setMaxTotal(20);
poolConfig.setMaxIdle(20);
poolConfig.setMinIdle(0);
return poolConfig;
}
@Bean
@Primary
public RedisConnectionFactory redisConnectionFactory() {
DefaultLettucePool lettucePool = new DefaultLettucePool(redisHost, Integer.valueOf(redisPort).intValue(), getPoolConfig());
lettucePool.setPassword(redisPass);
lettucePool.afterPropertiesSet();
LettuceConnectionFactory clientConfig = new LettuceConnectionFactory(lettucePool);
clientConfig.afterPropertiesSet();
return clientConfig;
}
@Bean
public RedisTemplate<?, ?> redisTemplate(RedisConnectionFactory connectionFactory) {
RedisTemplate<byte[], byte[]> template = new RedisTemplate<>();
template.setConnectionFactory(connectionFactory);
return template;
}
推荐阅读
- python - 将 Cython 库正确安装为 Python 包
- python - 如何更改系列中int元素的值
- django - factory_boy:为一个相关工厂传递模型实例
- node.js - 如何使用 NPM 将发布和快照发布到 Nexus 实例?
- c# - 无法从 c# dapper 代码将日期时间作为空值插入 Nexus 数据库
- facebook - 2018 年通过网站链接打开 Facebook 应用程序的正确方法?
- python - Python。从 Worker 发送信号
- javafx - 行开始/结束到嵌套的 javafx 组/窗格
- php - 从 MySQL 设置一个数组,然后将每个值设置为变量 PHP
- ionic-framework - Ionic 3 Virtual Scroll:更改项目大小