• 记录一次由于线程使用不当引发的血案


    背景

    最近给第三方做了一个接口,接口的作用是接收数据对数据进行验证之后通过kafka推送到模型进行数据处理,最终通过kafka接收模型的数据,开始只做了一个异步的接口,由于对方业务原因需要一个同步的接口传输数据,但是每当运行一段时间之后程序就会进入假死状态,接口无法正常调用;

    同步接口

    同步接口的实现是使用阻塞Map,当对方发送请求时,对数据进行验证,然后推送到模型,等待结果返回之后将处理好的数据推送到对方接口,此时这次请求给调用方返回相应信息;

    思路

    开始认为是由于用户量过大导致内存不足引发的程序假死,使用JMeter进行压力测试异步接口模拟10000个请求同时调用接口,程序如丝滑般运行,没有丝毫问题,所有请求都正常返回(这里由于在家里通过VPN连接的公司开发服务器,网络不稳定,所以就拿少量测试用例为例);

    然后开始怀疑是不是同步接口出了问题,刚开始模拟少量请求,因为当时是在开发环境进行测试,模型并没有放上去,所以没有返回信息,一直在等待模型的返回结果,也是没有问题的,这时候调用异步接口也没有任何问题;

    思考:所有资源都是阻塞状态,因为没有处理结果,一直没有释放进程,当数据过大时会不会造成服务器资源耗尽,导致程序假死?

    当再次加大同步接口的调用次数的时候,再去尝试请求异步接口,发现异步接口也没有了返回信息,这时遍确认了问题所在;

    线程全部在阻塞状态,当太多资源没有释放掉时,服务器资源耗尽,导致程序无法正常运行;

    解决

    找到问题之后就是要解决问题,去掉同步接口是不可能的,所以要给阻塞的线程设置一个超时时间,当长时间没有等到模型的处理数据时,主动放弃监听,释放掉占用的资源,从而保证服务器资源充足;

    思考

    虽然问题解决了,但是模型的数据产出最长达10秒钟,当并发量过大时还是会出现这种问题,在不动模型的情况下如何解决这种问题?如何一直保证服务器资源充足?

    参考资料

    阻塞Map的实现:https://songsong.iteye.com/blog/802881

    压力测试简介和JMeter的简单实用:https://www.cnblogs.com/TankXiao/p/4059378.html

  • 相关阅读:
    WindowsDocker初始化之Hyper-V
    vue cli安装失败,nodejs缺少模块,npm安装报错-之万能重装法则
    企业架构演进
    原生JS实现后端文件流导出Excel(附Node后端代码)
    Git和TortoiseGit安装配置
    SQL Server 单用户多用户模式切换
    Microsoft Visual Studio 2019一些个人初始设置
    腾讯云CentOS 7.6 64位之docker的镜像和容器练习
    腾讯云CentOS 7.6 64位安装docker
    常见的javascript跨站
  • 原文地址:https://www.cnblogs.com/Jacian/p/11386149.html
Copyright © 2020-2023  润新知