最近帮新来的校招同窗排查一个线上问题,问题自己不是很难,可是过程当中踩到了一个arthas的坑,挺有意思的。css
同时,也分享下在排查过程当中使用的一些比较实用的工具,包括tcpdump、arthas、simpleHTTPServer等,但愿能对你们有所帮助。html
新开发的一个功能,简单来讲,就是读取数据库的数据展现在前台。java
本地启动服务调试,用postman调用api,返回数据显示正常,数据中的中文也正常。python
可是部署到线上环境后,经过chrome浏览器调用和postman调用接口,返回的非中文数据正常,可是中文显示乱码。linux
这个问题的第一反应是请求的content-type有问题。nginx
不过在chrome浏览器中确认了请求的request和response的content-type都是application/json;charset=UTF-8,没有问题。git
而后又google了一番乱码问题,基本上都是说的spring的HttpMessageConverter问题或者content-type,都没法解决。github
只能深刻排查一番了。web
排查的主要思路就是先肯定乱码是哪一步产生的。面试
tcpdump是linux下的网络数据包截获分析工具。在linux的平常网络管理中,tcpdump的使用频率很高,熟练掌握对提升工做效率颇有帮助。
为了获取对应服务的请求报文,须要登陆对应的服务器(或者k8s的pod)使用tcpdump进行抓取。
做为一个暖男,我把从安装到使用都一步步记下来给你 :)
1)安装工具
若是你的服务器上没有安装过tcpdump,能够先执行如下命令安装
yum -y install net-tools
2)查看网络状态
若是服务上有多个网卡,能够经过如下命令查看
Netstat -i
3)部署抓包
tcpdump -i eth0 tcp -w xxx.cap
还有不少其余选项能够过滤使用,你们能够网上搜一下,这里就不展开了。
4)调用请求
部署了tcpdump后,对服务器发起api请求。这时候相关的tcp报文都会被输出到 xxx.cap文件中了。
1)把xxx.cap文件发送本地
通常可使用scp命令,直接发送
scp xxxx.cap admin@10.xxx.xxx.xxx:/path
在传输服务器的文件到本地时,若是scp不方便使用,好比一些防火墙限制。
也可使用 python 在服务器上开启一个 web 服务(端口可自定义)。
python -m SimpleHTTPServer 18888 &
而后在本地使用 wget 下载文件便可。
2)解析cap文件
本地获得cap文件后,能够经过wireshark软件对cap文件进行解析,获得以下结果。
对api的报文进行解析后,发现返回对中文已是乱码了,确认了在服务端发出的响应内容中,已是乱码了。
因此,只能继续排查应用自己的问题。
Arthas 是Alibaba开源的Java诊断工具,当你遇到如下相似问题而一筹莫展时,均可以尝试使用Arthas(更详细的用法参考官方文档:https://arthas.aliyun.com/doc/quick-start.html):
curl -O https://arthas.aliyun.com/arthas-boot.jar java -jar arthas-boot.jar
本次排查,就使用了arthas的watch功能(更详细的用法参考官方文档:https://arthas.aliyun.com/doc/watch.html),能方便的观察到指定方法的调用状况。能观察到的范围为:返回值、抛出异常、入参。
咱们先看看线上运行应用controller层对于请求的响应,无需添加日志从新部署,咱们立刻就能看到线上代码的返回结果。
watch xxx.xxx.controller method "{params,returnObj}" -x 2
而后发起api调用,在arthas中显示结果以下:
咱们能够看到,这个controller方法返回的内容就是乱码了。
所以,说明是代码逻辑中存在转换的问题了。
根据业务逻辑,基本能猜想是从业务中的 byte[] 转string的时候出现问题了。
找到对应代码以下,new string()时没有指定字符集:
所以会在转换过程当中,默认读取系统变量的file.encoding做为字符集。
而后咱们用arthas直接查看系统变量,果真不是utf8。
因此,解决方案有两个。
第一种是在new string(bytes) 时指定字符集。
第二种就是设置系统变量file.encoding=utf-8。
咱们一开始选择了代码修复,在代码中转换时指定字符集。
从新发布后,再用arthas观察一下,发现居然仍是乱码?!!
而后从新回头在代码中看了好久,一直找不到缘由,陷入了僵局。。。
忽然,随手看了下线上,发现线上已经显示正常了,纳尼?是arthas有问题?
而后google了一下,发现不少人碰到arthas显示中文乱码的问题。。。
解决方式也比较简单,启动arthas的时候,也指定一下字符集。
java -jar -Dfile.encoding=UTF-8 arthas-boot.jar
而后问题解决了。。。呵呵。。。
这时候再观察arthas的结果已经显示正常。
这说明了什么?!!!!
Arthas输出界面的时候,确定在字符串转换的时候,也没有指定字符集。。。。
一脚踩了个连环坑。。。
其实整个问题是比较粗浅的,就是最后这个arthas的中文乱码让人有点脑袋疼。。。
固然,最主要仍是简单分享下tcpdump、arthas、simpleHTTPServer这些小工具,但愿能有所帮助吧。
都看到最后了,原创不易,点个关注,点个赞吧~
文章持续更新,能够微信搜索「阿丸笔记 」第一时间阅读,回复关键字【学习】有我准备的一线大厂面试资料。
知识碎片从新梳理,构建Java知识图谱: github.com/saigu/JavaK…(历史文章查阅很是方便)