利用Arthas定位线上问题实例

前言

Arthas是一个类似于Btrace的JVM在线调试分析工具,具体可参考我之前写的一篇博客:利用JVM在线调试工具排查线上问题。本文分享笔者刚遇到的一个问题,虽然不复杂,但是很典型。

问题与分析过程

昨天上线遇到一个问题,交易后给大数据平台异步送数,但是他们说没收到数据,因为我们没有打日志,所以没有直接的证据证明是他们的问题而不是我们的问题。

送数的原理大致如下,就是交易主线程把数据放到队列里,然后异步线程从队列里把数据取出来,发送到后台。

队列:
BlockingQueue<Message> queue = new BlockingQueue();

同步线程:
void sendMsg(Message msg) {
   queue.offer(msg);
}
异步线程:
void consume() {
   Message msg = queue.take();
   while(msg != null) {
       HttpClient.post(msg);
       msg = queue.take();
   }
}

具体送数的代码如下( 加了行数):

38  public void consume(Map msg) {
39        HttpClient httpClient = new HttpClient(cm);
40        PostMethod method = new PostMethod(uri);
41        method.addRequestHeader("context-type", "application/x-www-form-urlencoded");
42        JSONObject json = new JSONObject(msg);
43       NameValuePair[] params = new NameValuePair[2];
44       params[0] = new NameValuePair("topic", topic);
45       params[1] = new NameValuePair("value", json.toJSONString());
46       //System.out.println(msg.toString());
47       logger.info("BigDataHttp Send Json:" + json.toJSONString());
48       method.addParameters(params);
49      try {
50
51         httpClient.executeMethod(method);
52         if(method.getStatusCode() == 200) {
53              logger.info("BigDataHttp response(Success):"+ method.getResponseBodyAsString());
54         } else {
55              logger.info("BigDataHttp Response(error):" + method.getResponseBodyAsString());
56         }
57     } catch(Exception e) {
58         logger.error(e.getMessage(), e);
59     } finally {
60         method.releaseConnection();
61     }
62  }

在日志里没有发现try里的异常,而比较遗憾的是,我们的日志虽然开了info级别,但是因为日志量太大,所以只开了交易上送和下发报文的日志,其他的日志都关了。

现在日志级别没法调,有没有办法能确定,请求返回了200,还是其他值呢?

可以用在线调试工具Arthas,我们使用Arthas的trace功能,查看这个类执行的详细步骤。

首先连接上这个JVM进程,pid为进程号。

java -jar arthas-boot.jar pid 

然后执行命令

trace xxx.util.bigDataUtil.BigDataHttpConsumer consume

这条命令的左右就是,追踪xxx.util.bigDataUtil.BigDataHttpConsumer类里consume方法的执行过程。

执行的结果如下,每一行最后的是代码行数,我们可以看一下,跟上面代码是一一对应的。

从代码中可以看到,如果返回码是200,那么它会执行第52行,如果返回码不是200,会执行55行,因此,我们通过trace功能确定执行了哪条语句,就可以知道到底返回没返回200,从结果来看,确定返回的不是200。

这样我们就有了确定的证据证明发给后台时返回非200,后台同事检查了自己的配置发现配置有误,是他们自己的问题。

原文地址:https://blog.51cto.com/nxlhero/2445610

时间: 2024-11-06 11:22:40

利用Arthas定位线上问题实例的相关文章

微服务中定位线上问题

微服务架构下的程序一般有多个节点提供服务,用户请求不一定落在哪一个节点,如果节点 存在问题,一般利用日志监控系统来确认问题. 日志监控系统提供实时日志,以及全文检索日志,并且日志实时查询以及全文检索查询都要 以倒叙查询. 中间件系统或业务系统对于日志生成的级别,debug.info.error等级别,以及error日志 要打印详细日志栈信息. 通过合理详细的使用日志以及配合日志监控系统的实时日志以及日志检索功能一般能够很快地 定位问题,定位到问题一般就能很快地解决. 错误日志尽量打印栈信息,in

不改一行代码定位线上性能问题

背景最近时运不佳,几乎天天被线上问题骚扰.前几天刚解决了一个 HashSet 的并发问题,周一又来了一个性能问题. 大致的现象是:我们提供出去的一个 OpenAPI 反应时快时慢,快的时候几十毫秒,慢的时候几秒钟才响应. 尝试解决由于这种也不是业务问题,不能直接定位.所以尝试在测试环境复现,但遗憾的测试环境贼快. 没办法只能硬着头皮上了. 中途有抱着侥幸心里让运维查看了 Nginx 里 OpenAPI 的响应时间,想把锅扔给网络.结果果然打脸了:Nginx 里的日志也表明确实响应时间确实有问题.

