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

16 | AprEndpoint组件:Tomcat APR提高I/O性能的秘密

李号双 2019-06-15
我们在使用 Tomcat 时,会在启动日志里看到这样的提示信息:
The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: ***
这句话的意思就是推荐你去安装 APR 库,可以提高系统性能。那什么是 APR 呢?
APR(Apache Portable Runtime Libraries)是 Apache 可移植运行时库,它是用 C 语言实现的,其目的是向上层应用程序提供一个跨平台的操作系统接口库。Tomcat 可以用它来处理包括文件和网络 I/O,从而提升性能。我在专栏前面提到过,Tomcat 支持的连接器有 NIO、NIO.2 和 APR。跟 NioEndpoint 一样,AprEndpoint 也实现了非阻塞 I/O,它们的区别是:NioEndpoint 通过调用 Java 的 NIO API 来实现非阻塞 I/O,而 AprEndpoint 是通过 JNI 调用 APR 本地库而实现非阻塞 I/O 的。
那同样是非阻塞 I/O,为什么 Tomcat 会提示使用 APR 本地库的性能会更好呢?这是因为在某些场景下,比如需要频繁与操作系统进行交互,Socket 网络通信就是这样一个场景,特别是如果你的 Web 应用使用了 TLS 来加密传输,我们知道 TLS 协议在握手过程中有多次网络交互,在这种情况下 Java 跟 C 语言程序相比还是有一定的差距,而这正是 APR 的强项。
取消
完成
0/1000字
划线
笔记
复制
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
该试读文章来自付费专栏《深入拆解Tomcat & Jetty 》,如需阅读全部文章,
请订阅文章所属专栏。
立即订阅
登录 后留言

