千家信息网

服务器故障实例分析

发表于:2024-09-22 作者:千家信息网编辑
千家信息网最后更新 2024年09月22日,这篇文章主要介绍"服务器故障实例分析"的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇"服务器故障实例分析"文章能帮助大家解决问题。1. 出故障了没办法,干it这一
千家信息网最后更新 2024年09月22日服务器故障实例分析

这篇文章主要介绍"服务器故障实例分析"的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇"服务器故障实例分析"文章能帮助大家解决问题。

1. 出故障了

没办法,干it这一行,就得天天面对故障,大家就是传说中的消防员,到处救火。不过,这次的故障范围有点大,宿主机都打不开了。

好在监控系统留下了一些证据。

证据发现,机器的CPU、内存、文件句柄,随着业务的增长,持续的上升...上升....,直到监控也无法将信息收集上来。

要命的是,这些宿主机上,部署了非常多的Java进程。没别的原因,就是为了节省成本,混部了应用。当宿主机表现出整体性的异常时,就难以找到罪魁祸首。

因为远程登录也Over,暴躁的运维只能重启机器,重启机器之后开始重启应用。经过漫长的等待,所有的进程都活了,但是,仅仅过了片刻,宿主机又立即死去。

业务一直处于死翘翘的状态,真是让人恼火啊。也让人心急。尝试过几次之后,运维崩溃了,启动了紧急预案:回滚!

最近的上线记录有点多,而且有开发人员私自上线部署的行为,运维蒙圈了:回滚哪些呢?还好有人脑瓜一亮,想起了还有find这个命令,那就找到最近更新的所有jar包,都给它来次回滚吧。

find /apps/deploy -mtime +3 | grep jar$

如果你不知道find这个命令,那可还真的是一场灾难。还好有人知道。

把十来个jar包回滚,还好没有碰到数据库的schema变更,系统终于正常运行了。

2. 找原因

没别的办法,查日志,进行代码审查。

代码审查要追溯到最近1周或者2周之内的代码改动,因为有些功能代码要沉淀一段时间,才能到线上风光一把。

看着满屏的提交记录"OK",技术经理的脸都绿了。

"xjjdog说过,《80%的程序员,不会写commit记录》,我看你们是100%都不会写"。

大家都静悄悄的,忍着痛翻查历史变更。经过大家的不懈努力,终于在屎山之间,找到了一些问题代码。CxO亲自建了个群,大家一股脑的把可能会出问题的代码,扔到了群里面。

"系统服务中断了接近一个小时,影响非常恶劣",CxO说,"务必把问题彻底解决掉,这个问题投资人非常关注"!

okokok,有了钉钉的助力,大家的手势都变得整齐划一。

3. 线程池的参数

代码有点多,大家对问题代码讨论了老久。包括一些使用并行流的,还有套在lamba表达式里的炫技代码,还重点排查了一些线程池的使用代码。

最后大家决定还是对线程池的代码再过一遍。其中有一段是这么写的。

RejectedExecutionHandler handler = new ThreadPoolExecutor.DiscardOldestPolicy(); ThreadPoolExecutor executor = new ThreadPoolExecutor(100,200,                 60000,                 TimeUnit.MILLISECONDS,                 new LinkedBlockingDeque<>(10),                 handler);

还别说,参数有模有样的,甚至考虑到了拒绝策略。

Java的线程池,使得编程变的非常简单。它有很多参数,如上图,我们一一介绍一下,否则代码是无法审查的。

  • corePoolSize:核心线程数,核心线程创建后会一直存活

  • maxPoolSize:最大线程数

  • keepAliveTime:线程空闲时间

  • workQueue:阻塞队列

  • threadFactory:线程创建工厂

  • handler:拒绝策略

下面来介绍一下它们的关系。

当线程数小于核心线程数的时候,有新的任务到来,将会生成一个新的线程进行服务。当当前线程数大于核心线程数,而且阻塞队列未满的时候,将会把任务放在阻塞队列中。当线程数大于核心线程数,而且阻塞队列满了的时候,将会创建新的线程进行服务,直到线程数到达maximumPoolSize的大小。此时,如果还有新的任务,将触发拒绝策略。

再说一下拒绝策略。jdk默认实现了4种策略,默认实现的是AbortPolicy,也就是直接抛出异常。下面介绍其他几种。

  • DiscardPolicy 比abort更加激进,直接丢掉任务,连异常信息都没有

  • CallerRunsPolicy 由调用的线程来处理这个任务。比如一个web应用中,线程池资源占满后,新进的任务将会在tomcat线程中运行。这种方式能够延缓部分任务的执行压力,但在更多情况下,会直接阻塞主线程的运行

  • DiscardOldestPolicy 丢弃队列最前面的任务,然后重新尝试执行任务

这段线程池的代码是新加的,参数设置还算正常,并没有什么大的问题。唯一有可能的风险,就是使用DiscardOldestPolicy 的拒绝策略。当任务非常多的时候,这个拒绝策略会造成任务排队,请求超时。

当然不能放过这种风险,说实话也是到现在为之能够找到的最可能的风险代码了。

"把DiscardOldestPolicy 改成默认的AbortPolicy吧,重新打包上线一下试试"。技术大牛在群里说。

4. 问题在哪里?

结果,服务灰度上线之后,宿主机不多时,就死掉了。是它的原因没跑了,但是why?

线程池的大小 ,最小100,最大200,说什么也不过分。阻塞队列的容量只有10,说什么也不会造成问题。你要说是这个线程池造成的原因,打死我都不信。

但是业务部门反馈,这段代码加上就死,不加就没事。技术大牛们抓耳挠腮百思不得其姐。

到最后,终于有人忍不住了,下载下业务的代码打算调试一下。

当他打开Idea的时候,瞬间懵逼了,又瞬间领悟了。他终于明白了这段代码为什么会产生问题了。

线程池,竟然是在方法里创建的!

当每一个请求到来的时候,它都会创建一个线程池,直到系统再也无法分配资源为止。

可真是霸道啊。

所有人都在关注线程池的参数是怎么设置的,但从来没有人怀疑这段代码所在的位置。

关于"服务器故障实例分析"的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识,可以关注行业资讯频道,小编每天都会为大家更新不同的知识点。

线程 代码 任务 问题 服务 策略 故障 时候 队列 阻塞 参数 宿主 核心 业务 原因 宿主机 系统 实例 实例分析 服务器 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 服务器接口并发限制 网络安全维护都有哪些方法 危害网络安全属于危害公共安全吗 移动互联网未来科技 好口碑的软件开发公司 安卓的软件开发多少钱 网络安全建设新趋势 浪潮服务器启动后显示二条杠 杭州数字多媒体软件开发 网络技术专业如何写简历 初中毕业学计算机网络技术 免费svn服务器 汕头市华辰网络技术有限公司 gis技术与gis软件开发 怎么在数据库清空用户密码 mc服务器地图获取 中国数据库40年发展简史 安卓软件开发用框架吗 上海市乐虞网络技术有限公司 服务器搭建视频云点播 为切实加强网络安全 未来网络技术发展与展望 安徽服务器机柜批发商 河北智慧校园管理平台软件开发 华文字体软件开发 实用计算机网络技术结课作业 系统服务器停机时间8.5小时 软件开发需要成本 曲阜兴成网络技术服务中心 游戏数据库技术技巧
0