深入拆解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
登录|注册

21 | 总结:Tomcat和Jetty的高性能、高并发之道

李号双 2019-06-27
高性能程序就是高效的利用 CPU、内存、网络和磁盘等资源,在短时间内处理大量的请求。那如何衡量“短时间和大量”呢?其实就是两个关键指标:响应时间和每秒事务处理量(TPS)。
那什么是资源的高效利用呢? 我觉得有两个原则:
减少资源浪费。比如尽量避免线程阻塞,因为一阻塞就会发生线程上下文切换,就需要耗费 CPU 资源;再比如网络通信时数据从内核空间拷贝到 Java 堆内存,需要通过本地内存中转。
当某种资源成为瓶颈时,用另一种资源来换取。比如缓存和对象池技术就是用内存换 CPU;数据压缩后再传输就是用 CPU 换网络。
Tomcat 和 Jetty 中用到了大量的高性能、高并发的设计,我总结了几点:I/O 和线程模型、减少系统调用、池化、零拷贝、高效的并发编程。下面我会详细介绍这些设计,希望你也可以将这些技术用到实际的工作中去。

I/O 和线程模型

I/O 模型的本质就是为了缓解 CPU 和外设之间的速度差。当线程发起 I/O 请求时,比如读写网络数据,网卡数据还没准备好,这个线程就会被阻塞,让出 CPU,也就是说发生了线程切换。而线程切换是无用功,并且线程被阻塞后,它持有内存资源并没有释放,阻塞的线程越多,消耗的内存就越大,因此 I/O 模型的目标就是尽量减少线程阻塞。Tomcat 和 Jetty 都已经抛弃了传统的同步阻塞 I/O,采用了非阻塞 I/O 或者异步 I/O,目的是业务线程不需要阻塞在 I/O 等待上。
取消
完成
0/1000字
划线
笔记
复制
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
该试读文章来自付费专栏《深入拆解Tomcat & Jetty 》,如需阅读全部文章,
请订阅文章所属专栏。
立即订阅
登录 后留言

精选留言(16)

  • QQ怪
    @正是那朵玫瑰同学,我认为老师所说的耗费cpu资源指的是线程阻塞和等待进行额外的上下文切换,要理解其,先要知道上下文是什么,具体来说,一个线程被剥夺处理器的使用权而被暂停运行,就是“切出”;一个线程被选中占用处理器开始或者继续运行,就是“切入”。在这种切出切入的过程中,操作系统需要保存和恢复相应的进度信息,这个进度信息就是“上下文”了。至于系统开销具体发生在切换过程中的哪些具体环节,总结如下:
    操作系统保存和恢复上下文;
    调度器进行线程调度;
    处理器高速缓存重新加载;
    上下文切换也可能导致整个高速缓存区被冲刷,从而带来时间开销。以上情况过多都会耗费cpu资源,而你看到cpu资源利用率下降了是因为cpu已经做完了上下文切换,把线程的上下文保存到内存或者硬盘上去了,但是当你的线程重新唤醒,其cpu是不是又要多一次不必要的上下文切换?

    作者回复: 👍

    2019-06-29
    13
  • nightmare
    文件读写,socket网络编程,HeapByteBuffer,JNI都会涉及到系统调用
    2019-06-28
    5
  • 802.11
    刚才看copyonwrite的相关代码,很多地方用了数组拷贝,想问老师,是不是java api中所有带native关键字的方法都走了系统调用

    作者回复: 不一定,native方法只是表明java调用了c函数,c函数一定都调用了系统API

    2019-06-29
    2
    4
  • 802.11
    standservice这个例子中,虽然没有加在方法上,在方法里面加是解决了粒度的问题,但是加了3次和只在方法上加1次,系统调用层面上哪个更少哪个更多呢

    作者回复: JDK1.6 以后 对锁的实现引入了大量的优化,如偏向锁、轻量级锁、自旋锁、适应性自旋锁、锁消除、锁粗化等技术来减少锁操作的开销。

    其实就是避免每次synchronized操作都引起系统调用和上下文切换

    2019-06-29
    1
    3
  • Grubby🐑
    tomcat的startInternal方法,理论上不是应该只有一个线程去调用吗?为什么要加synchronized ?
    2019-06-29
    1
    2
  • ty_young
    老师,请问tomcat的http body延迟解析只是延迟解析或者不用到不解析,但是http的head和body是同时一次都读到内存的吧,能减少一次系统io调用么

    作者回复: 是分开读的

    2019-07-27
    1
    1
  • 不二
    Acceptor 线程组在等待连接建立的过程中,线程还是会阻塞吧?在跟客户端建立连接的这个阻塞有没有优化的方式

    作者回复: 是阻塞的,这里没有很大的必要去优化,因为accept调用仅仅是从操作系统的Tcp已连接队列中取出一个连接,很快的。

    2019-07-18
    1
  • -W.LI-
    老师好!那就是get请求没有body。使用get请求把参数放url上少一次系统调用?

    作者回复: 给你的思考点赞,url长度有限制,另外敏感数据不合适放url,否则是可以的。

    2019-06-27
    1
  • 正是那朵玫瑰
    老师有点疑问:
    1、线程阻塞或者等待会发生上下文切换,耗费cpu资源,线程阻塞或者等待不是会让出cpu吗,应该是浪费cpu资源才对啊?我在压测的时候发现当有大量的线程在await状态时,cpu的利用率立马下降,应该是浪费cpu资源的!老师说会耗费cpu资源 怎么理解呢?
    2、无锁固然是好的、但是无限重试是不是也会耗掉cpu资源,因为很多时候重试都是无用功!
    2019-06-27
    1
    1
  • 不想输,就别懒
    比如可以用细粒度的对象锁或者低强度的读写锁:对于这个问题,我想问下老师,如何从维度更好的把控它?需要多考虑哪些方面?
    2019-12-06
  • 锟铻
    Runtime.exec("shell"),这个是不是系统调用

    作者回复: shell是一个c语言程序,运行这个程序的过程中会有系统调用

    2019-07-19
  • Visual C++
    有其它优化方式吗
    2019-07-07
  • Visual C++
    Tomcat类加载机制触发的Too many open files问题

    如何解决?

    作者回复: 加大进程可打开的最大文件数限制

    2019-07-04
    1
  • 新世界
    文件和网络操作会调用系统API导致在内核和用户态切换
    2019-06-30
  • WL
    老师能不能指点一下在Http11Processor的service()中调用的Http11InputBuffer的parseHeaders()方法是怎么解析header的, 我今天看晕了, 没看懂是怎么将buffer中数据取出解析成header的

    作者回复: 建议你先了解一下“状态机”,这是一种设计模式。

    2019-06-27
  • 代码搬运工
    网络编程socket,输入输出流,创建线程thread,这些属于吧。
    2019-06-27
收起评论
16
返回
顶部