栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Tomcat源码分析

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Tomcat源码分析

接口偶发报错缺少必填参数,经过排查分析,发现报错缺少参数时,其实客户端是传了参数的。

经过分析发现,这种现象是把HttpServletRequest对象传到了异步线程中使用引起的。

Request对象是tomcat创建的,用于封装一次http请求相关的信息,当一次请求结束后,Request对象并不会被销毁,Request对象会被回收,tomcat只是把Request对象中的所有属性重置为初始状态,清空参数,然后放入队列,供其他请求使用。

tomcat源码分析

tomcat 包含三种 EndPoint:

org.apache.tomcat.util.net.NioEndpoint.java
org.apache.tomcat.util.net.JIoEndpoint.java
org.apache.tomcat.util.net.AprEndpoint.java

EndPoint 用于接受客户端 socket 请求(由内部类 Poller 完成),然后对 Socket 进行简单处理(由内部类 SocketProcessor 完成),接着转交给对应的 ProtocolProcessor 进行处理,封装成 request,通过各个Container 后 到达 servlet。

Processor回收栈

每次处理客户端请求,会先从Processor回收栈(recycleProcessors)中pop出一个processor对象,如果没取到,则会创建一个Processor。(Processor回收栈的默认大小是200,可通过max_connection参数调整)

 

首次创建processor

每创建一个Processor对象,会同时创建一个Request、Response对象,Processor对象和Request、Response是一一对应的。(所以Request对象是跟随Processor对象进行回收并循环复用的)

 

 

请求处理结束,释放processor资源

 

 

回收资源

 

 

 

request.getParameter()方法,会判断是否解析过参数,第一次调用该方法,会解析参数(byte转成String),然后放到paramHashValues中,后面通过getParameter获取参数会去paramHashValues中取。

 

当一次请求结束后,本次请求的Processor对象中的所有元素属性(包括request、response等)会重置,然后Processor对象会push进入processor回收栈,供下次请求使用。

如果把Request对象传入了异步线程,异步线程执行比较慢时,会出现Processor对象已经放入回收栈中,下一次请求拿到了这个Processor对象,并使用其中的Request对象,在通过Request对象取参数前,异步线程中通过Request.getParameter获取参数,此时,会把didQueryParameters置为true,

而此时新的请求中还没有执行到给Request对象赋值,此时就出现获取不到参数的现象。

本地模拟异步传递Request对象的场景进行debug验证

把Request对象传入异步线程,异步线程sleep10秒(确保同步请求处理结束),然后通过Request对象获取参数。

预期结果:等待10秒待异步线程获取Request中的参数后,再通过postman请求该接口,此时会报缺少参数异常。

由于本地调试每次只发1个请求,所以第一次访问接口新建Processor对象以及Request对象,后续请求都是使用的第一次请求创建的Processor。

出现缺少参数异常时,getParameter查询到的数据

 

 

 

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1004300.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号