电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

您的位置:首頁技術(shù)文章
文章詳情頁

解析在Tomcat中啟用虛擬線程特性

瀏覽:226日期:2023-03-19 16:51:50
目錄
  • 前提
  • 引入依賴
  • 編程式初始化Tomcat
  • 暫時無法在SpringBoot體系中使用
  • 小結(jié)

前提

趁著國慶前后閱讀了虛擬線程相關(guān)的源碼,寫了一篇《虛擬線程 - VirtualThread源碼透視》,里面介紹了虛擬線程的實(shí)現(xiàn)原理和使用示例。需要準(zhǔn)備做一下前期準(zhǔn)備:

  • 安裝OpenJDK-19或者Oracle JDK-19
  • 準(zhǔn)備好嵌入式Tomcat的依賴,需要引入三個依賴包,分別是tomcat-embed-coretomcat-embed-eltomcat-embed-websocket,版本選用10.1.0+

查看Tomcat官方文檔的CHANGELOG

支持Loom項(xiàng)目的Tomcat最低版本為10.1.0-M16,對應(yīng)的正式版是10.1.0(當(dāng)前時間為2022-10-07前后),低于此版本因?yàn)榇罅?code>API還沒有適配虛擬線程,主要是沒有改造監(jiān)視器鎖的引用導(dǎo)致虛擬線程pin到載體(平臺)線程等問題,因此別無他選。另外,重要的提醒說三次:

  • 本文是實(shí)驗(yàn)性質(zhì),在未完全證實(shí)改造功能可以應(yīng)用生產(chǎn)環(huán)境前需要謹(jǐn)慎評估,或者先別使用于生產(chǎn)環(huán)境
  • 本文是實(shí)驗(yàn)性質(zhì),在未完全證實(shí)改造功能可以應(yīng)用生產(chǎn)環(huán)境前需要謹(jǐn)慎評估,或者先別使用于生產(chǎn)環(huán)境
  • 本文是實(shí)驗(yàn)性質(zhì),在未完全證實(shí)改造功能可以應(yīng)用生產(chǎn)環(huán)境前需要謹(jǐn)慎評估,或者先別使用于生產(chǎn)環(huán)境

引入依賴

引入以下依賴:

<dependency>    <groupId>org.apache.tomcat.embed</groupId>    <artifactId>tomcat-embed-core</artifactId>    <version>10.1.0</version></dependency><dependency>    <groupId>org.apache.tomcat.embed</groupId>    <artifactId>tomcat-embed-el</artifactId>    <version>10.1.0</version></dependency><dependency>    <groupId>org.apache.tomcat.embed</groupId>    <artifactId>tomcat-embed-websocket</artifactId>    <version>10.1.0</version></dependency>

編程式初始化Tomcat

為了使用反射調(diào)用一些java.base模塊下沒開放的依賴包和跟蹤虛擬線程棧,程序運(yùn)行時候加入下面的VM參數(shù):

--add-opens java.base/java.lang=ALL-UNNAMED --add-opens java.base/java.lang.reflect=ALL-UNNAMED --add-opens java.base/java.util.concurrent=ALL-UNNAMED -Djdk.tracePinnedThreads=full

IDEA的運(yùn)行配置中是這個樣子:

接著編寫一個HttpServlet實(shí)現(xiàn):

public class VirtualThreadHandleServlet extends HttpServlet {    private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS");    @Override    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {Thread thread = Thread.currentThread();System.out.printf("service by thread ==> %s, is virtual ==> %s, carrier thread ==> %s\n",thread.getName(), thread.isVirtual(), getCurrentCarrierThreadName(thread));resp.setStatus(HttpServletResponse.SC_OK);resp.setHeader("Content-Type", "application/json");String content = "{\"time\":" + "\"" + LocalDateTime.now().format(FORMATTER) + "\"}";resp.getWriter().write(content);    }    private static String getCurrentCarrierThreadName(Thread currentThread) {if (currentThread.isVirtual()) {    try {MethodHandle methodHandle = MethodHandles.privateLookupIn(Thread.class, MethodHandles.lookup()).findStatic(Thread.class, "currentCarrierThread", MethodType.methodType(Thread.class));Thread carrierThread = (Thread) methodHandle.invoke();return carrierThread.getName();    } catch (Throwable e) {e.printStackTrace();    }}return "UNKNOWN";    }}

Servlet實(shí)現(xiàn)比較簡單,就是在控制臺打印一些虛擬線程和載體線程的一些信息,然后返回HTTP狀態(tài)碼為200和一個JSON字符展示當(dāng)前精確到毫秒的時間。接著編寫一個main方法初始化Tomcat

