Netty FixedChannelPool超时获取channel导致占用资源问题

博客详细介绍了Netty的FixedChannelPool在超时获取channel时导致资源占用的问题,以及如何通过设置AcquireTimeoutAction为FAIL来解决这个问题。修复后,当获取连接超时时,能够抛出异常并避免资源浪费。测试代码展示了修复前后的不同效果。

Netty FixedChannelPool超时获取channel导致占用资源问题

背景

超时获取channel,虽然我们的代码里超时了,没拿到channel返回了,但netty中有一个线程仍然在获取channel,由于我们的程序直接返回了,没有释放channel,导致连接池里的channel可用数量下降!

更多问题情况参考这篇文章:https://cloud.tencent.com/developer/article/1704886

获取连接任务超时后,此时还有一个异步线程在执行着从连接池获取连接的操作,这个连接取出后由于不能再正常返回给业务线程了,因为此时业务线程因为获取连接超时异常了;又因为正常情况下,释放连接的操作由业务线程来触发完成。当获取连接超时的任务从连接池取完所有可用连接后,此时服务就不可用了。

问题解决

实现待获取连接超时任务策略,并设置acquireTimeoutMillis参数。但文章中给出的解决不适应本系统,略微修改解决。
观察FixedChannelPool源码:

 public FixedChannelPool(Bootstrap bootstrap, ChannelPoolHandler handler, int maxConnections) {
   
   
        this(bootstrap, handler, maxConnections, Integer.MAX_VALUE);
    }

    public FixedChannelPool(Bootstrap bootstrap, ChannelPoolHandler handler, int maxConnections, int maxPendingAcquires) {
   
   
        this(bootstrap, handler, ChannelHealthChecker.ACTIVE, (AcquireTimeoutAction)null, -1L, maxConnections, maxPendingAcquires);
    }

    public FixedChannelPool(Bootstrap bootstrap, ChannelPoolHandler handler, ChannelHealthChecker healthCheck, AcquireTimeoutAction action, long acquireTimeoutMillis, int maxConnections, int maxPendingAcquires) {
   
   
        this(bootstrap, handler, healthCheck, action, acquireTimeoutMillis, maxConnections, maxPendingAcquires, true);
    }

    public FixedChannelPool(Bootstrap bootstrap, ChannelPoolHandler handler, ChannelHealthChecker healthCheck, AcquireTimeoutAction action, long acquireTimeoutMillis, int maxConnections, int maxPendingAcquires, boolean releaseHealthCheck) {
   
   
        this(bootstrap, handler, healthCheck, action, acquireTimeoutMillis, maxConnections, maxPendingAcquires, releaseHealthCheck, true);
    }

    public FixedChannelPool(Bootstrap bootstrap, ChannelPoolHandler handler, ChannelHealthChecker healthCheck, AcquireTimeoutAction action, long acquireTimeoutMillis, int maxConnections, int maxPendingAcquires, boolean releaseHealthCheck, boolean lastRecentUsed) {
   
   
        super(bootstrap, handler, healthCheck, releaseHealthCheck, lastRecentUsed);
        this.pendingAcquireQueue = new ArrayDeque();
        this.acquiredChannelCount = new AtomicInteger()
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值