深入拆解Tomcat & Jetty
李号双
eBay技术主管
立即订阅
6067 人已学习
课程目录
已完结 44 讲
0/4登录后,你可以任选4讲全文学习。
开篇词 (1讲)
开篇词 | Java程序员如何快速成长?
免费
模块一 必备基础 (4讲)
01 | Web容器学习路径
02 | HTTP协议必知必会
03 | 你应该知道的Servlet规范和Servlet容器
04 | 实战:纯手工打造和运行一个Servlet
模块二 整体架构 (9讲)
05 | Tomcat系统架构(上): 连接器是如何设计的?
06 | Tomcat系统架构(下):聊聊多层容器的设计
07 | Tomcat如何实现一键式启停?
08 | Tomcat的“高层们”都负责做什么?
09 | 比较:Jetty架构特点之Connector组件
10 | 比较:Jetty架构特点之Handler组件
11 | 总结:从Tomcat和Jetty中提炼组件化设计规范
12 | 实战:优化并提高Tomcat启动速度
13 | 热点问题答疑(1):如何学习源码?
模块三 连接器 (9讲)
14 | NioEndpoint组件:Tomcat如何实现非阻塞I/O?
15 | Nio2Endpoint组件:Tomcat如何实现异步I/O?
16 | AprEndpoint组件:Tomcat APR提高I/O性能的秘密
17 | Executor组件:Tomcat如何扩展Java线程池?
18 | 新特性:Tomcat如何支持WebSocket?
19 | 比较:Jetty的线程策略EatWhatYouKill
20 | 总结:Tomcat和Jetty中的对象池技术
21 | 总结:Tomcat和Jetty的高性能、高并发之道
22 | 热点问题答疑(2):内核如何阻塞与唤醒进程?
模块四 容器 (8讲)
23 | Host容器:Tomcat如何实现热部署和热加载?
24 | Context容器(上):Tomcat如何打破双亲委托机制?
25 | Context容器(中):Tomcat如何隔离Web应用?
26 | Context容器(下):Tomcat如何实现Servlet规范?
27 | 新特性:Tomcat如何支持异步Servlet?
28 | 新特性:Spring Boot如何使用内嵌式的Tomcat和Jetty?
29 | 比较:Jetty如何实现具有上下文信息的责任链?
30 | 热点问题答疑(3):Spring框架中的设计模式
模块五 通用组件 (4讲)
31 | Logger组件:Tomcat的日志框架及实战
32 | Manager组件:Tomcat的Session管理机制解析
33 | Cluster组件:Tomcat的集群通信原理
特别放送 | 如何持续保持对学习的兴趣?
模块六 性能优化 (8讲)
34 | JVM GC原理及调优的基本思路
35 | 如何监控Tomcat的性能?
36 | Tomcat I/O和线程池的并发调优
37 | Tomcat内存溢出的原因分析及调优
38 | Tomcat拒绝连接原因分析及网络优化
39 | Tomcat进程占用CPU过高怎么办?
40 | 谈谈Jetty性能调优的思路
41 | 热点问题答疑(4): Tomcat和Jetty有哪些不同?
结束语 (1讲)
结束语 | 静下心来,品味经典
深入拆解Tomcat & Jetty
登录|注册

19 | 比较:Jetty的线程策略EatWhatYouKill

李号双 2019-06-22
我在前面的专栏里介绍了 Jetty 的总体架构设计,简单回顾一下,Jetty 总体上是由一系列 Connector、一系列 Handler 和一个 ThreadPool 组成,它们的关系如下图所示:
相比较 Tomcat 的连接器,Jetty 的 Connector 在设计上有自己的特点。Jetty 的 Connector 支持 NIO 通信模型,我们知道 NIO 模型中的主角就是 Selector,Jetty 在 Java 原生 Selector 的基础上封装了自己的 Selector,叫作 ManagedSelector。ManagedSelector 在线程策略方面做了大胆尝试,将 I/O 事件的侦测和处理放到同一个线程来处理,充分利用了 CPU 缓存并减少了线程上下文切换的开销。
具体的数字是,根据 Jetty 的官方测试,这种名为“EatWhatYouKill”的线程策略将吞吐量提高了 8 倍。你一定很好奇它是如何实现的吧,今天我们就来看一看这背后的原理是什么。

