美文网首页
图片处理功能失效问题排查

图片处理功能失效问题排查

作者: 站在海边看远方 | 来源:发表于2020-07-27 16:28 被阅读0次

项目上有一个保存PNG图片并展示的功能失效了,以前这个功能是没问题的,现在出现了问题,下面记录一下问题的排查过程。

问题表征

我本地的开发环境是Windows10,IDEA2020,本地启动功能是正常的,编辑流程可以正常展示流程的PNG格式的图片,如下图所示


image.png

然后应用打包部署到centos环境下,进行功能测试,图片无法正常展示,如下图所示


image.png

打开chrome控制台,有1个图片请求报错406


image.png

根据这个请求定位到后台代码,由于是部署在Linux环境下的,且根据日志无法定位问题,所以我们采用idea远程debug的方法进行调试。

问题排查

在查找问题的过程中,win10本地调试和centos功能测试,本地开发环境是正常的,centos上功能是不正常的。

本地环境和centos环境的zk、es、db都是用的同一套,排除依赖的第三方组件异常的问题。

定位到保存流程的代码进行远程debug,是进行PNG转码处理的


image.png

执行这行代码,抛出了一个异常


image.png

这个异常是类加载抛出的异常,类初始化失败

Could not initialize class org.apache.batik.gvt.font.FontFamilyResolver

这个是用的apache的batik包来处理的,有点老,是batik-1.7版本的,bytecode version :45.3(Java 1.1)。

我一开始怀疑可能是包版本太老了,后来换成了batik-1.11,结果还是无法展示图片,和包版本无关。

后来经过搜索,Could not initialize可能是静态代码块或者是静态变量加载失败导致的。

静态变量和静态代码块只在类加载的时候执行一次,且只会执行一次。后续抛出异常的时候有可能会覆盖这个错误,导致排查起来被误导。

重启应用程序(tomcat),定位到类加载失败的static代码块中,一步步执行。

static代码块中有一处执行抛出了异常

java.lang.NoClassDefFoundError: Could not initialize class sun.awt.X11FontManager

这个异常和设备的显示有关,Linux作为服务器,相比于个人PC,会缺少显示设备、鼠标、键盘等。

解决方案是设置jvm启动参数,模拟输入设备特性

-Djava.awt.headless=true

设置这个参数之后,还是会有报错,报错如下:

/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.151-1.b12.el6_9.x86_64/jre/lib/amd64/libfontmanager.so: libfreetype.so.6: cannot open shared object file: No such file or directory

猜测是openjdk缺少某些函数库,这个是容器自带的opnejdk,后来将openjdk换成oracle jdk8u181,可以正常展示图片了。

小结

首先根据页面上的错误定位到后端代码,进行排查。

其次由于是部署在Linux上,且没有清晰、直观的日志可供排查,所以选择了远程debug的方法,在本地进行调试。

调试过程中执行语句得到了Could not initialize class,这一步怀疑错方向了,这个错其实是类加载的问题,在加载静态变量或者静态代码块的时候,如果抛出异常,就会导致类加载失败。

还有1个问题是静态代码块只会在类加载的时候加载一次,加载完成后面都不会再加载了,所以对问题排查带来了一些困难。

最终问题的解决方案是加一个启动项:-Djava.awt.headless=true,另外还需要将openjdk更换为oracle jdk,openjdk缺少一些必要的库,导致产生了异常。

参考文章:
https://www.cnblogs.com/helf/p/12012619.html
https://blog.csdn.net/chen2526264/article/details/80534239

相关文章

网友评论

      本文标题:图片处理功能失效问题排查

      本文链接:https://www.haomeiwen.com/subject/bcszlktx.html