public class EmbedTomcatVirtualThreadDemo {    private static final String SERVLET_NAME = "VirtualThreadHandleServlet";    private static final String SERVLET_PATH = "/*";    /**     * 設(shè)置VM參數(shù):     * --add-opens java.base/java.lang=ALL-UNNAMED     * --add-opens java.base/java.lang.reflect=ALL-UNNAMED     * --add-opens java.base/java.util.concurrent=ALL-UNNAMED     * -Djdk.tracePinnedThreads=full     *     * @param args args     * @throws Exception e     */    public static void main(String[] args) throws Throwable {String pinMode = System.getProperty("jdk.tracePinnedThreads");System.out.println("pin mode = " + pinMode);Tomcat tomcat = new Tomcat();Context context = tomcat.addContext("", (new File(".")).getAbsolutePath());Tomcat.addServlet(context, SERVLET_NAME, new VirtualThreadHandleServlet());context.addServletMappingDecoded(SERVLET_PATH, SERVLET_NAME);Connector connector = new Connector();ProtocolHandler protocolHandler = connector.getProtocolHandler();if (protocolHandler instanceof AbstractProtocol<?> protocol) {    protocol.setAddress(InetAddress.getByName("127.0.0.1"));    protocol.setPort(9091);    ThreadFactory factory = Thread.ofVirtual().name("embed-tomcat-virtualWorker-", 0).factory();    Class<?> klass = Class.forName("java.util.concurrent.ThreadPerTaskExecutor");    MethodHandle methodHandle = MethodHandles.privateLookupIn(klass, MethodHandles.lookup())    .findStatic(klass, "create", MethodType.methodType(klass, new Class[]{ThreadFactory.class}));    ExecutorService executor = (ExecutorService) methodHandle.invoke(factory);    protocol.setExecutor(executor);}tomcat.getService().addConnector(connector);tomcat.start();    }}

這里VirtualThreadHandleServlet匹配所有格式的請求路徑并且處理所有請求方法類型的請求。默認(rèn)的虛擬線程調(diào)度器沒有為虛擬線程設(shè)置名稱,也就是如果使用Executors.newVirtualThreadPerTaskExecutor()作為Tomcat的線程池是最終調(diào)用看到的控制臺輸出的虛擬線程名稱是一個空字符串。所以筆者這里用MethodHandle直接實(shí)例化了默認(rèn)修飾符沒有開放訪問權(quán)限的ThreadPerTaskExecutor類,基于一個自定義的ThreadFactory強(qiáng)制構(gòu)造了一個自定義ThreadPerTaskExecutor實(shí)例。調(diào)用main方法啟動后見控制臺輸出:

這里確認(rèn)了Tomcat啟動完成偵聽127.0.0.1:9091,通過瀏覽器或者POSTMAN發(fā)送任意請求例如http://127.0.0.1:9091/foo就能看到響應(yīng)結(jié)果和控制臺輸出:

這里的Tomcat線程池甚至可以設(shè)計為一個完全自定義的虛擬線程調(diào)度器,可以參考前面一篇文章,這里不再贅述。

暫時無法在SpringBoot體系中使用

由于Servlet規(guī)范問題,Tomcat的升級導(dǎo)致一些接口遷移到jakarta.servlet包中,例如jakarta.servlet.Servlet,此時SpringBoot體系即使是最新版本(當(dāng)前時間為2022-10-07前后,此時最新版本為2.7.4)使用的是還是舊的規(guī)范,對應(yīng)的類是javax.servlet.Servlet,這只是其中一個接口,大部分和HTTP協(xié)議或者Servlet規(guī)范相關(guān)的接口都存在這個包升級不兼容的問題,需要等待SpringBoot升級為embed-tomcat-*-10.1.0+才能適配虛擬線程。

小結(jié)

Demo項(xiàng)目倉庫:

Github:https://github.com/zjcscut/framework-mesh/tree/master/tomcat-virtual-thread

到此這篇關(guān)于在Tomcat中啟用虛擬線程特性的文章就介紹到這了,更多相關(guān)Tomcat啟用虛擬線程內(nèi)容請搜索以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持!

