我有一个PHP Web表单,它接受文件上传(图像和文本),从中提取文本(OCR和.pdf,.doc等剥离为纯文本)。通过使用exec
来调用jar文件/命令行进程(我无法控制其中的源),执行文本提取,这将返回文本。虽然测试没有问题,但是同时上传5个PDF(每个大约5MB),服务器负载最大化。整个过程(每次上传)需要10-15秒,然后加载后立即恢复正常。
我假设问题是使用Java并为每个exec调用分配给JRE;当从命令行手动调用jar文件时,它需要大约10秒,因此几乎与单个上载响应相同。由于HTTP响应包含“数据”,因此无法将提取作为后台进程运行。从上传的文件文本处理。我考虑过分叉过程,但这对服务器负载没有帮助(可能会使情况变得更糟)。我希望避免完全用Java重写服务。
有没有办法预加载Java进程JRE或将连续文件管道到同一个或类似的东西?
答案 0 :(得分:1)
当然,为每个请求启动JVM是一个非常糟糕的主意。这正是Java慢的地方。
使用例如easy,应该非常ServerSocket。启动流程并向其发送请求。它不是最快的解决方案,而是简单且有保证的巨大加速。
JAR文件有时候是"可执行文件",但它始终是"库"。它实际上只是一个重命名的ZIP文件,因此您可以轻松查看其中的内容(我不会将其称为逆向工程)。这里有一个名为manifest的文件,其中包含对主类的引用。您可以编写自己的类,调用原始main
或忽略它。
为此,您根本不需要修改原始JAR。只是让你自己,但你甚至不需要一个JAR文件。对于简单的单个类应该足够的东西。然后你称之为
java -cp "old.jar;." YourClass
假设您正在使用Windows(否则将;
替换为:
),YourClass
位于主程序包中(这通常是一个坏主意,但对于单个类项目)和YourClass.class
(即YourClass.java
的编译版本在当前工作目录中。
<子> 我不会像使用ServerSocketChannel那样寻求更快,更复杂的解决方案,因为它不值得。启动一个新的JVM需要时间,而且,它首先解释字节码并编译它......这比一些通信开销要糟糕得多。你可以节省更多的微秒.... 子>
答案 1 :(得分:0)
如果我是你,我会先找一些关于在PHP中转换文件的开源项目。使用一种语言时,添加另一种语言通常会导致不必要的工作。机会是,你可以随心所欲地找到它;它甚至可能比你当前的解决方案更快。
鉴于您必须使用Java库:
文件操作通常会占用cpu,而且只有较大的文件才会变得更糟。除了可能限制文件大小之外,你可以做多少关于处理文件所需的时间。
但是,您可以控制服务器正在执行的操作。您应该考虑在服务器之间拆分工作。用于转换文件的服务器应该有一个更大的处理器,不需要大量的RAM;而你的网络服务器在内存较大的RAM上使用较小的处理器。
对于每次转换的数据,请将其存储在数据库中,直到转换完成。转换完成后,让您的转换服务器连接到数据库并存储相关数据,以及“完成”标志。
从这里你可以告诉客户端/浏览器反复检查数据库是否有完成标志(AJAX或Page Refresh)。
干杯!
- 尼克
此外,转换服务器永远不需要停止。将其作为无超时应用程序运行,不断检查数据库中的新作业是理想的;虽然它也建议你将它配置为在慢速期间关机或休眠。