Selector 编程的一般思路

常规的 NIO 编程思路是,将 I/O 事件的侦测和请求的处理分别用不同的线程处理。具体过程是:
启动一个线程,在一个死循环里不断地调用 select 方法,检测 Channel 的 I/O 状态,一旦 I/O 事件达到,比如数据就绪,就把该 I/O 事件以及一些数据包装成一个 Runnable,将 Runnable 放到新线程中去处理。
取消
完成
0/1000字
划线
笔记
复制
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
该试读文章来自付费专栏《深入拆解Tomcat & Jetty 》,如需阅读全部文章,
请订阅文章所属专栏。
立即订阅
登录 后留言

精选留言(15)

  • nightmare
    第一selectorUpdate可以统一抽象封装注册的io事件,坐到面相抽象编程,将来如果nio的api接口有变动,也不需要改动ManangerSelector的代码 只需要新建一下selectorUpdate的子类来实现变更 第二 作为缓冲,,如果高并发的话,一下子很多channel注册到linux的epoll模型上,红黑树的层级就会很大,select的时候就比较耗时,有一个缓冲,可以均匀注册到linux的epoll模型上,既不会快速让红黑树发生过多旋转,也不会过多占用太多文件描述符
    2019-06-22
    9
  • QQ怪
    课后问题就有点像分布式服务为什么爱用消息中间件一样,一切都是为了解耦,服务类比线程,服务与服务可以直接通讯,线程与线程也可以直接通讯,服务有时候会比较忙或者挂掉了,会导致该请求消息丢失,线程与线程之间的上下文切换同样会带来很大的性能消耗,如果此时的线程池没有多余的线程使用,可能会导致线程积压致使cpu飙高,使用队列能够有效平衡消费者和生产者之间的压力,达到高效率执行。

    作者回复: 是的,还有个原因是各个Process线程直接改变Poller的状态需要加锁,将Update的操作封装成任务放到队列串行执行无需加锁

    2019-06-23
    7
  • -W.LI-
    李老师好!越看越不明白了,我承认我基础差也没去看源码。不晓得别的同学看不看的懂。
    老师能不能画点图方便理解。managedSelector怎么工作的还是不清楚。
    只看懂了四种生成消费模型
    1.单线程
    2.io多路复用,把selector当做生成着,处理的业务逻辑单做消费者。(缺点就是不能用缓存,接受任务和处理任务不在一个线程)
    3.就是接受和处理放一个线程,整体放在多线程里面跑。好处就是可以用缓存
    4.对3和2的优化。空余线程多的时候用3,不足用2。把接受到的任务缓存起来防止拒绝太多任务。
    后面的就看不懂了。
    问题1.managedSelector只负责监听read事件么?。accept事件他监听么?一个端口能被多个serversocketchannel监听么?
    问题2.文中说managedselector由endpoint管理,具体怎么管理的呢?managedselector有多少个?怎么创建的?不同的managedselector之间channel共享么(个人感觉不共享会有并发冲突)?
    问题3.线程不够用的时候具体怎么切换的呢?慢慢的全部都转成2还是保留一部分线程执行3一部分执行2。
    问题4.我连channel是怎么注册到managedselector上的都没看明白。更别说销毁了。
    其实就是想知道这几个类的生命周期,然候就是直接执行交互图,纯文字我想不出。希望老师解惑不胜感激
    2019-06-24
    6
  • 802.11
    老师,在NIO2中服务器端的几个概念不是很清晰,比如WindowsAsynchronousChannelProvider,Invoker等。如果需要系统了解这几个概念是怎么串起来的,怎么办呢。

    作者回复: 建议阅读JVM底层源码

    2019-06-23
    2
  • 张德
    李老师能否讲一下怎么调试源码 怎么搭建调试源码的环境 就比如说拿Jetty举例

    作者回复: 用嵌入式的方式启动jetty,引入jetty jar包就行

    2019-06-25
    1
  • magicnum
    不直接注册I/O事件是为了解耦吧,而且队列平衡了生产者消费者的处理能力
    2019-06-22
    1
  • 掐你小77
    本章节中主要涉及的是三个组件:ManagerSelector,Producer(SelectoeProducer),ExecutionStrategy
    其中三个组件的作用如下:
    1,ManagerSelector用于其他调用者注册感兴趣事件和事件对应的处理逻辑。
       如何注册感兴趣事件和处理逻辑呢?提供了两个接口:SelectorUpdate和Selectable,
       其中SelectorUpdate接口让调用者可以网ManagerSelector中的Selector注册感兴趣事件,
       其中Selectable接口让调用者提供一个处理逻辑。
       
    2,Producer是一个发动机,它的作用就是:注册 --> 获取就绪的IO --> 产生对应的处理任务
       上述对应了其内部的三个方法:processUpdates,select,processSelected
       其对应的实现类为:ManagerSelector.SelectoeProducer

    3,ExecutionStrategy则是上面Producer接口产生处理任务的执行策略了,jetty中默认的策略有:
       a,ProduceConsume 单线程创建和执行所有任务
       b,ProduceExecuteConsume 专门线程创建任务,然后任务放进线程池中执行
       c,ExecuteProduceConsume 一个线程中创建任务并执行,同时启动另一个线程进行任务的创建
          和执行,其中顺序是:创建任务 --> 开启新线程(使用线程池) --> 执行任务
       d,EatWhatYouKill 判断当前当前是否系统忙碌,在ProduceExecuteConsume和ExecuteProduceConsume
          运行模式中切换
                
    较于理解(不准确)的执行顺序:调用者 --> ManagerSelector --> SelectoeProducer --> ExecutionStrategy

    这样总结对么?老师。
    2019-10-13
  • Gary
    老师好,在 ManagedSelector # SelectorProductor # processUpdates() 源码中看到有这么一段
                synchronized(ManagedSelector.this)
                {
                    Deque<SelectorUpdate> updates = _updates;
                    _updates = _updateable;
                    _updateable = updates;
                }
                ···
               for (SelectorUpdate update : _updateable){
                ···
                }
               这里不直接循环 _updates 的原因是防止不断有请求填充了 _updates,导致前面的请求无法返回吗,感觉这里的_updateable 用一个局部变量就可以了,为啥他要作为类的字段
    2019-10-09
  • 星辰
    1. 原来EatWhatYouKill是这个意思啊!

    2. 感觉jetty比tomcat更会巧妙的使用资源

    3. 评论区的问题和我的好像也差不多,22讲答疑应该会有。

    4. 操作系统的知识确实要常识化,到现在都没弄懂select poll epoll 是什么,已经三者之间的区别。

    5. 但是看了老师的讲解后,自己渐渐对网络编程好像有兴趣了,也更好奇了,之前从来没有过的感觉。只是现在还不知道从哪入手。
    2019-08-13
  • Demter
    赞一个
    2019-08-06
  • sionsion
    https://webtide.com/eat-what-you-kill/ , 这里有一篇文章也做了解释,有兴趣的可以看看。
    2019-07-14
  • kyon
    请问 Selectable 实现类是在什么时机注册到 ManagedSelector 的?是和提交 Selector 更新任务类一起吗?_selector.submit(_updateKeyAction)?

    另外 ManagedSelector 里为什么有两个 SelectorUpdate 队列,下面一个是不是 Selectable 队列?
    private Deque<Selectable> _updateable = new ArrayDeque<>();
    2019-06-26
  • -W.LI-
    李老师!SelectorUpdate接口的update方法有个入参完了。硬是没看见哪用了这个入参。泪流满面老师。
    2019-06-24
  • -W.LI-
    老师好!我有个问题,我是先把学校教的计算机基础的书操作系统,计算机组成原理这些再看一遍补基础。还是直接上手撸源码啊?

    作者回复: 可以看看操作系统相关的部分,比如进程,虚拟地址,用户空间,内核空间。

    2019-06-24
  • -W.LI-
    老实好!
    检测到读就绪的时候数据已被拷贝到了内核缓存中。CPU的缓存中也有这些数据。
    这句话怎么理解啊,CPU的缓存说的是高速缓存么?然后内核缓存是什么呢?这方面的知识需要看啥书补啊(是操作系统么?)?IO模型,数据需要拷贝的次数我一点搞不懂

    作者回复: 内核缓存是指,一个进程的虚拟地址地址空间分为用户空间和内核空间,我在22答疑篇会详细说说,这些都是操作系统的知识。

    2019-06-24
收起评论
15
返回
顶部