带你读《Apache Tomcat的云原生演进》——Tomcat的技术内幕和在喜马拉雅的实践(2)

本文涉及的产品
应用实时监控服务-可观测链路OpenTelemetry版,每月50GB免费额度
服务治理 MSE Sentinel/OpenSergo,Agent数量 不受限
容器镜像服务 ACR,镜像仓库100个 不限时长
简介: 带你读《Apache Tomcat的云原生演进》——Tomcat的技术内幕和在喜马拉雅的实践(2)

带你读《Apache Tomcat的云原生演进》——Tomcat的技术内幕和在喜马拉雅的实践(1)https://developer.aliyun.com/article/1377542


一般情况下,app发一个请求过来,你的包可能是完整的,但如果发一半过来,这个请求行可能是不完整的,这个时候它是不会阻塞的,它就会注册一个读事件读剩余的。读完请求行以后,它会继续解析头。解析头和解析行是一样的,也是不会阻塞。只需要配置好头的大小,它就会按照头的大小读。

 

因为Tomcat里有很多filterservlet,然后我们自己做了一些路由,去匹配filterservlet。一般我们这里处理完以后,我们就会去读它的body,但它和请求行、请求头不一样,它会阻塞。所以如果body不完整,比如content-length1000body只读到500,就会阻塞在Catalina work线程。这个时候它会通过增加一个wait,等到下次Poller线程来唤醒Catalina work线程。

 

image.png 

 

前面介绍了NIO模型主要分为三个部分Accept线程,Poller线程,Catalina work线程。

 

目前Tomcat已经支持了NIO2,它和NIO有一个很大的不同,中间没有Accept线程,Poller线程,它把NIO模式简化了。所以很多人说NIO2是异步的,但其实也不是,它只是基于自己的JDK实现epollAPI进行步模拟的。

 

NIO2在事件可读的时候会告诉操作系统,然后我这个时候就返回去做其他事情了。操作系统会把数据读到我的包里,然后告诉我可以用数据了,我就直接数据就行了。而NIO同步要发几个读,我需要自己触发操作系统去copy数据过来。然后我还需要在这里等着,等copy完了,再去把数据读出来,是会阻塞在这里的。

 

NIO2并不是真正的NIO,它的API使用机制模拟会告诉你读和写都完成了,所以整个模型是一个EPoller线程。它相当于直接操作EPoller wait,只要线程有事件来,它就会生成连接事件,读/写事件,他这里有一个队列,只要有事件就会一直读,不会说新建一个连接事件,我就处理读事件,它会把所有完整的事件先读出来。

 

读完以后就可以去处理了,如果是连接,我就执行accept这个操作,把连接读出来。接受连接不像NIO是单路线,有一个区别是,一般连接是有限制的,默认是1万。如果你是-1或者是没有限制的,accept就一直不会阻塞。如果是有限制,可能达到目标就会阻塞。

 

所以这个时候就会有两个不同的处理方式,如果是有限制的,不会用当前的Poller线程去做accept的操作,它会新提交一个任务到线程池里,让后面接着做accept的连接,因为不能阻塞Poller线程。

 

如果当时我是个读事件的话,我只要读出来就能提交给Catalina work线程,这个时候读是由Poller线程完成的。

 

假如我新建一个连接,做了三次握手,但是我不给你发数据。那么Poller线程就读不到数据,因此也就不会做处理。它只是注册一个事件到Poller线程,等数据来了再来读。还是和之前的不同,不会像NIO一样,刚开始肯定要去注册一个读事件。NIO2会直接读,一般很多的网络框架优化都是在这个地方做的。我是直接尝试读,不会去注册读事件。因为大部分情况下建立连接以后,后面就会发现不需要去做读事件的操作。因为你做一个读事件,这个读事件就会系统调用,就会涉及到上下文切换的开销

 

我一直在这里习惯用select,有事件就EPoll这个地方,没有就阻塞就EPoll这个地方。EPoller线程就是做这个事情。刚刚我们接触的连接它也是通过Catalina work线程,它们起来的时候可以添加一个accept task,就是先让你接受请求。

 

image.png

它和刚才说的读body一样,当body不够的时候,才会去注册一个事件到Epoller线程上去,它的读也是阻塞的。

 

