- 接下来官方就要甩锅了,有趣的是,这次接锅的并非JDK,而是大名鼎鼎的...Netty
- 为什么是Netty接锅呢?
- 首先 , Netty使用了Reactor线程模型,而Netty Reactor的核心是Event Loop,下图来自《Netty in Action》,是处理web请求的内部架构图,
文章插图
- 那么 , 应该有多少个EventLoop线程呢?下图是Netty源码 , 默认值是CPU核数的2倍,看得出这是个很保守的数字
文章插图
- 从上面的架构图和代码可以看出,Netty的反应式框架的核心是使用少量线程来分发web请求,这样的结果仅使用了少量线程资源就能高效处理事件
- 也正式因为有了线程数不多这个前提 , 在对JSON做序列化处理时,Netty放心的使用了ThreadLocal,毕竟线程少 , 一个4核的CPU也才8个ThreadLocal,毫无压力
- 而且,为了更加高效,Netty还对ThreadLoacal进行过改造,也就是他们自研的FastThreadLocal
- 然后,时间一天天过去 , 终于等来了JDK19发布,
- quarkus的反应式web服务模块底层就是Netty , 为了用上虚拟线程,他们动手了...咱们脑补一下吧,铺天盖地的虚拟线程线程 , 铺天盖地的FastThreadLocal对象,炸了吧您...Are U OK ?
- 快乐之后,咱们还是要正视这个问题,表面上看是个坑,实际上是两种设计思路的冲突:
- 虚拟线程的特性类似golang的协程,很适合直接拿来处理高并发web请求,为每个请求分配一个虚拟线程,逻辑清晰直白 , 资源消耗又不高,典型的简单高效
- Netty的反应式模型,核心思路就是用少量线程高效分发大量请求 , 本身就很高效,而且就算优化,线程数也不是瓶颈
- 所以,quarkus拎着虚拟线程冲到Netty的地盘一阵操作猛如虎 , 一看结果...唉,扯远了,来看quarkus官方的解释吧
文章插图
- 上图红框中那句话很有价值,咱们都能从中领悟到一些东西,我的收获是:当线程数不是系统瓶颈的时候,就别冲动,强行上虚拟线程没用
- 既然虚拟线程不适合反应式模型,个人认为:那就不妨大大方方的承认Netty的Reactor是优秀的,放弃将虚拟线程加入进来,这样不是挺好么?
- 然而quarkus接下来的操作还是把我吓到了:既然虚拟线程不适合反应式模型?那就想办法强行让它适合,下图就是quarkus的做法:在构建阶段,找到创建ThreadLocal的那段代码,修改它的字节码,以此来解决前面的内存问题
文章插图
- 然后我就翻到了上图提到的那段代码
文章插图
- 好奇心驱使,我点开上图那个NettyCurrentAdaptor去看了下源码,当时就一阵头晕眼花,ASM风格的代码您能撑多久?试试下图
文章插图
- 按照官方的说法,经过他们的优化有百分之八十的提升,终于快要达到之前反应式框架的水平了
- 呃 , 搞得这么辛苦,也只是快要追上而已,那行,咱不用了行吗?
- 另外,上面说的优化手段也不是默认开启的 , 还要做以下几步操作
- maven的pom.xml添加以下依赖
<dependency><groupId>io.quarkus</groupId><artifactId>quarkus-netty-loom-adaptor</artifactId></dependency>
- 编译构建的时候,增加参数-Dnet.bytebuddy.experimental
- 启动的时候,增加参数--add-opens java.base/java.lang=ALL-UNNAMED
- 上述操作算 , quarkus的手段,我这个草根只能仰望,能开拓自己的见识:原来还可以这样解决问题
- 但我自己是绝对不敢模仿的,开玩笑,在编辑阶段注入代码,难度太大,并且后面如何维护和交接?
- 至此,咱们压测做了,代码写了,源码读了,八卦也看了,《支持JDK19虚拟线程的web框架》系列也到了和您说再见的时候
推荐阅读
- 红米note11pro有呼吸灯吗_支持呼吸灯吗
- vivox60支持wifi6吗_wifi6有什么优势
- iqoo7支持无线充电吗_iqoo7电池容量是多少
- vivox70pro支持无线充电吗_支持多少w快充
- 支持JDK19虚拟线程的web框架之四:看源码,了解quarkus如何支持虚拟线程
- LAL v0.32.0发布,更好的支持纯视频流
- ipadmini6屏幕刷新率_ipadmini6支持120刷新率吗
- 一加9pro支持反向充电吗_一加9pro支持无线反向充电吗
- 小米11无线充电多少w_小米11支持多少w无线充电
- 荣耀magic3有没有红外遥控?荣耀magic3支持NFC吗