皇冠客服飞机:@seo3687
最近排查一个bug,发现了一系列成心旨好奇羡慕好奇羡慕的东西,对「自界说线程池」、「Jetty线程模子」王人有了一些新的意志。
文化产业的发展,不仅为人们提供了更为丰富的精神食粮,在推动社会主义文化繁荣兴盛等方面也发挥着重要作用。文化的力量已融入经济社会发展的各个方面。文化不仅能引领风尚,化为催人奋进的精神力量,而且能推动发展,造福于民。通过提供精神产品和文化服务,文化消费已经成为经济发展的重要引擎。文化产业正在向国民经济支柱产业阔步迈进,成为扩投资、调结构、促消费、稳增长的新动能。
本文瞻望阅读时辰10分钟,包括:
问题分解 常原宥因筛查 根因与源码分析 最好试验 一些小TIPS 1、问题分解预发环境偶发苦求失败格外,职业端浮现子虚信息为:
Required 威尼斯人骰宝String parameter 'seriesbaid' is not present
对应controller的api为
乍一看,是一个超过简便的格外,苦求参数里面莫得带seriesbaid,导致失败。
然则,经过证据,前端苦求参数依然佩戴了seriesbaid,而况为“偶发失败”,并不是常见的参数传递问题。
2、常原宥因筛查 2.1 网关参数丢失?由于前端苦求到达后端职业中会经过网关,是以一运行怀疑是否网关丢失了传递参数。
经过 调用链分析,在偶发的失败的苦求中,也证据依然传递了querystring。是以网关莫得丢失参数传递。
2.2 稀奇字符导致参数调养失败 ?既然依然传递了querystring到后端职业,那么一种常见的原因,由于queryString中带有稀奇字符而导致知道成queryParam失败了。
会是这个问题吗?
皇冠博彩网站一家注重用户体验用户隐私安全保护博彩平台,网站拥有丰富博彩游戏种类赛事直播,广大博彩爱好者提供优质博彩服务。咱们通过在职业中接管一个spring-web的OncePerRequestFilter,对苦求参数进行打印。
皇冠hg86a
在偶发的失败的苦求中,找到了以下日记
2021-12-29 15:36:05,536 INFO [com.xxx.interceptor.RequestLoggingFilter] - shouldLog - swanparameter:traceId:fb2266d3687911ecb5f3cf045ea19ac3; query:seriesbaid=3FO4K4SLX2IW&x_plugin=custom&x_bz=&locale=zh_CN&x_resourceId=&x_resourceVersion=; parameterMap:{};
比拟缺憾,咱们证据了苦求中照实有querystring而莫得见效知道为queryParam,然则这个querystring中,并莫得盼愿的稀奇字符,讲好奇羡慕好奇羡慕是不错知道见效的。
既然常原宥因无法阐述,只可去源码捞一把了。
2.3 去源码捞一把咱们的汇注容器使用了jetty,是以HttpServletRequest的终了是jetty的Request类。
Request类中,对queryString的知道是在 getParameters() 的时候。
咱们发现,当格外苦求进来的时候,这里的判断
_queryParameter尽然不是null,而是一个空对象。
而盛大苦求,这里判断_queryParameter为null,然后进行知道。
是以,如故要从源码去分析了。
3、根因与源码分析 3.1 _queryParamter为什么不是null了?咱们通过在Request类中缔造多个断点,找到了原因。整理经由如下图所示。
1)同步苦求A快速完成复返。当苦求A进来,在一次Http苦求浪漫后(controller要领复返客户端),会进行相应的recycle()操作,这里包括Requst对象扩充recycle()要领,算帐联系参数,包括_queryParameters。
皇冠分红 2)异步任务延长反应,在recycle()后重新缔造了_queryParameter属性。在苦求A扩充经由中,使用「自界说线程池」异步扩充了一个要领B(要领较慢)。要领B中,从RequestContextHolder中获得了HttpServletRequest,然后通过request.getParameter()获得苦求头。
因为此时_queryParameters为null,因此extractQueryParameters()要领就知道了一个空的对象放进去。
博彩娱乐 皇冠足球投注网 3)新苦求C参预,欧博体育复返格外。当新的苦求C参预后端职业,拿到了并吞个Request对象,由于此时_queryParameters不为null,因此跳过了extractQueryParameters(),导致应该知道的queryString无法被知道,controller抛出格外。
转头:一朝干线程扩充结束,完成recycle经由,而异步线程扩充较慢,异步线程中的任何request.getParameter()行径会碎裂Request对象的recycle,导致_queryParameters属性为空对象而不是null,从而导致新的苦求失败。
3.2 异步线程中,RequestContextHolder还能拿到Request对象?(根蒂原因)咱们知说念RequestContextHolder是基于ThreadLocal终了的。因此,在异步线程中,是无法成功通过
RequestContextHolder.getRequestAttributes()获得干线程的HttpServletRequest。
问题出在了「自界说线程池」
ThreadPoolExecutorWithMonitor中。
电竞里面自界说终昭着一个里面类DecorateRunnableTask来惩办任务。
博彩平台注册送体验金 皇冠信用盘平台里面类DecorateRunnableTask接管了里面类DecorateTask,保存了干线程的RequestAttributes对象。
然后在异步线程扩充前,通过before()要领缔造到了现时哨程的RequestContextHolder中。
转头:给异步线程传递RequestAttributes对象,是形成Request对象泄漏的根蒂原因!
3.3 两个苦求,为什么会分享一个Request对象?蓝本上头的分析基本依然找到了Bug的原因,然则我仔细思了下,又认为有点奇怪。
两个苦求,为什么会分享一个Request对象?
要是是使用了联系池化工夫,那怎样能在两个苦求找到并吞个对象,然后结识复现呢?因此,又继续去商讨了下jetty的联系实质。
jetty 9.x全体架构图:
SelectorManager + ManagedSelector +QueuedThreadPool 构成了「Reactor线程模子」。关于一个http苦求,SelectorManager分拨给某一个ManagedSelector创建HttpConnection对象,然后在QueuedThreadPool中扩充相应的IO操作。
HttpConnection对象合手有HttpChannel对象,HttpChannel中合手有了Request对象(即是HttpServletRequest)。
网关到后端职业之间使用的是Http苦求,默许为长贯穿,因此,在短时辰内的新的苦求(长贯穿浪漫前),会复用并吞个HttpConnection对象。
4、最好试验不要给异步线程传递RequestAttributes对象并进行保存。
要是需要联系苦求参数,不错新建凹凸文对象存储参数后进行传递。八成使用TransmittableThreadLocal。
5、一些小TIPS 5.1 jetty源码不匹配在对jetty的Request类进行debug时,一运行这里碰到一个小坑,idea一直源码匹配不上。从github上把 jetty源码拉下来,按照引入的jetty版块进行土产货mvn install,如故不一致。
把柄pom的依赖分析,不错看到引入的jetty版块为9.4.12。
其后一会儿思起来,这个技俩天然是springboot技俩,然则并不是打成jar包通过内置jetty容器启动的。而是打成了war包,土产货通过jetty-maven-plugin的jetty:run启动的。这里使用的jetty版块为9.4.9。
亚新骰宝是以,咱们需要按照jetty-maven-plugin的版蓝本遴荐jetty的源码。
5.2 「偶提问题」难以复现考虑到篇幅原因与阅读体验,本文在排查经由中,莫得伸开说明一个超过辛苦的所在————土产货怎样结识复现「偶提问题」格外苦求。
着实排查经由中,土产货结识复现虚耗了多半时辰。要是不是土产货不错结识复现,背面的debug也无从谈起。
背面主要把柄代码的近期变更情况,发现了一个异步苦求的引入,将异步改为同步后,发现就不会再出现这个问题了。
是以才从异步苦求起程,屡次尝试后,进行了结识复现。
是以本次排查的一个紧迫成绩,即是关于一些故障的排查,不错考虑从近期的「多样变更」中去寻找印迹。