サーバー上でlibreofficeを使ったpdf変換を高速化する勘所
最初に
調査過程などが長いので、結論だけ先に書いておきます。
結論だけみれば恐らく十分。
検証Libreバージョン: LibreOffice 7.0.6.2 144abb84a525d8e30c9dbbefa69cbbf2d8d4ae3b
結論
- libreofficeをdaemonとして、事前に動かしておく
- 事前起動や印刷コマンドでは
-env:UserInstallation
を同じ値に設定するか、使用しない
# 常駐起動。systemdなどを使用してバックグラウンドで動作させておく
# systemd のサービスファイルは最後付近のセクションを参考にする。
soffice --quickstart
soffice --headless --convert-to pdf --outdir 出力ディレクトリ 変換元ファイルパス
概要
みなさん、pdf出力していますか?
libreofficeのpdf変換が便利ですよね。
ローカルで利用する分には困らないのですが、サーバー内でサービスに組み込む際は問題があります。
1 ods(xlsx)ファイルをpdfに変換するとき、3-5秒程度かかります。
pdf出力で3-5秒もかかると、Webサービスの1機能に組み込みづらいですよね。おそすぎです。
プロセスを見ていると、1コマンドで soffice
プロセスが立ち上がり、変換が終わると soffice
プロセスが終了します。普通ですね。
実は、 soffice
コマンドは引数を複数渡すと1回の実行で100ファイル以上をpdfへ変換できます。
1コマンドで100ファイルを変換しても、1コマンドで1ファイルの100倍の時間がかかるわけではありません。長くて10倍程度です。このことから、私は soffice
の起動コストが高いと判断しました。
「常駐起動しておけば、高速で soffice
を使った変換ができるかも...?」
検索しても情報がない
英語サイトを検索しました。
daemon化の記事はいくつか引っかかるのですが、期待した動作の回答は見つかりませんでした。
(常駐起動して、Javaでlibreの機能を使う系の記事はありました)
「違う。そうじゃない。私は常駐daemonとコマンド実行の組み合わせで実行したいんだ。」
ひらめきと気付き
事前に
soffice
を実行すると、常駐のような状態になりました。
このタブを tab_A
とします。
別タブで変換コマンドを実行すると、0.5秒程度で変換完了しました。
爆速化してる。ヨシ!
...惜しいことに、 tab_A
の処理は終了してしまい、常駐できていませんでした。
終了しないで常駐するオプションもあると思い、片っ端からオプションを試して見つけました。
soffice --quickstart
です。
解決策
事前にlibreofficeを常駐起動
常駐起動します。systemdであれば、以下のようになります。
[Unit]
Description=Soffice Server
After=network.target
[Service]
Type=simple
User=実行ユーザー
ExecStart=/usr/bin/soffice --quickstart
TimeoutSec=300
Restart=always
[Install]
WantedBy=multi-user.target
sudo systemctl enable soffice.service
sudo systemctl start soffice.service
のように起動しておきましょう。
印刷コマンド
RubyやPHPなどでコマンドを実行して変換しましょう。
soffice --headless --convert-to pdf --outdir 出力ディレクトリ 変換元ファイルパス
注意点
Rubyには、LibreOfficeの変換用ラッパーライブラリ libreconvがあります。
これを使用すると、常駐のlibreofficeは使用されず新しく soffice
のプロセスが作られてしまい高速化できません。 -env:UserInstallation
の指定が原因で毎度新しいlibreインスタンスが作成されます。
そのため、直でコマンドで扱う必要があります。(少し古いlibreconvであれば、 -env:UserInstallation
が実装されていないバージョンがあるかも)
ほかライブラリからlibreのpdf変換を使う場合も、上記を気をつけましょう。
また、 -env:UserInstallation
の指定がない or 同じことで、同時に変換処理ができなくなるので注意が必要です。(CPUの多コアが活かせない、大量リクエストが来たときにタイムアウトするなど)
おわりに
みんな同じことで困っている人いるはず。このノウハウほとんど記事になっていないようなので、どんどん広まって欲しい。libreofficeは便利。
Discussion