midwayjs / midway

🍔 A Node.js Serverless Framework for front-end/full-stack developers. Build the application for next decade. Works on AWS, Alibaba Cloud, Tencent Cloud and traditional VM/Container. Super easy integrate with React and Vue. 🌈
https://www.midwayjs.org/
MIT License
7.4k stars 577 forks source link

passport-jwt在某种情况下异常卡死 #3293

Closed minefujiko9293 closed 1 year ago

minefujiko9293 commented 1 year ago

今天遇到个奇怪的问题,使用passport-jwt时,在遇到接口请求并发时,会导致某个线程的接口队列无法请求。 当时是有个前端页面,created时同时请求几个接口,发现接口全部挂起,F12面板中请求的耗时全卡在连接时耗上, 然后我使用接口压测工具,开启多线程,模拟同时访问接口时,也出现了某个线程组的接口无法连通。

我使用的strategy如下: image

主要是在validate中,我对payload中的信息进一步执行查表工作。 image 这个情况下就会发生上述情况,注释掉这些查表工作直接 return payload就不会出现。 检查代码也看不出异常。。。。

然后我又重新写了个中间件,直接使用文档里面的jwt而不是passport-jwt, 同样执行了查表工作,但这次他并不会发生上述卡死的现象。 image image

真的是郁闷了,不知道什么原因哈

minefujiko9293 commented 1 year ago

省流版: 采用passport-jwt时,在validate中执行了查表工作,导致接口并发时的卡死现象,validate中不执行查表工作则不会。 采用jwt时,在中间件resolve实现相同的逻辑,并发时不会卡死,一切正常。 问:passport-jwt是怎么了= =

czy88840616 commented 1 year ago

我理解下,高并发使用 passport-jwt 能复现卡死,而使用中间件不会?

minefujiko9293 commented 1 year ago

我理解下,高并发使用 passport-jwt 能复现卡死,而使用中间件不会?

在我目前的项目是这样的,就像我说的,直接使用jwt写中间件,即使里面执行查表工作,也不会造成压测线程组卡死

但是使用passport-jwt(在validate中执行查表工作)的中间件就会卡死。 validata中不执行查表工作就不会

czy88840616 commented 1 year ago

必现么? 拿 sqlite 写个简单的demo ?

minefujiko9293 commented 1 year ago

必现么? 拿 sqlite 写个简单的demo ?

正在新建项目测试,晚点回复

minefujiko9293 commented 1 year ago

必现么? 拿 sqlite 写个简单的demo ?

测试了,目前就是只要validata中执行了typeorm的相关查询,必定卡死线程。 我分别测试了mysql和oracle的实体,都会。

实体: image

validata: image

压测: image 压测结果:一直运行中,而且只有部分线程组跑完,这里我设了2组,一组跑完,一组一直卡住。 image

minefujiko9293 commented 1 year ago

必现么? 拿 sqlite 写个简单的demo ?

这次我更简单的,只用了注入的redis,也是同样卡死。 image

好像和Inject有关的调用都会卡死?

czy88840616 commented 1 year ago

Strategy是单例,初始化就会注入完成了,不会每次请求再注入的,可以试试去掉这些,加点异步的逻辑看看。

minefujiko9293 commented 1 year ago

写一个简单await Promise,发现有2种情况。 里面有异步的会卡死,里面代码纯同步的不会卡死 image

minefujiko9293 commented 1 year ago

Strategy是单例,初始化就会注入完成了,不会每次请求再注入的,可以试试去掉这些,加点异步的逻辑看看。

有进展了吗 这个bug

czy88840616 commented 1 year ago

测试local和jwt都没有发现这个问题,你是不是把中间件放到全局了?

minefujiko9293 commented 1 year ago

测试local和jwt都没有发现这个问题,你是不是把中间件放到全局了?

是全局的, 要模拟同时调用才会出现哦 正常单个接口掉没问题的

czy88840616 commented 1 year ago

有忽略登录和不需要拦截的路由么?

minefujiko9293 commented 1 year ago

有忽略登录和不需要拦截的路由么?

有的

ignore = [ /^(?!\/admin\/).*$/, // 不以/admin/开头的所有路由

'/admin/sys/user/login',
'/admin/sys/user/login_by_cert',

];

czy88840616 commented 1 year ago

image

并发10,并未复现。

minefujiko9293 commented 1 year ago

@czy88840616

我又新建了个新的简洁项目,完全无额外的引入了,还是复现了呀!!。。郁闷。 nodejs -v 14.16.0

image

ab测试:

线程-c 1时,结果正常 image


线程 -c 大于1时,还是出现了卡死 timeout现象。 image

czy88840616 commented 1 year ago

提交demo呗

minefujiko9293 commented 1 year ago

@czy88840616 demo https://api.zshuizhi.com/midway-test.rar

czy88840616 commented 1 year ago

请求参数是?

minefujiko9293 commented 1 year ago

请求参数是?

demo中是简洁项目呀。 直接测home.controller中方法就能复现。

先调 '/jwt' 获取jwt, 再添加header 多线程测试 '/'路由即可 image

czy88840616 commented 1 year ago

能复现了,表现看起来是其中一个并发被hang住或者其他原因。

minefujiko9293 commented 1 year ago

能复现了,表现看起来是其中一个并发被hang住或者其他原因。

@czy88840616 嗯嗯,暂时可以用普通jwt中间件解决哈。 就是怕别人踩坑。 感觉挺容易中招的,因为我就是发现前端开发的页面中,接口访问不正常。 在页面created中异步请求多个接口是很普遍的现象啦。。

czy88840616 commented 1 year ago

问题已定位修复。

czy88840616 commented 1 year ago

https://github.com/midwayjs/midway/releases/tag/v3.12.7

minefujiko9293 commented 1 year ago

got it!3q

github-actions[bot] commented 10 months ago

This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.