Redis连接在版本3.9.4上丢失



根据版本x文档将vertx-redis-client升级到版本3.9.4

需要更新连接代码以符合更新的版本。代码基于上面文档中的示例,如下所示:

Redis.createClient(vertx, redisOptions).connect(onConnect -> {
if (onConnect.succeeded()) {
RedisConnection client = onConnect.result();
RedisAPI redis = RedisAPI.api(client);
vertx.getOrCreateContext().put("redis", redis);
}
});

但一个小时后(或多或少(,我的连接丢失,错误堆栈跟踪如下:

io.vertx.redis.client.impl.ConnectionManager lambda$static$0 - Unhandled Error
java.nio.channels.ClosedChannelException 
at io.netty.channel.AbstractChannel$AbstractUnsafe.newClosedChannelException(AbstractChannel.java:957)
at io.netty.channel.AbstractChannel$AbstractUnsafe.write(AbstractChannel.java:865) 
at io.netty.channel.DefaultChannelPipeline$HeadContext.write(DefaultChannelPipeline.java:1367) 
at io.netty.channel.AbstractChannelHandlerContext.invokeWrite0(AbstractChannelHandlerContext.java:717) 
at io.netty.channel.AbstractChannelHandlerContext.invokeWriteAndFlush(AbstractChannelHandlerContext.java:764) 
at io.netty.channel.AbstractChannelHandlerContext.write(AbstractChannelHandlerContext.java:790) 
at io.netty.channel.AbstractChannelHandlerContext.writeAndFlush(AbstractChannelHandlerContext.java:758) 
at io.vertx.core.net.impl.ConnectionBase.write(ConnectionBase.java:124) 
at io.vertx.core.net.impl.ConnectionBase.writeToChannel(ConnectionBase.java:205) 
at io.vertx.core.net.impl.NetSocketImpl.writeMessage(NetSocketImpl.java:130) 
at io.vertx.core.net.impl.NetSocketImpl.write(NetSocketImpl.java:174) 
at io.vertx.core.net.impl.NetSocketImpl.write(NetSocketImpl.java:168) 
at io.vertx.redis.client.impl.RedisConnectionImpl.lambda$send$1(RedisConnectionImpl.java:136) 
at io.vertx.core.impl.ContextImpl.executeTask(ContextImpl.java:366) 
at io.vertx.core.impl.EventLoopContext.lambda$executeAsync$0(EventLoopContext.java:38) 
at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:164) 
at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:472) 
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:497) 
at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:989) 
at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) 
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30) 
at java.lang.Thread.run(Thread.java:748)

有人知道为什么会发生这种事吗?或者知道如何解决这个问题吗?

如果您的连接长时间空闲,Redis服务器可能会关闭连接。有几种方法可以解决这个问题。类似的内容在本期中有解释

  1. 添加固定的周期性伪命令(PING(,这样连接就不会关闭。

    Redis.createClient(vertx, new RedisOptions()).connect(onConnect -> {
    if (onConnect.succeeded()) {
    RedisConnection client = onConnect.result();
    RedisAPI redis = RedisAPI.api(client);
    vertx.getOrCreateContext().put("redis", redis);
    vertx.setPeriodic(30 * 1000, handler -> {
    redis.ping(new ArrayList<>(), result -> {
    if (result.failed()) {
    System.out.println("Error " + result.cause().getMessage());
    }
    });
    });
    }
    });
    
  2. 添加将获得和替换连接的定期任务。

    final AtomicReference<RedisConnection> vertxConnection = new AtomicReference<>();
    private void refreshConnection(Redis client, RedisConnection fallback) {
    // get a connection
    client.connect()
    .onFailure(err -> {
    // maybe log, don't change the current connection
    System.out.println("connect failed: " + err.getMessage());
    vertx.setTimer(5000L, t -> refreshConnection(client, fallback));
    })
    .onSuccess(conn -> {
    // swap old with new
    System.out.println("connect swapped: " + (conn != null ? conn.hashCode() : null));
    final RedisConnection old = vertxConnection.getAndSet(conn);
    vertx.setTimer(5000L, t -> refreshConnection(client, old));
    // the fallback isn't needed anymore
    if (fallback != null) {
    fallback.close();
    }
    });
    }
    // create client
    Redis client = Redis.createClient(vertx, redisOptions);
    // get a connection
    refreshConnection(client, null);
    
  3. 当这种情况发生时,添加异常处理程序来刷新连接,在官方文档中可以找到很好的例子:https://vertx.io/docs/vertx-redis-client/java/#_implementing_reconnect_on_error

相关内容

  • 没有找到相关文章

最新更新