【Exception】Address already in use: no further information: localhost/127.0.0.1:6379

Talk is cheap, show me the code.

环境 | Environment

kversion
OSwindows 10
jdk1.8
maven3.6.0
spring boot2.3.4.RELEASE
redis5.0.10

背景 | Background

我在测试 redis stream 时,需要对比 消费消息后使用xdel删除消息 和 消费消息后不使用xdel删除消息。

这个对比实验的目的是为了研究,不使用xdel去删除已消费的消息,是否会占用更多的 redis 内存。

实验方案是:向 redis stream 中推送 50000 条消息, 对比消费结束后的内存占用情况。

但是在消费数据过程中,大概消费了44000多条数据时,发生了异常:org.springframework.data.redis.RedisConnectionFailureException: Unable to connect to Redis; nested exception is java.util.concurrent.CompletionException: io.lettuce.core.RedisConnectionException: Unable to connect to localhost:6379

复现步骤 | Reproduction steps

先一次性向 Redis stream 中生产了 50000 条数据,在消费数据过程中,大概在消费了44000多条数据时,发生了异常。

生产消息

@RestController
@RequestMapping("/redis/stream")
public class RedisStreamController {

    @Autowired
    private RedisTemplate redisTemplate;

    @GetMapping("/push-data")
    public String pushData() {
        for (int i = 0; i < 5_0000; i++) {
            Map<String, String> map = new HashMap<>();
            map.put("k", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss:SSS").format(LocalDateTime.now()));
            RecordId recordId = redisTemplate.opsForStream().add("stream_test1", map);
        }
        return "Success";
    }

}

消费消息

@Slf4j
@Component
public class Stream1Listener extends AbstractAutoRetryStreamListener<String, MapRecord<String, String, String>> {

    @Override
    public void doOnMessage(MapRecord<String, String, String> message) {
        Map<String, String> msgMap = message.getValue();

        // do something

        double random = Math.random();
        if (random > 0.5) {
            log.warn("consume failure, consumer={} message={} random={}", getFullName(), message.getValue(), random);
            throw new RuntimeException("Message processing failed");
        }
        log.info("consume success, consumer={} message={}", getFullName(), message.getValue());
    }

    @Override
    public String getStream() {
        return "stream_test1";
    }

    @Override
    protected long maxRetries() {
        return 0L;
    }
}

报错日志 | Error log

Caused by: java.util.concurrent.CompletionException: io.lettuce.core.RedisConnectionException: Unable to connect to localhost:6379
    at java.base/java.util.concurrent.CompletableFuture.encodeThrowable(CompletableFuture.java:331)
    at java.base/java.util.concurrent.CompletableFuture.completeThrowable(CompletableFuture.java:346)
    at java.base/java.util.concurrent.CompletableFuture$UniApply.tryFire(CompletableFuture.java:632)
    ... 30 more
Caused by: io.lettuce.core.RedisConnectionException: Unable to connect to localhost:6379
    at io.lettuce.core.RedisConnectionException.create(RedisConnectionException.java:78)
    at io.lettuce.core.RedisConnectionException.create(RedisConnectionException.java:56)
    at io.lettuce.core.RedisClient.lambda$transformAsyncConnectionException$20(RedisClient.java:767)
    at io.lettuce.core.DefaultConnectionFuture.lambda$thenCompose$1(DefaultConnectionFuture.java:253)
    ... 22 more
Caused by: java.util.concurrent.CompletionException: io.netty.channel.AbstractChannel$AnnotatedSocketException: Address already in use: no further information: localhost/127.0.0.1:6379
    at java.base/java.util.concurrent.CompletableFuture.encodeThrowable(CompletableFuture.java:331)
    at java.base/java.util.concurrent.CompletableFuture.completeThrowable(CompletableFuture.java:346)
    at java.base/java.util.concurrent.CompletableFuture$UniApply.tryFire(CompletableFuture.java:632)
    ... 20 more
Caused by: io.netty.channel.AbstractChannel$AnnotatedSocketException: Address already in use: no further information: localhost/127.0.0.1:6379
Caused by: java.net.BindException: Address already in use: no further information
    at java.base/sun.nio.ch.SocketChannelImpl.checkConnect(Native Method)
    at java.base/sun.nio.ch.SocketChannelImpl.finishConnect(SocketChannelImpl.java:779)
    at io.netty.channel.socket.nio.NioSocketChannel.doFinishConnect(NioSocketChannel.java:330)
    at io.netty.channel.nio.AbstractNioChannel$AbstractNioUnsafe.finishConnect(AbstractNioChannel.java:334)
    at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:707)
    at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:655)
    at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:581)
    at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:493)
    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.base/java.lang.Thread.run(Thread.java:834)

原因分析 | Analysis

  1. 通过后面的参考文章获得了解决思路。

解决方案 | Solution

打开 Widnows 命令行窗口( Run as administor )执行以下命令:

netsh int ipv4 set dynamicport tcp start=20000 num=90000

这个命令是Windows的Netsh工具命令,用于配置网络接口。具体来说,netsh int ipv4 set dynamicport tcp start=20000 num=90000 这个命令是设置TCP协议的动态端口范围。其中,'start=20000’表示动态端口的起始值,而’num=90000’表示端口范围的大小,即从20000开始,共有90000个连续的端口可供动态分配。

参考 | References

CSDN - 并发测试异常[Address already in use: no futher infomation]

cnpython - java Spring Redis流消费者停止消费消息(地址已在使用中)

知乎 - 【Netty】网络连接数上限造成的问题

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值