background
Recently, a young monk intern has arranged for him to implement the small function of testing the connectivity of the target website. Simply speaking, the shell script below will be replaced by Java code to achieve it.
#!/bin/bash URL="https://www.baidu" HTTP_CODE=`curl -o /dev/null -s -w "%{http_code}" "${URL}"` #echo $HTTP_CODE if [ $HTTP_CODE != '200' ];then curl 'https://oapi.dingtalk.com/robot/send?access_token=xx' \ -H 'Content-Type: application/json' \ -d '{"msgtype": "text", "text": { "content": "Baidu platform status is not normal, please note!" }, "isAtAll": true }' fi
Functional realization
Using spring task
@Scheduled(cron = "0 0 0/1 * * ? ") public void startSchedule() { log.info("Start executing timed tasks to test Baidu's website connectivity"); try { HttpResponse response = HttpRequest.get("").execute(); if (HttpStatus.HTTP_OK != response.getStatus()) { this.send2DingTalk(response.getStatus()); } log.info("Request Baidu to succeed, return message:{}",response.body()); } catch (HttpException e) { log.error("Request Abnormal Baidu:{}", e); this.send2DingTalk(e.getMessage()); } log.info("Complete the task of testing Baidu's website connectivity"); }
Problem Description
Deployed on the server, my old jio had already called the task status abnormal, but my younger brother's Java code still did not execute the notification.
- To turn over the production log, only input the beginning and not output the end of the timed task, feel where the stuck, assume that if the timeout will always go to the catch logic, the search is fruitless.
- Since the task is once an hour, how to quickly trigger the exception and restore the accident scene
- Because there is no graphical interface and API interface with simple Spring Task
Arthas restores the accident scene and re-triggers the task
The core takes spring context and executes its startSchedule method
Identifying monitoring points
- Spring MVC requests are processed through the Request Mapping Handler Adapter to invokeHandler Method to the target interface.
- In the RequestMappingHandlerAdapter class, there is getApplicationContext ()
@Nullable public final ApplicationContext getApplicationContext() throws IllegalStateException { if (this.applicationContext == null && this.isContextRequired()) { throw new IllegalStateException("ApplicationObjectSupport instance [" + this + "] does not run in an ApplicationContext"); } else { return this.applicationContext; } }
- Arbitrarily execute a request to get the RequestMapping Handler Adapter target, and then execute getApplication Context
The tt command gets the Application Context
- arthas performs tt
tt -t org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter invokeHandlerMethod
-
If a web request is executed arbitrarily, tt can be captured
-
According to the index of the target, execute the custom OGNL expression.
tt -i 1019 -w 'target.getApplicationContext()'
Use Application Context to get the timed task bean to execute startSchedule
tt -i 1000 -w 'target.getApplicationContext().getBean("baiduSchedule").startSchedule()'
ok task triggered again
Investigation of the cause of the accident is clear, because the tool class using hutool does not set timeout, resulting in unlimited waiting, so the catch logic is not executed.
summary
- The above operations of frightening and crying interns prohibit production operations, but only provide a way of thinking, of course, can be derived from other business scenarios of operation.
- The core is to grab the Spring Application Context object through Arthas, and then grab the bean to execute the method.
- About Arthas Alibaba is an open source Java diagnostic tool that is popular with developers
-
Welcome to our more fun Java EE practices :