NIOCatalina不一样的是,它只负责读和写,比NIO少了注册事件的操作。


带你读《Apache Tomcat的云原生演进》——Tomcat的技术内幕和在喜马拉雅的实践(3)https://developer.aliyun.com/article/1377540

相关文章
|
3月前
|
运维 监控 Cloud Native
【云故事探索】NO.17:国诚投顾的云原生 Serverless 实践
国诚投顾携手阿里云,依托Serverless架构实现技术全面升级,构建高弹性、智能化技术底座,提升业务稳定性与运行效率。通过云原生API网关、微服务治理与智能监控,实现流量精细化管理与系统可观测性增强,打造安全、敏捷的智能投顾平台,助力行业数字化变革。
【云故事探索】NO.17:国诚投顾的云原生 Serverless 实践
|
3月前
|
消息中间件 OLAP Kafka
Apache Doris 实时更新技术揭秘:为何在 OLAP 领域表现卓越?
Apache Doris 为何在 OLAP 领域表现卓越?凭借其主键模型、数据延迟、查询性能、并发处理、易用性等多方面特性的表现,在分析领域展现了独特的实时更新能力。
373 9
|
3月前
|
运维 监控 Cloud Native
【云故事探索】NO.17:国诚投顾的云原生 Serverless 实践
通过与阿里云深度合作,国诚投顾完成了从传统 ECS 架构向云原生 Serverless 架构的全面转型。新的技术架构不仅解决了原有系统在稳定性、弹性、运维效率等方面的痛点,还在成本控制、API 治理、可观测性、DevOps 自动化等方面实现了全方位升级。
|
5月前
|
Kubernetes Cloud Native 安全
云原生机密计算新范式 PeerPods技术方案在阿里云上的落地和实践
PeerPods 技术价值已在阿里云实际场景中深度落地。
|
5月前
|
Kubernetes Cloud Native 安全
云原生机密计算新范式 PeerPods 技术方案在阿里云上的落地和实践
PeerPods 技术价值已在阿里云实际场景中深度落地。
|
1月前
|
人工智能 Cloud Native 算法
拔俗云原生 AI 临床大数据平台:赋能医学科研的开发者实践
AI临床大数据科研平台依托阿里云、腾讯云,打通医疗数据孤岛,提供从数据治理到模型落地的全链路支持。通过联邦学习、弹性算力与安全合规技术,实现跨机构协作与高效训练,助力开发者提升科研效率,推动医学AI创新落地。(238字)
|
2月前
|
消息中间件 监控 Java
Apache Kafka 分布式流处理平台技术详解与实践指南
本文档全面介绍 Apache Kafka 分布式流处理平台的核心概念、架构设计和实践应用。作为高吞吐量、低延迟的分布式消息系统,Kafka 已成为现代数据管道和流处理应用的事实标准。本文将深入探讨其生产者-消费者模型、主题分区机制、副本复制、流处理API等核心机制,帮助开发者构建可靠、可扩展的实时数据流处理系统。
342 4
|
3月前
|
弹性计算 运维 Cloud Native
【云故事探索】NO.17:国诚投顾的云原生Serverless实践
简介: 通过与阿里云深度合作,国诚投顾完成了从传统 ECS 架构向云原生 Serverless 架构的全面转型。新的技术架构不仅解决了原有系统在稳定性、弹性、运维效率等方面的痛点,还在成本控制、API 治理、可观测性、DevOps 自动化等方面实现了全方位升级。
141 1
|
2月前
|
存储 弹性计算 Cloud Native
云原生数据库的演进与应用实践
随着企业业务扩展,传统数据库难以应对高并发与弹性需求。云原生数据库应运而生,具备计算存储分离、弹性伸缩、高可用等核心特性,广泛应用于电商、金融、物联网等场景。阿里云PolarDB、Lindorm等产品已形成完善生态,助力企业高效处理数据。未来,AI驱动、Serverless与多云兼容将推动其进一步发展。
187 8
|
7月前
|
运维 Cloud Native 测试技术
极氪汽车云原生架构落地实践
随着极氪数字业务的飞速发展,背后的 IT 技术也在不断更新迭代。极氪极为重视客户对服务的体验,并将系统稳定性、业务功能的迭代效率、问题的快速定位和解决视为构建核心竞争力的基石。

推荐镜像

更多