欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

使用Arthas 获取Spring ApplicationContext还原问题现场

程序员文章站 2022-04-29 14:25:10
## 背景 最近来了个实习僧小弟,安排他实现对目标网站 连通性检测的小功能,简单讲就是将下边的shell 脚本换成Java 代码来实现 ``` 1#!/bin/bash 2URL="https://www.baidu" 3HTTP_CODE=`curl -o /dev/null -s -w "%{h ......
## 背景 最近来了个实习僧小弟,安排他实现对目标网站 连通性检测的小功能,简单讲就是将下边的shell 脚本换成java 代码来实现 ``` 1#!/bin/bash 2url="https://www.baidu" 3http_code=`curl -o /dev/null -s -w "%{http_code}" "${url}"` 4#echo $http_code 5if [ $http_code != '200' ];then 6curl 'https://oapi.dingtalk.com/robot/send?access_token=xx' \ 7 -h 'content-type: application/json' \ 8 -d '{"msgtype": "text", 9 "text": { 10 "content": "百度平台状态不正常,请注意!" 11 }, 12 "isatall": true 13 }' 14 15fi ``` ## 功能实现 #### 使用spring task ``` 1@scheduled(cron = "0 0 0/1 * * ? ") 2public void startschedule() { 3 log.info("开始执行定时任务 ,检测百度网站连通性"); 4 try { 5 httpresponse response = httprequest.get("").execute(); 6 if (httpstatus.http_ok != response.getstatus()) { 7 this.send2dingtalk(response.getstatus()); 8 } 9 log.info("请求百度成功,返回报文:{}",response.body()); 10 } catch (httpexception e) { 11 log.error("请求异常百度:{}", e); 12 this.send2dingtalk(e.getmessage()); 13 } 14 log.info("执行检测百度网站连通任务完毕"); 15} ``` ## 问题描述 部署在服务器上,我的*io本 都已经呼叫任务状态不正常了,可是小弟的java 代码还是没有执行通知 ![](https://img2018.cnblogs.com/blog/1234351/201908/1234351-20190806220913790-536582331.jpg) - 去翻生产日志,只输入了开始并没有输出定时任务结束,感觉是哪里卡死,想当然以为如果超时总会到catch 逻辑,排查无果 - 由于任务是一小时一次,如何快速触发一下这个异常,还原事故现场 - 由于使用简单的spring task 没有图形化界面和api接口 ## arthas 还原事故现场,重新触发任务 核心拿到 spring context 然后执行它的 `startschedule` 方法 #### 确定监控点 - springmvc 的请求会通过 `requestmappinghandleradapter` 执行`invokehandlermethod` 到达目标接口上进行处理 - 而在 `requestmappinghandleradapter`类中有 getapplicationcontext() ``` 1@nullable 2public final applicationcontext getapplicationcontext() throws illegalstateexception { 3 if (this.applicationcontext == null && this.iscontextrequired()) { 4 throw new illegalstateexception("applicationobjectsupport instance [" + this + "] does not run in an applicationcontext"); 5 } else { 6 return this.applicationcontext; 7 } 8} ``` - 任意执行一次请求获取到 `requestmappinghandleradapter`target 目标,然后执行 `getapplicationcontext` #### tt命令 获取到applicationcontext - arthas 执行 tt ``` 1tt -t org.springframework.web.servlet.mvc.method.annotation.requestmappinghandleradapter invokehandlermethod ``` - 任意执行一次web 请求,tt 即可捕获 ![](https://img2018.cnblogs.com/blog/1234351/201908/1234351-20190806220913920-1288377533.jpg) - 根据目标的索引,执行自定义 ognl 表达式即可 ``` 1tt -i 1019 -w 'target.getapplicationcontext()' ``` ![](https://img2018.cnblogs.com/blog/1234351/201908/1234351-20190806220914149-1040303452.jpg) #### 使用applicationcontext获取 定时任务bean 执行 startschedule ``` 1tt -i 1000 -w 'target.getapplicationcontext().getbean("baiduschedule").startschedule()' ``` ok 任务重新触发了 事故原因调查清楚,由于使用hutool 的工具类 没有设置timeout 导致无限等待,所以没有执行catch 逻辑 ## 总结 以上吓哭实习僧的操作`禁止`生产操作,只是提供个思路 ,当然可以衍生其他业务场景的操作 核心是通过arthas 来抓取spring applicationcontext 对象,然后获取bean 进行执行方法 关于arthas 是alibaba开源的java诊断工具,深受开发者喜爱 欢迎关注我们获得更多的好玩javaee 实践 **推荐阅读:** [《深入理解 java 内存模型》读书笔记](http://mp.weixin.qq.com/s?__biz=mzu0mdewmjgwna==&mid=2247485768&idx=1&sn=baeb6e3e6ce1c22b8b87bbcd1e968152&chksm=fb3f10b3cc4899a51205e06df69bab0632636f13217062eaa6dbe678bc9fe1db883e5f54fe63&scene=21#wechat_redirect) [面试-基础篇](http://mp.weixin.qq.com/s?__biz=mzu0mdewmjgwna==&mid=2247485764&idx=1&sn=418a946e30a9dc1d3166da3d83a90d8d&chksm=fb3f10bfcc4899a92d510f7d2c612536626ead30d4e0ace82e89c50210d4fd09ce48fd924c37&scene=21#wechat_redirect) [spring boot 2.0 迁移指南](http://mp.weixin.qq.com/s?__biz=mzu0mdewmjgwna==&mid=2247485754&idx=1&sn=9158ea22e664aad9972f2582e66a215c&chksm=fb3f10c1cc4899d7ec106aa0c1e7ef4e7217fdf91dd852d5a34b0f3f88c321cf36e03a55c6ec&scene=21#wechat_redirect) [springboot使用docker快速部署项目](http://mp.weixin.qq.com/s?__biz=mzu0mdewmjgwna==&mid=2247485741&idx=1&sn=b048dfa7110ac22b09319af5806a8307&chksm=fb3f10d6cc4899c0338be7ba5c7b63688a8d8c0ce3d2a56d2db387636f9939c2a951f8280c60&scene=21#wechat_redirect) **为什么选择 spring 作为 java 框架?** **springboot rocketmq 整合使用和监控** **spring boot 面试的十个问题** [使用 spring framework 时常犯的十大错误](http://mp.weixin.qq.com/s?__biz=mzu0mdewmjgwna==&mid=2247485793&idx=1&sn=d832f0318916628b8867df21a030adf1&chksm=fb3f109acc48998ced40390c8e01a33c37cb96a06c90b96ba34f81fd51a5aa70ce3792a6847d&scene=21#wechat_redirect) [springboot kafka 整合使用](http://mp.weixin.qq.com/s?__biz=mzu0mdewmjgwna==&mid=2247485807&idx=1&sn=846306cd5115e3bd16dd2c999db84f16&chksm=fb3f1094cc489982f3857fc2116723bb916f6790ba3f407d4fa5282dab4252d9129c8a3098f9&scene=21#wechat_redirect) [springboot rabbitmq 整合使用](http://mp.weixin.qq.com/s?__biz=mzu0mdewmjgwna==&mid=2247485812&idx=1&sn=fdc6770c4179cfda2899dfe62a6067b8&chksm=fb3f108fcc4899998ebea903eda1d89f502893a372b108f63591156efa62d650fbeef5df7bc7&scene=21#wechat_redirect) **上篇好文:** [如何优雅关闭 spring boot 应用](http://mp.weixin.qq.com/s?__biz=mzu0mdewmjgwna==&mid=2247485843&idx=1&sn=fe2a8844e807e4a8a71cc62a2fc08f1e&chksm=fb3f1068cc48997e0eaedc18a4d307d49f36b20caca573ff6b5bdc11265f8115b35e913bb98c&scene=21#wechat_redirect) ![](https://img2018.cnblogs.com/blog/1234351/201908/1234351-20190806220914350-1746984740.jpg)