Docker 容器阻塞中的 Apache Batik 转码器 [英] Apache Batik Transcoder inside Docker Container Blocking

查看:34
本文介绍了Docker 容器阻塞中的 Apache Batik 转码器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们在 docker 容器中运行 Spring 应用程序.我们的应用程序可以将 SVG 文件转换为 PDF 格式以嵌入到 PDF 中.

应用程序在 osx 上正常运行,并按预期进行转码.然而,当从具有不同文件系统的 docker 容器内部运行时,转码器卡住并在一些奇怪的递归文件搜索循环中颠簸 cpu.

java.lang.Thread.State: RUNNABLE在 java.io.UnixFileSystem.getBooleanAttributes0(Native Method)在 java.io.UnixFileSystem.getBooleanAttributes(UnixFileSystem.java:242)在 java.io.File.isFile(File.java:882)在 org.apache.commons.io.filefilter.FileFileFilter.accept(FileFileFilter.java:59)在 org.apache.commons.io.filefilter.AndFileFilter.accept(AndFileFilter.java:122)在 org.apache.commons.io.filefilter.AndFileFilter.accept(AndFileFilter.java:122)在 org.apache.commons.io.filefilter.OrFileFilter.accept(OrFileFilter.java:118)在 java.io.File.listFiles(File.java:1291)在 org.apache.commons.io.DirectoryWalker.walk(DirectoryWalker.java:357)在 org.apache.commons.io.DirectoryWalker.walk(DirectoryWalker.java:364)在 org.apache.commons.io.DirectoryWalker.walk(DirectoryWalker.java:364)在 org.apache.commons.io.DirectoryWalker.walk(DirectoryWalker.java:364)在 org.apache.commons.io.DirectoryWalker.walk(DirectoryWalker.java:364)在 org.apache.commons.io.DirectoryWalker.walk(DirectoryWalker.java:364)在 org.apache.commons.io.DirectoryWalker.walk(DirectoryWalker.java:364)在 org.apache.commons.io.DirectoryWalker.walk(DirectoryWalker.java:364)在 org.apache.commons.io.DirectoryWalker.walk(DirectoryWalker.java:364)在 org.apache.commons.io.DirectoryWalker.walk(DirectoryWalker.java:364)在 org.apache.commons.io.DirectoryWalker.walk(DirectoryWalker.java:364)在 org.apache.commons.io.DirectoryWalker.walk(DirectoryWalker.java:364

下面是运行 PDFTranscoder 的线程的堆栈跟踪.Walk 被递归调用一段时间,然后最终 getBooleanAttributes0 被调用并且所有的东西都被阻塞了.

经过进一步研究,我们发现我们可以仔细查看 strace 命令发生的情况,并发现系统本质上是在无限循环中发送以下垃圾邮件.

stat("/./sys/devices/pci0000:00/PNP0103:00/subsystem/devices/PNP0103:00/subsystem/devices/PNP0103:00/subsystem/devices/PNP0103:00/subsystem/设备/PNP0103:00/子系统/设备/PNP0103:00/子系统/设备/PNP0103:00/子系统/设备/PNP0103:00/子系统/设备/PNP0103:00/子系统/设备/PNP0103:00/子系统/设备PNP0103:00/subsystem/devices/PNP0103:00/subsystem/devices/PNP0103:00/subsystem/devices/PNP0103:00/subsystem/devices/PNP0103:00/subsystem/devices/PNP0103:00/subsystem/devices/PNP0103:00/subsystem/devices/PNP0103:00/subsystem/devices/00/subsystem/devices/PNP0103:00/subsystem/devices/pcspkr/input/input1/subsystem/input0/subsystem/input0/uniq", {st_mode=S_IFREG|0444, st_size=4096, ...}) = 0 <0.000224>

我们似乎在 stat 调用中被阻止或挂起.但是我们现在已经深入研究了系统调用,结果证明它很难调试.有人有什么想法吗?

解决方案

我遇到了同样的错误.在尝试了很多方法来修复它之后,我得出的结论是,你在 Mac OS X 上有可用的字体是一个问题,而你的(无头)Docker 容器操作系统没有字体.在到处搜索字体时,转码器并没有优雅地失败.我通过强制转码器使用默认字体(并且不自动寻找其他字体)像这样:

<预><代码>...PDFTranscoder transcoder = new PDFTranscoder();transcoder.addTranscodingHint(PDFTranscoder.KEY_AUTO_FONTS, false);...transcoder.transcode(transcoderInput, transcoderOutput);...

请注意,这当然有缺点,当它遇到 14 种字体之外的一种时,会退回到已知字体.我尝试了一些方法来解决这个问题,但到目前为止没有运气.

我希望这对某人有所帮助.

We're running a Spring application within a docker container. Our application can take SVG files and transform them into PDF format to be embedded within a PDF.

The application works correctly on osx and transcodes as expected. However when run from inside a docker container, which has a different file system, the transcoder gets stuck and thrashes the cpu in some bizarre recursive file searching loop.

java.lang.Thread.State: RUNNABLE
    at java.io.UnixFileSystem.getBooleanAttributes0(Native Method)
    at java.io.UnixFileSystem.getBooleanAttributes(UnixFileSystem.java:242)
    at java.io.File.isFile(File.java:882)
    at org.apache.commons.io.filefilter.FileFileFilter.accept(FileFileFilter.java:59)
    at org.apache.commons.io.filefilter.AndFileFilter.accept(AndFileFilter.java:122)
    at org.apache.commons.io.filefilter.AndFileFilter.accept(AndFileFilter.java:122)
    at org.apache.commons.io.filefilter.OrFileFilter.accept(OrFileFilter.java:118)
    at java.io.File.listFiles(File.java:1291)
    at org.apache.commons.io.DirectoryWalker.walk(DirectoryWalker.java:357)
    at org.apache.commons.io.DirectoryWalker.walk(DirectoryWalker.java:364)
    at org.apache.commons.io.DirectoryWalker.walk(DirectoryWalker.java:364)
    at org.apache.commons.io.DirectoryWalker.walk(DirectoryWalker.java:364)
    at org.apache.commons.io.DirectoryWalker.walk(DirectoryWalker.java:364)
    at org.apache.commons.io.DirectoryWalker.walk(DirectoryWalker.java:364)
    at org.apache.commons.io.DirectoryWalker.walk(DirectoryWalker.java:364)
    at org.apache.commons.io.DirectoryWalker.walk(DirectoryWalker.java:364)
    at org.apache.commons.io.DirectoryWalker.walk(DirectoryWalker.java:364)
    at org.apache.commons.io.DirectoryWalker.walk(DirectoryWalker.java:364)
    at org.apache.commons.io.DirectoryWalker.walk(DirectoryWalker.java:364)
    at org.apache.commons.io.DirectoryWalker.walk(DirectoryWalker.java:364

Here's a look at the stack trace of a thread that ran the PDFTranscoder. Walk is called recursively for a while and then eventually getBooleanAttributes0 is called and everything blocks.

After some further research, we found out we could take a closer look at what is happening with the strace command and saw that the system is essentially spamming the following in an endless loop.

stat("/./sys/devices/pci0000:00/PNP0103:00/subsystem/devices/PNP0103:00/subsystem/devices/PNP0103:00/subsystem/devices/PNP0103:00/subsystem/devices/PNP0103:00/subsystem/devices/PNP0103:00/subsystem/devices/PNP0103:00/subsystem/devices/PNP0103:00/subsystem/devices/PNP0103:00/subsystem/devices/PNP0103:00/subsystem/devices/PNP0103:00/subsystem/devices/PNP0103:00/subsystem/devices/PNP0103:00/subsystem/devices/PNP0103:00/subsystem/devices/PNP0103:00/subsystem/devices/PNP0103:00/subsystem/devices/PNP0103:00/subsystem/devices/PNP0103:00/subsystem/devices/pcspkr/input/input1/subsystem/input0/subsystem/input0/uniq", {st_mode=S_IFREG|0444, st_size=4096, ...}) = 0 <0.000224>

We seem to be getting blocked or hanging in the stat call. But we've delved so deep into system calls now that it's proving hard to debug. Does anyone have any ideas?

解决方案

I was getting the same error. After trying many things to fix it, I came to the conclusion that it's an issue with your having fonts available to you on Mac OS X, while your (headless) Docker container OS has no fonts. The transcoder is not failing gracefully while searching for fonts all over the place. I solved it by forcing the transcoder to use the default fonts (and to not automatically look for other fonts) like this:

...
PDFTranscoder transcoder = new PDFTranscoder();
transcoder.addTranscodingHint(PDFTranscoder.KEY_AUTO_FONTS, false);
...
transcoder.transcode(transcoderInput, transcoderOutput);
...

Note this has the downside, of course, of falling back to its known fonts when it encounters one outside of the 14 fonts. I tried things to fix that but so far no luck.

I hope this helps someone.

这篇关于Docker 容器阻塞中的 Apache Batik 转码器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