sockettimeout在httpcomponent中的实现

探讨了HTTP组件中客户端和服务端如何实现连接池及超时处理机制,特别是在基于连接池的情况下,如何确保HTTP请求能够正确地判断socket超时。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

client--->server

但是httpcomponent是基于连接池的,那么连接是永远不关闭的话,如何做到判断http请求的socketimout的呢?

代码基于4.4.6

clinet端实际是使用AbstractIOReactor类

          for (;;) {

                final int readyCount;
                try {
                    readyCount = this.selector.select(this.selectTimeout);
                } catch (final InterruptedIOException ex) {
                    throw ex;
                } catch (final IOException ex) {
                    throw new IOReactorException("Unexpected selector failure", ex);
                }

                if (this.status == IOReactorStatus.SHUT_DOWN) {
                    // Hard shut down. Exit select loop immediately
                    break;
                }

                if (this.status == IOReactorStatus.SHUTTING_DOWN) {
                    // Graceful shutdown in process
                    // Try to close things out nicely
                    closeSessions();
                    closeNewChannels();
                }

                // Process selected I/O events
                if (readyCount > 0) {
                    processEvents(this.selector.selectedKeys());
                }

                // Validate active channels
                validate(this.selector.keys());

                // Process closed sessions
                processClosedSessions();

                // If active process new channels
                if (this.status == IOReactorStatus.ACTIVE) {
                    processNewChannels();
                }

                // Exit select loop if graceful shutdown has been completed
                if (this.status.compareTo(IOReactorStatus.ACTIVE) > 0
                        && this.sessions.isEmpty()) {
                    break;
                }

                if (this.interestOpsQueueing) {
                    // process all pending interestOps() operations
                    processPendingInterestOps();
                }

            }

 validate(this.selector.keys());的时候会判断连接是否已经socketimeout。

    protected void timeoutCheck(final SelectionKey key, final long now) {
        final IOSessionImpl session = (IOSessionImpl) key.attachment();
        if (session != null) {
            final int timeout = session.getSocketTimeout();
            if (timeout > 0) {
                if (session.getLastAccessTime() + timeout < now) {
                    sessionTimedOut(session);
                }
            }
        }
    }

但是这里有个问题,就是这里获取到session.getSocketTimeout(),如果这个连接长时间都没有请求,岂不是这里进行连接的判断

的时候就超时了,不就抛出异常了?

这里其实是在这里:

在cpool归还连接的时候,会将sockettimeout置为0.则不再判断连接的时效性。直到下次新的连接来了,则再设置sockettimeout,再进行超时的判断。

2. 而server端的httpcomponent,则每次真的在判断timeout,通过(代码基于。4和5的DefaultConnectingIOReactor类

都完全不一样了)

InternalChannel

    final boolean checkTimeout(final long currentTime) {
        final int timeout = getTimeout();
        if (timeout > 0) {
            final long deadline = getLastReadTime() + timeout;
            if (currentTime > deadline) {
                try {
                    onTimeout();
                } catch (final CancelledKeyException ex) {
                    close(CloseMode.GRACEFUL);
                } catch (final Exception ex) {
                    onException(ex);
                    close(CloseMode.IMMEDIATE);
                }
                return false;
            }
        }
        return true;
    }

这里的getTimeout,也是从InternalDataChannel

@Override
    int getTimeout() {
        return ioSession.getSocketTimeout();
    }

中获取,但是这里真的不会重新设置iosessionimpl的socktTimeout。因此,server端设置的是多少就是多少。

客户端使用的是SingleCoreIOReactor,也不会重新设置socktTimeout。如果设置,也应该是和4.6一样,由前端cpool等

线程池进行操作。因此,这猜测是http请求完毕以后,直接关闭这个链接,

没有让这个SingleCoreIOReactor继续循环的可能性,因为继续循环将造成超时。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值