19 | 比较:Jetty的线程策略EatWhatYouKill
该思维导图由 AI 生成,仅供参考
Selector 编程的一般思路
- 深入了解
- 翻译
- 解释
- 总结
Jetty的线程策略EatWhatYouKill采用了名为“EatWhatYouKill”的线程策略,将I/O事件的侦测和处理放到同一个线程来处理,充分利用了CPU缓存并减少了线程上下文切换的开销。根据Jetty的官方测试,这种策略将吞吐量提高了8倍。Jetty的Connector支持NIO通信模型,封装了自己的Selector,叫作ManagedSelector。Jetty的Connector做了一个大胆尝试,将I/O事件的生产和消费放到同一个线程来处理,以充分利用CPU缓存。为了实现这一策略,Jetty定义了ExecutionStrategy接口,并提供了几种具体策略实现类。其中,EatWhatYouKill策略是对ExecuteProduceConsume策略的改良,能在系统繁忙时切换成ProduceExecuteConsume策略,以避免全局线程池中的线程被业务代码阻塞,导致I/O事件侦测无线程可用的情况发生。Jetty的EatWhatYouKill线程策略通过将I/O事件的生产和消费放到同一个线程来处理,充分利用CPU缓存,提高了系统的吞吐量。同时,Jetty还提供了多种具体策略实现类,以适应不同系统繁忙程度下的线程处理需求。Jetty巧妙设计了EatWhatYouKill的线程策略,尽量用同一个线程侦测I/O事件和处理I/O事件,充分利用了CPU缓存,并减少了线程切换的开销。 ManagedSelector的使用者不能直接向它注册I/O事件,而是需要向ManagedSelector提交一个SelectorUpdate事件,ManagedSelector将这些事件Queue起来由自己来统一处理,这样做有利于统一处理I/O事件,提高系统效率。
《深入拆解 Tomcat & Jetty 》,新⼈⾸单¥68
全部留言(19)
- 最新
- 精选
- QQ怪课后问题就有点像分布式服务为什么爱用消息中间件一样,一切都是为了解耦,服务类比线程,服务与服务可以直接通讯,线程与线程也可以直接通讯,服务有时候会比较忙或者挂掉了,会导致该请求消息丢失,线程与线程之间的上下文切换同样会带来很大的性能消耗,如果此时的线程池没有多余的线程使用,可能会导致线程积压致使cpu飙高,使用队列能够有效平衡消费者和生产者之间的压力,达到高效率执行。
作者回复: 是的,还有个原因是各个Process线程直接改变Poller的状态需要加锁,将Update的操作封装成任务放到队列串行执行无需加锁
2019-06-2321 - -W.LI-老实好! 检测到读就绪的时候数据已被拷贝到了内核缓存中。CPU的缓存中也有这些数据。 这句话怎么理解啊,CPU的缓存说的是高速缓存么?然后内核缓存是什么呢?这方面的知识需要看啥书补啊(是操作系统么?)?IO模型,数据需要拷贝的次数我一点搞不懂
作者回复: 内核缓存是指,一个进程的虚拟地址地址空间分为用户空间和内核空间,我在22答疑篇会详细说说,这些都是操作系统的知识。
2019-06-243 - 张德李老师能否讲一下怎么调试源码 怎么搭建调试源码的环境 就比如说拿Jetty举例
作者回复: 用嵌入式的方式启动jetty,引入jetty jar包就行
2019-06-252 - 802.11老师,在NIO2中服务器端的几个概念不是很清晰,比如WindowsAsynchronousChannelProvider,Invoker等。如果需要系统了解这几个概念是怎么串起来的,怎么办呢。
作者回复: 建议阅读JVM底层源码
2019-06-232 - -W.LI-老师好!我有个问题,我是先把学校教的计算机基础的书操作系统,计算机组成原理这些再看一遍补基础。还是直接上手撸源码啊?
作者回复: 可以看看操作系统相关的部分,比如进程,虚拟地址,用户空间,内核空间。
2019-06-24 - nightmare第一selectorUpdate可以统一抽象封装注册的io事件,坐到面相抽象编程,将来如果nio的api接口有变动,也不需要改动ManangerSelector的代码 只需要新建一下selectorUpdate的子类来实现变更 第二 作为缓冲,,如果高并发的话,一下子很多channel注册到linux的epoll模型上,红黑树的层级就会很大,select的时候就比较耗时,有一个缓冲,可以均匀注册到linux的epoll模型上,既不会快速让红黑树发生过多旋转,也不会过多占用太多文件描述符2019-06-2218
- -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-24213
- 掐你小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-133
- sionsionhttps://webtide.com/eat-what-you-kill/ , 这里有一篇文章也做了解释,有兴趣的可以看看。2019-07-142
- Gary老师好,在 ManagedSelector # SelectorProductor # processUpdates() 源码中看到有这么一段 synchronized(ManagedSelector.this) { Deque<SelectorUpdate> updates = _updates; _updates = _updateable; _updateable = updates; } ··· for (SelectorUpdate update : _updateable){ ··· } 这里不直接循环 _updates 的原因是防止不断有请求填充了 _updates,导致前面的请求无法返回吗,感觉这里的_updateable 用一个局部变量就可以了,为啥他要作为类的字段2019-10-0921