使用Arthas 获取Spring ApplicationContext还原问题现场
## 背景
最近来了个实习僧小弟,安排他实现对目标网站 连通性检测的小功能,简单讲就是将下边的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}
```
## 问题描述
部署在服务器上,我的老jio本 都已经呼叫任务状态不正常了,可是小弟的Java 代码还是没有执行通知

- 去翻生产日志,只输入了开始并没有输出定时任务结束,感觉是哪里卡死,想当然以为如果超时总会到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 即可捕获

- 根据目标的索引,执行自定义 OGNL 表达式即可
```
1tt -i 1019 -w 'target.getApplicationContext()'
```

#### 使用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)

使用Arthas 获取Spring ApplicationContext还原问题现场的更多相关文章
- 获取spring applicationcontext数据连接connection
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); ...
- spring获取webapplicationcontext,applicationcontext几种方法详解
法一:在初始化时保存ApplicationContext对象代码: ApplicationContext ac = new FileSystemXmlApplicationContext(" ...
- 获取Spring的上下文环境ApplicationContext的方式
摘自: http://blog.csdn.net/yang123111/article/details/32099329 获取Spring的上下文环境ApplicationContext的方式 Web ...
- 获取spring的ApplicationContext几种方式【转】
转自:http://blog.sina.com.cn/s/blog_9c7ba64d0101evar.html Java类获取spring 容器的bean 常用的5种获取spring 中bean的方式 ...
- 【Spring学习笔记-3.1】让bean获取spring容器上下文(applicationContext.xml)
*.hl_mark_KMSmartTagPinkImg{background-color:#ffaaff;}*.hl_mark_KMSmartTagBlueImg{background-color:# ...
- 【spring框架】spring获取webapplicationcontext,applicationcontext几种方法详解--(转)
方法一:在初始化时保存ApplicationContext对象代码:ApplicationContext ac = new FileSystemXmlApplicationContext(" ...
- spring获取webapplicationcontext,applicationcontext几种方法详解(转)
方法一:在初始化时保存ApplicationContext对象 代码: ApplicationContext ac = new FileSystemXmlApplicationContext(&quo ...
- 7 -- Spring的基本用法 -- 4... 使用 Spring 容器:Spring 容器BeanFactory、ApplicationContext;ApplicationContext 的国际化支持;ApplicationContext 的事件机制;让Bean获取Spring容器;Spring容器中的Bean
7.4 使用 Spring 容器 Spring 有两个核心接口:BeanFactory 和 ApplicationContext,其中ApplicationContext 是 BeanFactory ...
- spring获取webapplicationcontext,applicationcontext几种方法详解(转载)
转载自 http://www.blogjava.net/Todd/archive/2010/04/22/295112.html 方法一:在初始化时保存ApplicationContext对象 代码: ...
随机推荐
- MYSQL事务之Yii2.0商户提现
我是一个半路出家的PHP程序员,到目前为止,不算在培训班学习的时间,已经写代码整整两年了.可能由于工作业务的原因,在这两年中我没有用到过MySQL事务.就在昨天有个关于支付宝转账的业务不得不使用MyS ...
- 设计模式-简单工厂模式(SimpleFactory)
简单工厂模式又叫静态工厂模式,,通过定义一个类(FruitFactory)来负责创建其他类的实例,被创建的实例通常都具有相同的父类(Fruit). 角色和职责: 1.工厂角色(Factory)-Fru ...
- Hive入门(三)分桶
1 什么是分桶 上一篇说到了分区,分区中的数据可以被进一步拆分成桶,bucket.不同于分区对列直接进行拆分,桶往往使用列的哈希值进行数据采样.在分区数量过于庞大以至于可能导致文件系统崩溃时,建议使用 ...
- Codeforces 730J:Bottles(背包dp)
http://codeforces.com/problemset/problem/730/J 题意:有n个瓶子,每个瓶子有一个当前里面的水量,还有一个瓶子容量,问要把所有的当前水量放到尽量少的瓶子里至 ...
- POI 设置Excel单元格背景色(setFillForegroundColor)
背景介绍:使用Java开发信息系统项目,项目中往往会涉及到报表管理部分,而Excel表格首当其冲称为最合适的选择,但是对单元格操作时对于设置单元格的背景颜色却很少提及,本文旨在方便单元格背景颜色设计. ...
- Maven发布项目到Nexus私服中 (发布jar包)
目录 1 需求说明 2 实现步骤 2.1 Maven服务的setting.xml文件 2.2 项目的pom.xml文件 2.3 发布项目 1 需求说明 开发完项目后, 将项目版本发布到Nexus私服中 ...
- PTP 接线方式及通讯距离
PTP 接线方式 CB 1241 RS485 接线 (6ES7 241 1CH30-1XB0) CB1241 RS485 信号板(安装在CPU机本体上) ,订货号为: 6ES7 241 1CH30-1 ...
- Salesforce Admin篇(二) Report
针对salesforce系统也好,针对其他的平台系统也好,对于business user的需求以及疑问,数据往往决定了答案.业务人员提出了某些疑问,管理员需要根据需求的分析转换成数据的分析及过滤从而反 ...
- django项目中遇到要实现定时任务
django项目中遇到要实现定时任务,所以选用了简单易用的django-crontab插件. 1.安装 django-crontab pip install django-crontab 2.定时要执 ...
- .NET Core 学习资料精选:入门
开源跨平台的.NET Core,还没上车的赶紧的,来不及解释了-- 本系列文章,主要分享一些.NET Core比较优秀的社区资料和微软官方资料.我进行了知识点归类,让大家可以更清晰的学习.NET Co ...