支持JDK19虚拟线程的web框架,之三:观察运行中的虚拟线程

支持JDK19虚拟线程的web框架,之三:观察运行中的虚拟线程

本篇借助JProfiler工具,从线程的观察结果去印证官方资料,做到理论结合实践,让您领先一步,掌握和了解神秘的虚拟线程内幕

欢迎访问我的GitHub

这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos

《支持JDK19虚拟线程的web框架》系列文章链接

本篇概览

  • 本篇是《支持JDK19虚拟线程的web框架》系列的第三篇,在前面两篇咱们一起了解和体验了支持虚拟线程的web服务,功能性能都试过,整个开发过程也完整执行,算是对quarkus和虚拟线程有了初步的了解,但也留下两个问题

  • 虚拟线程和常规子线程的区别,究竟能不能看出来?前文已经验证了性能上区别不大,那还有别的方式来观察和区分吗?

  • 能不能稍微深入一点,仅凭一个@RunOnVirtualThread注解就强行写两篇博客,实在是太忽悠人了

  • 本文聚焦第一个问题,与大家一起深入了解虚拟线程,重点在理论结合实际,将官方资料在实战中得到印证

  • 至于第二个问题,留待下一篇…

设置

  • 开始深入学习前有个设置需要确认,否则会导致访问服务失败,请打开前文开发的quarkus应用,下图红色箭头指向的配置必须存在,且值必须是0.0.0.0

支持JDK19虚拟线程的web框架,之三:观察运行中的虚拟线程
  • 如果没有上述配置,IDEA启动的应用就只会监听127.0.0.1这块网卡,如此依赖外部测试工具访问此应用的服务就无法成功
  • 那么就开始吧:如何直观地、清楚地看出虚拟线程和常规子线程的区别?

准备工作

  • 工欲善其事…..咱们先把必要的工具装上:IDEA的JProfiler插件,安装步骤如下图

支持JDK19虚拟线程的web框架,之三:观察运行中的虚拟线程
  • 接下来请在自己电脑上安装JProfiler,注意,这一步必须要做,详细的安装和注(po)册(jie)过程就不写在本文中了,请自行搜索相关资料
  • 完成上述准备后,点击下图箭头所指按钮,这样就指定了JProfiler去监控分析启动后的应用进程
  • IDEA会拉起JProfiler

支持JDK19虚拟线程的web框架,之三:观察运行中的虚拟线程
  • 出现新的窗口如下图,再点击右下角的确定按钮

支持JDK19虚拟线程的web框架,之三:观察运行中的虚拟线程
  • 现在JProfiler已经在监控quarkus应用的进程了,界面如下

支持JDK19虚拟线程的web框架,之三:观察运行中的虚拟线程
  • 如下图,点击线程历史菜单,就能看到当前应用进程内的所有线程,注意按照步骤2过滤一下,只看存活的线程

支持JDK19虚拟线程的web框架,之三:观察运行中的虚拟线程
  • 接下来,咱们就要用JProfiler来观察常规线程和虚拟线程的区别了
  • 先回忆一下,前文中,咱们开发的quarkus应用有两个web服务类,分别是:

  • VTPersonResource.java,该服务类使用了虚拟线程来执行web响应,对应web路径:/vt/persons

  • PoolPersonResource.java,该服务类未使用虚拟线程,所以执行web响应的是传统线程池中的子线程,对应web路径:/pool/persons

  • 接下来,压测工具k6先后压测上述两个接口,用JProfiler观察进程中线程的变化情况

不使用虚拟线程时的线程状况

  • 咱们先发请求到/pool/persons,也就是先不用虚拟线程,看看传统线程池响应web服务的时候,在JProfiler中是啥样的
  • 像那样,用K6压测接口/pool/persons,脚本如下,注意IP地址不能用localhost,因为这是在docker容器内运行的,localhost代表容器的回环网卡,而并非宿主机的:
import http from 'k6/http';
import { sleep, check } from 'k6';

export let options = {
  vus: 10,
  duration: '60s',
};

