-> new Http11NioProtocol()
public Http11NioProtocol() {
super(new NioEndpoint());
}
=================================================================================
org.apache.tomcat.util.net.NioEndpoint
-> new NioEndPoint()
创建之后如何被启动?见springboot启动tomcat方式
=============================================================================
启动之后
NioEndpoint执行bind()方法,
一些初始化,绑定端口
@Override
public void bind() throws Exception {
initServerSocket();
setStopLatch(new CountDownLatch(1));
// Initialize SSL if needed
initialiseSsl();
selectorPool.open(getName());
}
//socket相关 initServerSocket()具体如下
// Separated out to make it easier for folks that extend NioEndpoint to
// implement custom [server]sockets
protected void initServerSocket() throws Exception {
//…
//根据平台不同,反回具体底层类对象(windows,linux,unix)
serverSock = ServerSocketChannel.open();
socketProperties.setProperties(serverSock.socket());
//绑定地址和端口号
InetSocketAddress addr = new InetSocketAddress(getAddress(), getPortWithOffset());
serverSock.socket().bind(addr,getAcceptCount());
//…
}
NioEndpoint初始化之后,调用start()执行startInternal()
代码如下
// Create worker collection
if (getExecutor() == null) {
//创建线程池
createExecutor();
}
initializeConnectionLatch();
// Start poller thread
// 创建客户端队列(客户端过来的请求)
poller = new Poller();
Thread pollerThread = new Thread(poller, getName() + “-ClientPoller”);
pollerThread.setPriority(threadPriority);
pollerThread.setDaemon(true);
pollerThread.start();
//创建接收远程请求线程
startAcceptorThread();
========================================================================
-> createExecutor() 用于处理用户请求
指定 备用线程,对大线程数,队列类型,超时时间,和线程工厂
public void createExecutor() {
internalExecutor = true;
TaskQueue taskqueue = new TaskQueue();
TaskThreadFactory tf = new TaskThreadFactory(getName() + “-exec-”, daemon, getThreadPriority());
executor = new ThreadPoolExecutor(getMinSpareThreads(), getMaxThreads(), 60, TimeUnit.SECONDS,taskqueue, tf);
taskqueue.setParent( (ThreadPoolExecutor) executor);
}
==========================================================================
poller = new Poller();
Thread pollerThread = new Thread(poller, getName() + “-ClientPoller”);
pollerThread.setPriority(threadPriority);
pollerThread.setDaemon(true);
pollerThread.start();
创建Acceptor线程
protected void startAcceptorThread() {
acceptor = new Acceptor<>(this);
String threadName = getName() + “-Acceptor”;
acceptor.setThreadName(threadName);
Thread t = new Thread(acceptor, threadName);
t.setPriority(getAcceptorThreadPriority());
t.setDaemon(getDaemon());
t.start();
}
=============================================================================
=========================================================================
org.apache.tomcat.util.net.Acceptor
Acceptor 负责循环等待远程请求,将请求以socket形式携带信息,调用setSocketOptions()将socket包装配置为socketWrapper,
setSocketOptions: 对socket包装处理配置,使用poller对象注册到队列,让poller线程做后续的处理
Acceptor 类的run方法:
public void run() {
int errorDelay = 0;
//…以下省略部分代码
try {
// Loop until we receive a shutdown command
// 一直循环等待远程请求
while (!stopCalled) {
// Accept the next incoming connection from the server socket
// 1 接收请求
socket = endpoint.serverSocketAccept();
// setSocketOptions() will hand the socket off to
// 2 处理请求,setSocketOptions() 内部调用poller 将新请求任务放入队列
if (!endpoint.setSocketOptions(socket)) {
endpoint.closeSocket(socket);
}
}
} finally {
stopLatch.countDown();
}
state = AcceptorState.ENDED;
}
=======================================================================
org.apache.tomcat.util.net.NioEndpoint.Poller
Poller负责接收包装后的socket请求,放入队列,
并在run方法中循环去poll()请求任务,将与流读写有关的组件IOChannel Selector socketWrapper 绑定关联
再通过selector获取selectionKeys
迭代循环获取对应的socket,提交任务(线程),线程读写处理socketWrapper等后续操作
public void run() {
// Loop until destroy() is called
while (true) {
// poller队列任务处理 将IOChannel Selector socketWrapper 关联
hasEvents = events();
//…省略
Iterator iterator =
keyCount > 0 ? selector.selectedKeys().iterator() : null;
// Walk through the collection of ready keys and dispatch
// 非阻塞io api 任务处理
while (iterator != null && iterator.hasNext()) {
SelectionKey sk = iterator.next();
iterator.remove();
NioSocketWrapper socketWrapper = (NioSocketWrapper) sk.attachment();
// Attachment may be null if another thread has called
// cancelledKey()
if (socketWrapper != null) {
// 如果有等待处理的任务,则处理
processKey(sk, socketWrapper);
//processKey内部会调用processSocket方法,最终用线程池提交任务
}
}
// Process timeouts
timeout(keyCount,hasEvents);
}
getStopLatch().countDown();
}
==================================================================
events队列
private final SynchronizedQueue events =
new SynchronizedQueue<>(); //事件队列(socket请求)
//注册请求到队列
public void rigister(final NioSocketWrapper socketWrapper)
{
event = new PollerEvent(socketWrapper, OP_REGISTER);
addEvent(event);
}
private void addEvent(PollerEvent event) {
events.offer(event);
if (wakeupCounter.incrementAndGet() == 0) {
selector.wakeup();
}
}
events()绑定及后面的 processSocket()最终提交实际处理任务到线程
/**
-
Processes events in the event queue of the Poller.
-
@return
true
if some events were processed, -
false
if queue was empty
*/
public boolean events() {
boolean result = false;
PollerEvent pe = null;
for (int i = 0, size = events.size(); i < size && (pe = events.poll()) != null; i++ ) {
result = true;
NioSocketWrapper socketWrapper = pe.getSocketWrapper();
SocketChannel sc = socketWrapper.getSocket().getIOChannel();
int interestOps = pe.getInterestOps();
if (sc == null) {
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)

最后总结
搞定算法,面试字节再不怕,有需要文章中分享的这些二叉树、链表、字符串、栈和队列等等各大面试高频知识点及解析
最后再分享一份终极手撕架构的大礼包(学习笔记):分布式+微服务+开源框架+性能优化
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
5%以上Java开发知识点,真正体系化!**
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)

最后总结
搞定算法,面试字节再不怕,有需要文章中分享的这些二叉树、链表、字符串、栈和队列等等各大面试高频知识点及解析
最后再分享一份终极手撕架构的大礼包(学习笔记):分布式+微服务+开源框架+性能优化
[外链图片转存中…(img-OtZRbkhz-1713640543459)]
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!