专栏名称: ImportNew
伯乐在线旗下账号,专注Java技术分享,包括Java基础技术、进阶技能、架构设计和Java技术领域动态等。
目录
相关文章推荐
芋道源码  ·  项目终于用上了 Spring 状态机,太优雅了! ·  23 小时前  
ImportNew  ·  Java 之父怒斥:AI ... ·  3 天前  
芋道源码  ·  很严重了,大家极限搞钱吧 ·  昨天  
51好读  ›  专栏  ›  ImportNew

Tomcat 连接之 KeepAlive 逻辑分析

ImportNew  · 公众号  · Java  · 2023-08-27 10:59

正文

请到「今天看啥」查看全文


class Poller implements Runnable { public void register ( final NioChannel socket) { socket.setPoller( this ); // KeyAttachment继承了SocketWrapper KeyAttachment key = keyCache.poll(); final KeyAttachment ka = key!= null ?key: new KeyAttachment(socket); ... ... // 将MaxKeepAliveRequests关联到socket上 ka.setKeepAliveLeft(NioEndpoint. this .getMaxKeepAliveRequests()); ... ... PollerEvent r = eventCache.poll(); ... ... addEvent(r); } @Override public void run () { while ( true ) { ... ... Iterator iterator = keyCount > 0 ? selector.selectedKeys().iterator() : null ; while (iterator != null && iterator.hasNext()) { SelectionKey sk = iterator.next(); KeyAttachment attachment = (KeyAttachment)sk.attachment(); // Attachment may be null if another thread has called // cancelledKey() if (attachment == null ) { iterator.remove(); } else { attachment.access(); iterator.remove(); // 处理Socket上的事件 processKey(sk, attachment); } } ... ... } } protected boolean processKey (SelectionKey sk, KeyAttachment attachment) { ... ... if (sk.isReadable()) { if (!processSocket(channel, SocketStatus.OPEN_READ, true )) { closeSocket = true ; } } if (!closeSocket && sk.isWritable()) { if (!processSocket(channel, SocketStatus.OPEN_WRITE, true )) { closeSocket = true ; } } ... ... } public boolean processSocket (NioChannel socket, SocketStatus status, boolean dispatch) { ... ... KeyAttachment attachment = (KeyAttachment)socket.getAttachment(); ... ... SocketProcessor sc = processorCache.poll(); if ( sc == null ) sc = new SocketProcessor(socket,status); else sc.reset(socket,status); // 从Socket poller thread切换到Worker Threads pool if ( dispatch && getExecutor()!= null ) getExecutor().execute(sc); else sc.run(); ... ... } }

流程由 Socket poller thread 切换到了 Worker threads pool SocketProcessor,Worker threads pool 是用来处理业务逻辑的线程池,接下来分析 Tomcat 如何解析请求的。


解析请求


SocketProcessor 会流转到 org.apache.coyote.http11.AbstractHttp11Processor.process 中,解析请求相关逻辑如下:


public SocketState process(SocketWrapper socketWrapper) throws IOException {    ... ...    keepAlive = true;    // 如果当前处理业务的线程占总线程的比例超过disableKeepAlivePercentage(默认:75),    // 则将socket可接收的请求数设置为0    if (disableKeepAlive()) {        socketWrapper.setKeepAliveLeft(0);    }    ... ...    prepareRequest();    ... ...    if (maxKeepAliveRequests == 1) {        keepAlive = false;    } else if (maxKeepAliveRequests > 0 && socketWrapper.decrementKeepAlive() <= 0) {        // 关键逻辑,socket已接收的请求数量是否超过配置值        keepAlive = false;    }  ... ...  // 调用Servlet service方法






请到「今天看啥」查看全文