我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Tomcat处理请求的线程模型是什么

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Tomcat处理请求的线程模型是什么

小编给大家分享一下Tomcat处理请求的线程模型是什么,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!

    一、前言

    JAVA后端项目,运行在容器tomcat中,由于现在springboot的内置tomcat容器,其默认配置屏蔽了很多对tomcat的认知,但是对tomcat的学习和认识是比较重要的,所以专门查资料加深了理解,本文主要讨论在springboot集成下的tomcat9的请求过程,线程模型为NIO。

    二、tomcat结构

    Tomcat处理请求的线程模型是什么

    找了张结构图,每个模块的意思和作用就不详解了,可以搜其他文章

    三、探讨tomcat是如何处理请求

    Tomcat处理请求的线程模型是什么

    自己画了一个connector的结构

    1、初始化

    在springboot启动后,org.springframework.context.support.AbstractApplicationContext#finishRefresh,这里进去调用org.springframework.boot.web.servlet.context.WebServerStartStopLifecycle.start()方法启动TomcatWebServer,初始化tomcat。

    Tomcat处理请求的线程模型是什么

    Tomcat处理请求的线程模型是什么

    通过这样的调用链到达org.apache.tomcat.util.net.NioEndpoint#startInternal(),进行初始化Endpoint中的AcceptorPoller,这两者都实现了Runnable接口,初始化后就通过线程start启动了。

    2、如何处理客户端请求

    Acceptor: 接收器,作用是接受scoket网络请求,并调用setSocketOptions()封装成为NioSocketWrapper,并注册到Poller的events中。注意查看run方法org.apache.tomcat.util.net.Acceptor#run

     @Override    public void run() {        int errorDelay = 0;        try {            // Loop until we receive a shutdown command            while (!stopCalled) {                // Loop if endpoint is paused                while (endpoint.isPaused() && !stopCalled) {                    state = AcceptorState.PAUSED;                    try {                        Thread.sleep(50);                    } catch (InterruptedException e) {                        // Ignore                    }                }                if (stopCalled) {                    break;                }                state = AcceptorState.RUNNING;                try {                    //if we have reached max connections, wait                    endpoint.countUpOrAwaitConnection();                    // Endpoint might have been paused while waiting for latch                    // If that is the case, don't accept new connections                    if (endpoint.isPaused()) {                        continue;                    }                    U socket = null;                    try {                        // 等待下一个请求进来                        socket = endpoint.serverSocketAccept();                    } catch (Exception ioe) {                        // We didn't get a socket                        endpoint.countDownConnection();                        if (endpoint.isRunning()) {                            // Introduce delay if necessary                            errorDelay = handleExceptionWithDelay(errorDelay);                            // re-throw                            throw ioe;                        } else {                            break;                        }                    }                    // Successful accept, reset the error delay                    errorDelay = 0;                    // Configure the socket                    if (!stopCalled && !endpoint.isPaused()) {                        // 注册socket到Poller,生成PollerEvent事件                        if (!endpoint.setSocketOptions(socket)) {                            endpoint.closeSocket(socket);                        }                    } else {                        endpoint.destroySocket(socket);                    }                } catch (Throwable t) {                    ExceptionUtils.handleThrowable(t);                    String msg = sm.getString("endpoint.accept.fail");                    // APR specific.                    // Could push this down but not sure it is worth the trouble.                    if (t instanceof Error) {                        Error e = (Error) t;                        if (e.getError() == 233) {                            // Not an error on HP-UX so log as a warning                            // so it can be filtered out on that platform                            // See bug 50273                            log.warn(msg, t);                        } else {                            log.error(msg, t);                        }                    } else {                            log.error(msg, t);                    }                }            }        } finally {            stopLatch.countDown();        }        state = AcceptorState.ENDED;    }

    Poller:轮询器,轮询是否有事件达到,有请求事件到达后,以NIO的处理方式,查询Selector取出所有请求,遍历每个请求的需求,分配给Executor线程池执行。查看org.apache.tomcat.util.net.NioEndpoint.Poller#run()

     public void run() {            // Loop until destroy() is called            while (true) {                boolean hasEvents = false;                try {                    if (!close) {                        hasEvents = events();                        if (wakeupCounter.getAndSet(-1) > 0) {                            // If we are here, means we have other stuff to do                            // Do a non blocking select                            keyCount = selector.selectNow();                        } else {                            keyCount = selector.select(selectorTimeout);                        }                        wakeupCounter.set(0);                    }                    if (close) {                        events();                        timeout(0, false);                        try {                            selector.close();                        } catch (IOException ioe) {                            log.error(sm.getString("endpoint.nio.selectorCloseFail"), ioe);                        }                        break;                    }                    // Either we timed out or we woke up, process events first                    if (keyCount == 0) {                        hasEvents = (hasEvents | events());                    }                } catch (Throwable x) {                    ExceptionUtils.handleThrowable(x);                    log.error(sm.getString("endpoint.nio.selectorLoopError"), x);                    continue;                }//查询selector取出所有请求                Iterator<SelectionKey> iterator =                    keyCount > 0 ? selector.selectedKeys().iterator() : null;                // Walk through the collection of ready keys and dispatch                // any active event.                while (iterator != null && iterator.hasNext()) {                    SelectionKey sk = iterator.next();                    iterator.remove();                    NioSocketWrapper socketWrapper = (NioSocketWrapper) sk.attachment();                    //处理请求key                    if (socketWrapper != null) {                        processKey(sk, socketWrapper);                    }                }                // Process timeouts                timeout(keyCount,hasEvents);            }            getStopLatch().countDown();        }

    请求过程大致如下图:

    Tomcat处理请求的线程模型是什么

    以上是“Tomcat处理请求的线程模型是什么”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注编程网行业资讯频道!

    免责声明:

    ① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

    ② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

    Tomcat处理请求的线程模型是什么

    下载Word文档到电脑,方便收藏和打印~

    下载Word文档

    猜你喜欢

    Tomcat处理请求的线程模型是什么

    小编给大家分享一下Tomcat处理请求的线程模型是什么,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!一、前言JAVA后端项目,运行在容器tomcat中,由于现在s
    2023-06-29

    springmvc处理请求的流程是什么

    Spring MVC处理请求的流程如下:1. 客户端发送请求到DispatcherServlet,DispatcherServlet是前端控制器。2. DispatcherServlet根据请求的URL调用HandlerMapping,Ha
    2023-08-18

    ASP.NET处理HTTP请求的流程是什么

    这篇文章主要介绍“ASP.NET处理HTTP请求的流程是什么”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“ASP.NET处理HTTP请求的流程是什么”文章能帮助大家解决问题。一、ASP.NET处理管
    2023-06-30

    Redis线程模型的原理是什么

    这篇文章主要介绍“Redis线程模型的原理是什么”,在日常操作中,相信很多人在Redis线程模型的原理是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Redis线程模型的原理是什么”的疑惑有所帮助!接下来
    2023-06-21

    Redis线程模型是什么

    这篇文章主要讲解了“Redis线程模型是什么”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Redis线程模型是什么”吧! Redis它是一个单线程的,这一点需要去注意的。首先我们呢会有一个客
    2023-06-30

    浏览器请求流程和PHP对请求的处理方法是什么

    这篇“浏览器请求流程和PHP对请求的处理方法是什么”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“浏览器请求流程和PHP对请求
    2023-07-05

    SpringBoot监控Tomcat活动线程数来判断是否完成请求处理方式

    这篇文章主要介绍了SpringBoot监控Tomcat活动线程数来判断是否完成请求处理方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-02-28

    SpringBoot怎么监控Tomcat活动线程数来判断是否完成请求处理方式

    这篇文章主要讲解了“SpringBoot怎么监控Tomcat活动线程数来判断是否完成请求处理方式”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“SpringBoot怎么监控Tomcat活动线程
    2023-07-05

    php处理post请求的方法是什么

    在PHP中处理POST请求的方法是使用$_POST超全局变量来获取POST请求的数据。$_POST是一个关联数组,它包含了所有的POST请求参数和对应的值。以下是处理POST请求的示例代码:```php// 检查请求是否是POST请求if
    2023-10-10

    Android中的单线程模型是什么

    这篇文章给大家介绍Android中的单线程模型是什么,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。Android 单线程模型详解及实例当第一次启动一个Android程序时,Android会自动创建一个称为“main”主
    2023-05-31

    django异步请求处理的方法是什么

    Django中的异步请求处理可以通过以下几种方法实现:1. 使用Django的内置异步任务处理机制:Django提供了一个名为`asyncio`的模块,用于处理异步任务。可以使用`async`和`await`关键字来定义异步函数,然后将其作
    2023-09-26

    Nginx请求处理流程是怎样的

    这篇文章主要介绍“Nginx请求处理流程是怎样的”,在日常操作中,相信很多人在Nginx请求处理流程是怎样的问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Nginx请求处理流程是怎样的”的疑惑有所帮助!接下来
    2023-06-04

    postman模拟post请求的四种请求体分别是什么

    今天就跟大家聊聊有关postman模拟post请求的四种请求体分别是什么,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。1.application/x-www-form-urlenco
    2023-06-26

    ASP.NET的请求处理过程是怎样的

    这篇文章主要介绍“ASP.NET的请求处理过程是怎样的”,在日常操作中,相信很多人在ASP.NET的请求处理过程是怎样的问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”ASP.NET的请求处理过程是怎样的”的疑
    2023-06-17

    java处理高并发请求的方法是什么

    Java处理高并发请求的方法有很多种,以下是一些常用的方法:使用线程池:可以使用Java中的线程池技术来管理并发请求。通过创建固定大小的线程池,可以控制同时处理的请求数量,避免系统资源被过多的请求耗尽。使用消息队列:可以使用消息队列来缓冲请
    2023-10-25

    java中的事件处理模型是什么

    java中的事件处理模型是什么?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。Java有哪些集合类Java中的集合主要分为四类:1、List列表:有序的,可重复的;2、Queue
    2023-06-14

    编程热搜

    • Python 学习之路 - Python
      一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
      Python 学习之路 - Python
    • chatgpt的中文全称是什么
      chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
      chatgpt的中文全称是什么
    • C/C++中extern函数使用详解
    • C/C++可变参数的使用
      可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
      C/C++可变参数的使用
    • css样式文件该放在哪里
    • php中数组下标必须是连续的吗
    • Python 3 教程
      Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
      Python 3 教程
    • Python pip包管理
      一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
      Python pip包管理
    • ubuntu如何重新编译内核
    • 改善Java代码之慎用java动态编译

    目录