export default function () {
  let r = Math.floor(Math.random() * 6) + 1;
  const res = http.get(http://192.168.3.187:8080/pool/persons/${r});
  check(res, {
    'is status 200': (res) => res.status === 200,
    'body size is > 0': (r) => r.body.length > 0,
  });
  sleep(1);
}
  • 在压测期间去看JProfiler,如下图红框,新增了10个线程,它们就是负责处理web响应的线程(前文的实战中,我们已见过web响应的内容,里面就有线程名称,红框中的和它们一致)

支持JDK19虚拟线程的web框架,之三:观察运行中的虚拟线程
  • 下图是K6的测试报告,可见一共发起了570次请求,然而压测期间JProfiler上新增的线程只有上图中的十个,这也印证了线程池的逻辑:每个线程执行完业务逻辑后,回到线程池,下一次请求到来时,该线程继续执行业务逻辑

支持JDK19虚拟线程的web框架,之三:观察运行中的虚拟线程
  • k6压测结束后,等上三十秒再去看JProfiler,如下图,那些处理web响应的子线程已经不见了(或者说不是存活状态了)

支持JDK19虚拟线程的web框架,之三:观察运行中的虚拟线程
  • 如果您熟悉Java的线程池原理,对以上情况就一目了然:线程池空闲时,保留线程数不超过corePoolSize
  • 既然看过了传统线程池的服务情况,接着改看虚拟线程的情况了,两边对比着看收获一定不小

思考:用JProfiler观察虚拟线程,你到底想收获什么?(本篇精华段落)

  • 大家好,接下来这一段话,个人觉得是本篇的精华,因为这是欣宸自己在迷茫中找到方向的一种方法(或者套路),希望能给您带来参考
  • 在用JProfiler观察虚拟线程之前,咱们先来捋捋: 接下来咱们究竟想看到什么,能用文字说清楚吗?这个问题很重要!
  • 仅仅是想看一眼虚拟线程吗?那无非就是看到几个新增的线程,名字有些特殊,仅此而已,这能有啥收获?
  • 不要急于动手,咱们都应该冷静下来,认真思考,让这个问题能用文字表达出来,而不是仅仅在心中有个运行JProfiler的冲动:借助JProfiler,咱们真正想要的是证虚拟线程的来龙去脉,也就是把官方文档中的理论,在JProfiler中找到实现!
  • 所以,先阅读虚拟线程的官方文档吧,放心,咱们只看最关键的部分即可,不会涉及长篇大论
  • 打开java官方文档,找到虚拟线程定义的那段,如下图,注意红框中的内容以及我的中文注解(我将下面这幅图称为本篇最有价值的地方)

支持JDK19虚拟线程的web框架,之三:观察运行中的虚拟线程
  • 没错,官方文档虽多,但咱们没必要全看,上面这段才是关键,看完后捋捋流程图如下

支持JDK19虚拟线程的web框架,之三:观察运行中的虚拟线程
  • 看到上图,您应该会有以下三个疑惑:

  • ForkJoin线程池啥时候创建的?会不会销毁?

  • 调度器(scheduler)啥时候创建的?会不会销毁?
  • carrier啥时候创建的?会不会销毁?

  • 如果这些关键问题没说清楚,上面的流程图算不算是捋了个寂寞…

  • 要想搞清楚为什么没有回答上面三个问题,咱们把官方文档滚动到最顶部,如下图

支持JDK19虚拟线程的web框架,之三:观察运行中的虚拟线程
  • 上图红框表明,这是一篇JEP文档,即: JDK Enhancement Proposal ,这类文档只提出标准,而非实现,真正实现的这个标准的,是各个JVM虚拟机厂家(例如Oracle),所以,要想回答上面三个问题,只能去查找具体JDK软件的实现
  • 简单的说:别纠结那三个问题,我答不上来…

  • 咱们继续,接下来更精彩

  • 看过官方资料后,再回到最初的问题,咱们想通过JProfiler得到什么?相信您已经很清楚了吧,我觉得是这三样:

  • 调度器,scheduler(ForkJoin线程池中的线程)

  • 执行虚拟线程任务的真实线程,carrier
  • 虚拟线程

  • 现在开始压测吧,继续用k6,如下图,脚本中的地址要改成使用虚拟线程的web服务

支持JDK19虚拟线程的web框架,之三:观察运行中的虚拟线程
  • 压测期间去观察JProfiler,如下图,完全符合预期,说实话,第一次看到这些内容时,自己的内心是很激动的,这种知识点得到印证的感觉真是太好了

支持JDK19虚拟线程的web框架,之三:观察运行中的虚拟线程
  • 再看看那些不再存活的线程,如下图,大量VirtualThreads存在,这也符合虚拟线程的特性:不复用,执行完毕就结束

支持JDK19虚拟线程的web框架,之三:观察运行中的虚拟线程
  • 等到压测结束后,scheduler、carrier、虚拟线程,它们都不再存活,如下图

支持JDK19虚拟线程的web框架,之三:观察运行中的虚拟线程
  • 如此看来,在执行任务的时候,会出现sheduler和carrier来完成虚拟线程中的任务,等到这些任务执行完毕,所有真实线程、虚拟线程都被结束,不再存活
  • 至此,借助JProfiler观察常规线程和虚拟线程的实战就完成了,经过了这些理论结合实际的操作和分析,相信您对虚拟线程的认知已经更具体和全面,如今它不再神秘或者高深莫测,咱们也更有信心学好它用好它

我有个想法

  • 码字码到这里,我想抛出一个大胆的想法和大家一起讨论:今天咱们借助JProfiler观察到了scheduler、carrier、虚拟线程等的创建、运行、结束等过程,我这里用的虚拟机是azul JDK,所以JProfiler中看到的也只是azul JDK对虚拟线程规范的实现情况, 如果换成其他JDK,例如Oracle JDK,那么在JProfiler中看到的scheduler、carrier、虚拟线程它们会不会有所不同呢?(例如scheduler可能会存活得久一些)毕竟JEP 425只是个标准,没有明确规定实现,而azul JDK和Oracle JDK属于不同厂商的实现
  • 当然了这只是个猜测,篇(lan)幅(de)所(dong)限(shou)就不在本篇做这些事情了,当我相信会有爱动手的读者去实战操作的,麻烦您告诉欣宸一下您的验证结果,谢谢啦!
  • 写到这里,虚拟线程的文章可以完结了吗?不会,接下来咱们还要畅游quarkus,揭秘@RunOnVirtualThread注解背后的故事,看看优秀的框架是如何玩转虚拟线程的,上广告词:欣宸原创,不辜负您的期待!

欢迎关注博客园:程序员欣宸

学习路上,你不孤单,欣宸原创一路相伴…

Original: https://www.cnblogs.com/bolingcavalry/p/16868467.html
Author: 程序员欣宸
Title: 支持JDK19虚拟线程的web框架,之三:观察运行中的虚拟线程

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/686239/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • 建造者模式(创建型)

    建造者模式 介绍 建造者模式注重的是部件构建的过程,意在 通过一步一步地精确构造出一个复杂的对象。 可以将建造者模式理解为,假设我们有一个对象需要建立,这个对象是由多个组件(Com…

    技术杂谈 2023年6月21日
    099
  • 常见题目

    这几天有朋友反映给小编说让多发点关于面试的文章,小编深知从事IT行业的难处,跳槽多,加班多,薪资不乐观,大多数朋友都想找新的工作,进入一个好的公司,今天小编就给大家带来了C语言面试…

    技术杂谈 2023年6月21日
    0102
  • MySQL的简单实用 手把手教学

    MySQL的使用 1.登陆数据库 打开terminal 在终端根文件目录下输入 /usr/local/mysql/bin/mysql -u root -p 接着输入管理员密码 2….

    技术杂谈 2023年7月25日
    077
  • 接入华为游戏防沉迷,点击防沉迷弹窗后游戏闪退

    问题描述 我们游戏接入华为游戏服务sdk 6.1.0.301版本后,使用华为帐号(实名信息为未成年人)测试,登录后出现SDK的防沉迷提示弹框,点击”知道了”…

    技术杂谈 2023年5月31日
    096
  • 如何禁用笔记本自带键盘

    将笔记本自带键盘禁用之后,就可以把课本放在键盘上而不按键了 搜索cmd,选择命令提示符,右键,以管理员身份运行(否则会无法访问),随后输入: 重启即可 如果想要重新启用自带键盘,输…

    技术杂谈 2023年7月25日
    094
  • FlinkSQL之Windowing TVF

    Windowing TVF 在Flink1.13版本之后出现的替代之前的Group window的产物,官网描述其 is more powerful and effective s…

    技术杂谈 2023年7月24日
    071
  • Vue 插槽

    插槽到底是个啥?5分钟搞定 Vue 插槽 插槽的基本使用 组件使用slot标签,显示组件标签的内容 Title aaa Vue.component(‘child1’, { temp…

    技术杂谈 2023年6月21日
    0100
  • 技术管理进阶——把控基建与业务的比例和节奏

    原创不易,求分享、求一键三连 前段时间有个粉丝问了一个问题: 小钗你好,我十分喜欢技术,但真的转到工程团队后又十分困惑:工作没人评价也没人push!做得好没人夸奖,做得差没人批评,…

    技术杂谈 2023年6月1日
    0100
  • c语言-交换两个整数

    使用c来写一个函数来实现交换两个整数。 第一种 一般的方法,引用中间变量,方便快捷。 第二种 tmp虽然可能会溢出,但是依然能够达到交换的效果。 上面的都是引用了中间变量,再看看不…

    技术杂谈 2023年6月21日
    092
  • 软件测试流程是什么?这题我不会啊

    转载请注明出处❤️ 作者:测试蔡坨坨 原文链接:caituotuo.top/ae4fff18.html 你好,我是测试蔡坨坨。 最近收到不少准备转行软件测试的小伙伴私信问真实企业里…

    技术杂谈 2023年7月11日
    091
  • tcprstat和tcpstat性能监控

    tcprstat是percona用来监测mysql响应时间的。不过对于任何运行在TCP协议上的响应时间,都可以用。 下面是一个监控示例,监控分析mysql的3306端口。 根据上面…

    技术杂谈 2023年5月31日
    0116
  • HTTP状态管理机制之Cookie

    一、cookie 起源 cookie 最早是网景公司的雇员 Lou Montulli 在1993年3月发明,后被 W3C 采纳,目前 cookie 已经成为标准,所有的主流浏览器如…

    技术杂谈 2023年6月1日
    095
  • 如何将JetBrains IDE 光标由块变为 |

    1 设置中确认未勾选 2 安装了IdeaVim 插件,将其改为未选中状态,或者 ⌥ + ⌘ + v 将其关闭 Original: https://www.cnblogs.com/p…

    技术杂谈 2023年5月31日
    0103
  • Hadoop集群模式安装笔记

    前言 Hadoop集群= HDFS集群+ YARN集群特点:两个集群逻辑上分离,通常物理上在一起;并且都是标准的主从架构集群 Hadoop安装 方&#…

    技术杂谈 2023年6月21日
    094
  • 详解重绘与回流

    1、输入url ( 协议、网络地址、资源路径 ) 2、查看浏览器缓存,看是否有缓存,如果有缓存,继续查看缓存是否过期,如果没有过期,直接返回缓存页面,如果没有缓存或者缓存过期,发送…

    技术杂谈 2023年6月1日
    095
  • Rust入门秘籍(更新中)

    骏马金龙 (博客已搬家:www.junmajinlong.com) 网名骏马金龙,钟情于IT世界里的各种原理和实现机制,强迫症重症患者。爱研究、爱翻译、爱分享。特借此一亩三分田记录…

    技术杂谈 2023年5月31日
    099
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球