精选留言(26)

  • -W.LI-
    NIO 的 Buffer 除了做了缓冲块优化之外,还提供了一个可以直接访问物理内存的类 DirectBuffer。普通的 Buffer 分配的是 JVM 堆内存,而 DirectBuffer 是直接分配物理内存。

    我们知道数据要输出到外部设备,必须先从用户空间复制到内核空间,再复制到输出设备,而 DirectBuffer 则是直接将步骤简化为从内核空间复制到外部设备,减少了数据拷贝。

    李老师好!上面是隔壁班刘超老师的原话。好像和您讲的优点冲突。请问答题时写哪个答案啊?

    作者回复: Directbytebuffer是通过Unsafe类来分配本地内存的,实际上调用了C语言中的allocate来分配内存,是属于用户空间的。
    base = unsafe.allocateMemory(size);

    从用户空间到内核空间中需要有一次数据拷贝,应用程序不能直接操作内核空间。知乎上也有人问了这个问题:
    https://www.zhihu.com/question/269052579/answer/354173816

    2019-06-20
    12
  • YF
    老师,为什么从本地内存到 JVM 堆的拷贝过程中 JVM 可以保证不做 GC呢?那为什么从内核拷贝到JVM堆中就不能保证做GC呢?

    作者回复: 这是HotSpot VM层面保证的,具体来说就是HotSpot不是什么时候都能GC的,需要JVM中各个线程都处在“safepoint”时才能GC, 本地内存到JVM 堆的拷贝过程中是没有“safepoint”的,所以不会GC,至于什么是“safepoint”,你可以搜索一下。

    2019-06-15
    9
  • nimil
    学到了,之前还纳闷,我在使用高版本的SpringBoot的时候总是会有arp的警告,今天终于知道是干嘛的了。感谢老师。
    2019-06-15
    5
  • 鱼仔💪
    看老师课收获很多,老师讲的很好,这一讲有个问题:
    之前讲到 同步和异步,是指应用程序在与内核通信时,数据从内核空间到应用空间的拷贝,是由内核主动发起还是由应用程序来触发。
    JVM 内存只是进程空间的一部分,除此之外进程空间内还有代码段、数据段、内存映射区、内核空间等。
    从内核空间到应用空间的拷贝是 应用程序本地内存向JVM堆上的拷贝;还是内核缓冲区向 应用程序本地内存的拷贝?

    作者回复: 是内核缓冲区向应用程序本地内存的拷贝

    2019-07-16
    3
  • gameboy120
    请问从本地内存拷贝到jvm堆不会引起gc是在哪里有说明?

    作者回复: 文中没有说明,展开会收不住,你可以搜索hotspot vm的safepoint是怎么回事

    2019-07-10
    3
  • 飞翔
    老师 能不能讲讲什么时候用apr 什么时候用nio2 nio?

    作者回复: 如果web应用使用tls通信,对性能响应时间要求比较高,而用户又愿意花时间去配置APR,推荐APR。

    NIO和NIO2其实差别不是很大,如果硬要区分,NIO适合处理比较轻的,数据传输量比较少的请求,AIO适合比较重,数据传输量比较大的请求。

    这是因为NIO本质还是同步,数据从用户空间和内核空间之间的拷贝还是阻塞的。

    2019-06-16
    3
  • 代码搬运工
    java语言有个特性,一次编译到处执行,而class文件需要通过虚拟机编译成操作系统指令。不同操作系统的指令不一样,所以有对应的虚拟机来简化代码开发。c语言好像是直接调用操作系统指令,代码开发中调用一个方法,不同的操作系统可能不一样,还得准备两份。老师,说的对吗?

    作者回复: 对的

    2019-06-15
    3
  • 粉条炒肉
    老师,请教一个问题,每次服务的访问高峰期重启或者发布tomcat服务,都会出现阻塞线程过多 这种情况是不是容器初始化的时候需要预热很多资源,从而响应不过来请求而导致阻塞,关于这种情况,有什么好的解决办法。

    作者回复: 服务没有启动完成的时候,不要把流量送过来。

    2019-06-15
    3
  • z.l
    请教老师, DirectByteBuffer和常说的mmap是什么关系?

    作者回复: 没有关系的,mmap是将文件映射到用户进程的虚拟地址空间,进程向这个地址读写内存,内核负责将数据同步到磁盘文件,考虑在答疑篇详细说说

    2019-06-15
    2
  • 陆离
    虚拟机只是抽象了操作系统,但并不是虚拟机也是一套的。
    jvm的解释器在不同操作系统下是不同的,因为要将字节码解释生成本地机器码。
    这么简单个问题,感觉还是解释不清楚,这个要和操作系统原理联系起来了。
    烦请老师做一个详细的简单!

    作者回复: JVM为了跟操作系统打交道,必须调用操作系统提供的API,而每个操作系统提供的API都不同,所以必须针对不同的操作系统实现不同的JVM,这样位于JVM之上的Java字节码才可以实现跨平台。

    2019-06-15
    2
  • 莫妮卡的泥
    我不认同作者说的directbuffer少一次拷贝就一定性能好,我们先不提内联,可以简单地将directbuffer cache类比到page cache,就会发现如果做的够好,看起来的多一次拷贝反而会提升性能,而且作者的sendfile图画错了,两张图也都没有体现出page cache的存在,看到现在,个人感觉,作者在框架把控上确实一流,但是在io栈上有待提升。
    2019-09-15
    1
  • -W.LI-
    老师好!
    网卡->内核->用户空间->内核->网卡。
    IO读写都需要拷贝两次。
    之前一直不理解为啥不直接到用户空间,看完老师的解释才知道是因为网卡直接到用户空间,容易GC,GC后内存映射地址改变。所以多了一次内核空间做桥接。大部分基于虚拟机的语言都会有这个问题?

    作者回复: 跟GC的实现有关,GC有多种算法,有的需要移动对象,有的不需要,如果不需要移动对象就没有问题。

    2019-06-20
    1
  • nightmare
    老师,arp模式更加适合https,或者文件传输的业务场景,相对于nio会有更快的io速度
    2019-06-15
    1
  • 静水流深
    看了网上的很多资料,也有其他培训课程的,内存这块,只有老师您讲得最清晰。谢谢老师分享。
    2019-11-14
  • 佑儿
    sendfile的过程是不是就是所谓的零拷贝?
    2019-10-10
  • 靠人品去赢
    老师文章好,答疑也很有料,我之前学习GC的时候对这个safepoint只是了解一个概念,结合文章和答疑中,本地内存往JVM堆中拷贝数据时肯定不能GC,万一干掉了或者找不到了就不行,safepoint可以保障一下。
    还有一个问题就是DirectByteBuffer的,我觉得他就是用户态了,因为应用不能直接操作内核态,我在想本地内存会不会也有垃圾回收的说法,万一搞不好内存溢出本地内存怎么办。
    2019-10-10
  • intomymind
    老师您好,有两台服务器,A服务器向B服务器发起一个rpc调用,那么从A服务器发起请求到B服务器,B服务器接收请求处理最后在返回给服务器A,那么从A->B和B -> A这两个过程的网卡、用户空间、内核空间的一个处理流程是什么样的呢?
    2019-09-01
  • 愤怒💢的可乐😠
    大佬,本文中所介绍的I/O,内存拷贝等知识有没有书籍推荐啊

    作者回复: unix环境高级编程

    2019-08-31
  • What for
    关于 TCP 连接我有一个问题想请教下老师:
    我理解的 TCP 是经过三次握手之后建立了连接才可以发送数据的,那么文中提到的等有了数据才建立连接是怎么回事呢?
    2019-08-24
  • 王藝明
    老师。内核缓冲区和本地缓冲区,物理上是指哪里呢,是指内存条,还是cpu高速缓存
    2019-08-22
收起评论
26
返回
顶部