標(biāo)簽: Tomcat
主站蜘蛛池模板: 混合反应量热仪-高温高压量热仪-微机差热分析仪DTA|凯璞百科 | 安徽集装箱厂-合肥国彩钢结构板房工程有限公司 | 步进电机_agv电机_伺服马达-伺服轮毂电机-和利时电机 | 汽车水泵_汽车水泵厂家-瑞安市骏迪汽车配件有限公司 | 浙江栓钉_焊钉_剪力钉厂家批发_杭州八建五金制造有限公司 | 圈酒招商网【jiushuitv.com】_酒水招商_代理_加盟平台 | 干培两用箱-细菌恒温培养箱-菲斯福仪器 | 【铜排折弯机,钢丝折弯成型机,汽车发泡钢丝折弯机,线材折弯机厂家,线材成型机,铁线折弯机】贝朗折弯机厂家_东莞市贝朗自动化设备有限公司 | 升降炉_真空气氛炉_管式电阻炉厂家-山东中辰电炉有限公司 | 多米诺-多米诺世界纪录团队-多米诺世界-多米诺团队培训-多米诺公关活动-多米诺创意广告-多米诺大型表演-多米诺专业赛事 | 世界箱包品牌十大排名,女包小众轻奢品牌推荐200元左右,男包十大奢侈品牌排行榜双肩,学生拉杆箱什么品牌好质量好 - Gouwu3.com | 上海新光明泵业制造有限公司-电动隔膜泵,气动隔膜泵,卧式|立式离心泵厂家 | 超声波成孔成槽质量检测仪-压浆机-桥梁预应力智能张拉设备-上海硕冠检测设备有限公司 | 重庆网站建设,重庆网站设计,重庆网站制作,重庆seo,重庆做网站,重庆seo,重庆公众号运营,重庆小程序开发 | 过跨车_过跨电瓶车_过跨转运车_横移电动平车_厂区转运车_无轨转运车 | 清水混凝土修复_混凝土色差修复剂_混凝土色差调整剂_清水混凝土色差修复_河南天工 | 【铜排折弯机,钢丝折弯成型机,汽车发泡钢丝折弯机,线材折弯机厂家,线材成型机,铁线折弯机】贝朗折弯机厂家_东莞市贝朗自动化设备有限公司 | 千斤顶,液压千斤顶-力良企业,专业的液压千斤顶制造商,shliliang.com | 硫酸钡厂家_高光沉淀硫酸钡价格-河南钡丰化工有限公司 | 浙江红酒库-冰雕库-气调库-茶叶库安装-医药疫苗冷库-食品物流恒温恒湿车间-杭州领顺实业有限公司 | 深圳货架厂_仓库货架公司_重型仓储货架_线棒货架批发-深圳市诺普泰仓储设备有限公司 | 圆盘鞋底注塑机_连帮鞋底成型注塑机-温州天钢机械有限公司 | 蓄电池在线监测系统|SF6在线监控泄露报警系统-武汉中电通电力设备有限公司 | 农产品溯源系统_农产品质量安全追溯系统_溯源系统 | 重庆网站建设,重庆网站设计,重庆网站制作,重庆seo,重庆做网站,重庆seo,重庆公众号运营,重庆小程序开发 | 河南15年专业网站建设制作设计,做网站就找郑州启凡网络公司 | 丁基胶边来料加工,医用活塞边角料加工,异戊二烯橡胶边来料加工-河北盛唐橡胶制品有限公司 | 汽车水泵_汽车水泵厂家-瑞安市骏迪汽车配件有限公司 | 伟秀电气有限公司-10kv高低压开关柜-高低压配电柜-中置柜-充气柜-欧式箱变-高压真空断路器厂家 | 层流手术室净化装修-检验科ICU改造施工-华锐净化工程-特殊科室建设厂家 | 双能x射线骨密度检测仪_dxa骨密度仪_双能x线骨密度仪_品牌厂家【品源医疗】 | 土壤养分检测仪|土壤水分|土壤紧实度测定仪|土壤墒情监测系统-土壤仪器网 | Safety light curtain|Belt Sway Switches|Pull Rope Switch|ultrasonic flaw detector-Shandong Zhuoxin Machinery Co., Ltd | 佛山商标注册_商标注册代理|专利注册申请_商标注册公司_鸿邦知识产权 | 重庆中专|职高|技校招生-重庆中专招生网| 盛源真空泵|空压机-浙江盛源空压机制造有限公司-【盛源官网】 | 数显恒温油浴-电砂浴-高温油浴振荡器-常州迈科诺仪器有限公司 | 上海恒驭仪器有限公司-实验室平板硫化机-小型平板硫化机-全自动平板硫化机 | 商用绞肉机-熟肉切片机-冻肉切丁机-猪肉开条机 - 广州市正盈机械设备有限公司 | 安平县鑫川金属丝网制品有限公司,防风抑尘网,单峰防风抑尘,不锈钢防风抑尘网,铝板防风抑尘网,镀铝锌防风抑尘网 | 加热制冷恒温循环器-加热制冷循环油浴-杭州庚雨仪器有限公司 |