Arthas 是Alibaba开源的Java诊断工具
JSON解析异常问题
org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error
org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Unexpected character ('ä' (code 228)): was expecting comma to separate Object entries; nested exception is com.fasterxml.jackson.core.JsonParseException: Unexpected character ('ä' (code 228)): was expecting comma to separate Object entries
at [Source: (PushbackInputStream); line: 1, column: 264]
Caused by: com.fasterxml.jackson.core.JsonParseException: Unexpected character ('ä' (code 228)): was expecting comma to separate Object entries
at [Source: (PushbackInputStream); line: 1, column: 264]
看到上面的异常信息我们已经很明确的知道了是接口调用方传入的JSON字符串有问题,从而导致后端解析JSON失败。但是,具体请求的是哪个接口异常中并未打印出来。这时候犯难了。不可能去让接口调用方一个一个的去找(没有足够的证据可能还会被diss一通)。正当一筹莫展的时候想到了之前用阿里开源的Arthas诊断线上内存泄漏问题时的经历,感觉它面对这个也应该是可以的,于是乎就有如下尝试。
-
因为使用的是docker 所以直接使用了如下命令进入容器:
docker exec -it ${containerId} /bin/bash -c "wget https://alibaba.github.io/arthas/arthas-boot.jar && java -jar arthas-boot.jar"
不料官方原版tomcat镜像找不到pid
[INFO] arthas-boot version: 3.4.4 [INFO] Can not find java process. Try to pass <pid> in command line. Please select an available pid.
算了,直接用外部jdk 查看容器挂载外部目录信息
docker inspect --format "{{.Config.Volumes}}" ${containerId}
,直接把下载好的jdk解压放入其中一个目录中。下载arthas-boot.jar
:curl -O https://alibaba.github.io/arthas/arthas-boot.jar
同样放入在挂载目录下。 注意:外部的JDk
bin
目录下文件最好都加上可执行权限chmod -R 777 bin
#${dir} 为外部文件挂载在容器内的目录 docker exec -it ${containerId} /bin/bash -c "/${dir}/jdk/bin/java -jar /${dir}/arthas-boot.jar" #或者通过 docker exec -it ${containerId} bash # 进入之后cd 到 ${dir} 执行命令
-
进入容器后使用 watch 命令来查看调用接口以及参数
观察入参:
watch org.springframework.web.servlet.DispatcherServlet doDispatch 'params[0]' -x 3 -b -n 2 # 通过查看 HttpServletRequest 里面的请求,来得到信息 #java 8 直接获取到POST body 里面的参数 watch org.springframework.web.servlet.DispatcherServlet doDispatch 'params[0].getReader().lines().collect(@java.util.stream.Collectors@joining(@java.lang.System@lineSeparator()))' -x 3 -b -n 2 ## 注意流在这里被读取之后,后面的方法就没法处理了
-
如上大概就可以知道调用方入参的原始数据了,根据原始数据就可以去说理了!!但是,以上只能用于 应急 或 测试环境,如果线上环境还得重新考虑。
结束、也未结束
这只是一个开始,方法还得完善。