阿里问题定位神器 Arthas 的骚操作,定位线上BUG,超给力

背景公司有个渠道系统,专门对接三方渠道使用,没有什么业务逻辑,主要是转换报文和参数校验之类的工作,起着一个承上启下的作用. 最近在优化接口的响应时间,优化了代码之后,但是时间还是达不到要求:有一个诡异的100ms左右的耗时问题,在接口中打印了请求处理时间后,和调用方的响应时间还有差了100ms左右.比如程序里记录150ms,但是调用方等待时间却为250ms左右. 下面记录下当时详细的定位&解决流程(其实解决很简单,关键在于怎么定位并找到解决问题的方法) 定位过程分析代码渠道系统是一个常见的spr

jstack定位线上CPU过高问题

top  查看占用资源最高进程的PID jstack -l  pid  >  statck.log   输出线程堆栈信息 top -H -p pid   找出相对应的线程TID printf "%x \n" <tid>  输出十六进制 less  statck.log  查看日志文件,找到线程16进制关键字,上下翻页查看与代码相关的信息,定位代码问题 原文地址:https://www.cnblogs.com/byfboke/p/12681632.html

Android 上千实例源码分析以及开源分析

Android 上千实例源码分析以及开源分析(百度云分享) 要下载的直接翻到最后吧,项目实例有点多. 首先 介绍几本书籍(下载包中)吧. 01_Android系统概述 02_Android系统的开发综述 03_Android的Linux内核与驱动程序 04_Android的底层库和程序 05_Android的JAVA虚拟机和JAVA环境 06_Android的GUI系统 07_Android的Audio系统 08_Android的Video 输入输出系统 09_Android的多媒体系统 10_

利用tinyproxy在Linux上搭建HTTP Proxy Server

之所以需要用到HTTP Proxy Server并不是为了要翻墙,而是为了让没有公网IP地址的内网主机通过有公网IP地址的外网主机访问Internet.举个例子,阿里云ECS在购买时可以不购买公网IP地址,但这种没有公网IP地址的ECS云主机(实例)是没有访问Internet的能力的,也就是说无法在这台实例上下载文件,这在部署应用如部署MySQL时可能遇到无法完成安装问题.解决的办法有两种,一种是在另一台具有公网访问能力的ECS实例上搭建VPN服务,另一种是在另一台具有公网访问能力的ECS实例上

selenium+java利用AutoIT实现文件上传

1.AutoIT介绍 AutoIT是一个类似脚本语言的软件,利用此软件我们可以方便的实现模拟键盘.鼠标.窗口等操作,实现自动化. 2.实现原理 利用AutoIT编写合适的脚本,然后将脚本编译成可执行文件,在自动化实现时,直接调用此脚本实现文件上传. 备注:编写脚本和编译,需要借助AutoIT提供的工具,但是脚本编译成可执行文件后,可以直接使用,不再需要安装AutoIT. 3.自动化调用 AutoIT脚本编译成可执行文件后,放到本地的某一个目录下 自动化实现过程中,需要上传图片时,首先定位到[上传

mysql 利用binlog增量备份,还原实例

mysql 利用binlog增量备份,还原实例 张映 发表于 2010-09-29 分类目录: mysql 一,什么是增量备份 增量备份,就是将新增加的数据进行备份.假如你一个数据库,有10G的数据,每天会增加10M的数据,数据库每天都要备份一次,这么多数据是不是都要备份呢?还是只要备份增加的数据呢,很显然,我只要备份增加的数据.这样减少服务器的负担. 二,启用binlog vi my.cnf log-bin=/var/lib/mysql/mysql-bin.log,如果是这样的话log-bin

利用iframe无刷新上传文件的坑

原文:利用iframe无刷新上传文件的坑 页面里经常要用到文件上传的功能,而且要求页面不刷新,先说一下原理:页面里放一个file控件和submit按钮,外面用form表单包住,给form表单加上对应的属性值,action.method.entype.name,到这一步,能上传文件了,但是这样上传文件会刷新页面,这不是我们想要的.我们要的是文件上传时不刷新页面,那么也简单,在页面里放一个iframe,设置它的宽高为0,这里有两个坑: 1.需要设置iframe的name值与form的target属性