Java調用shell腳本執行imagemagick壓縮圖片



前言

自己做個小項目,有個需求得存儲圖片,爲了頁面渲染速度。
這裏存儲的是壓縮圖片,然後外鏈指向原圖。本地不存儲。美滋滋。
但是想法很美好,結果缺不盡人意…

業務邏輯上一點問題沒有,結果出在服務器上,內存不足,導致宕機。
一通排查之後發現是壓縮圖片這裏導致的內存溢出。
嘗試解決辦法:

  • 所有IO流操作完立馬close,無效
  • 數量降低爲每分鐘處理3張圖片,無效
  • 採用谷歌的開源工具thumbnailator,無效

最後無奈在linux上安裝imagemagick,然後java執行shell語句去壓縮圖片。
然後就一路順暢了,不得不說java的IO真的喫內存。


安裝

介紹一下本文的環境,java項目運行在docker容器中,基於java:8-alpine鏡像。
注意是alpine,超苗條的linux。所以很多基本指令在容器內都沒有。

方式一:Dockerfile

全寫註釋了,就不做過多額外的解釋了

FROM java:8-alpine
ADD target/xxx.jar xxx.jar
# 修改alpine的源地址改爲阿里的,否則下載速度極慢
RUN echo -e "https://mirrors.aliyun.com/alpine/v3.7/main" > /etc/apk/repositories
# 更新本地apk的鏡像索引數據 並且 安裝imagemagick
RUN apk update && apk add imagemagick
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "/xxx.jar"]

方式二:進入已有容器內部安裝

# 進入容器,因爲是基於alpine,所以這裏用sh,而不是bash
docker exec -it xxx sh
# 修改alpine的源地址改爲阿里的,否則下載速度極慢
echo -e "https://mirrors.aliyun.com/alpine/v3.7/main" > /etc/apk/repositories
# 更新本地apk的鏡像索引數據 並且 安裝imagemagick
apk update && apk add imagemagick

測試

convert -version

/ # convert -version
Version: ImageMagick 7.0.7-11 Q16 x86_64 2017-11-15 http://www.imagemagick.org
Copyright: © 1999-2017 ImageMagick Studio LLC
License: http://www.imagemagick.org/script/license.php
Features: Cipher DPC HDRI Modules OpenMP
Delegates (built-in): bzlib cairo fontconfig freetype gslib jng jpeg lcms ltdl pangocairo png ps rsvg tiff webp xml zlib
/ #


Linux上壓縮

官方示例:https://www.imagemagick.org/Usage/

# 壓縮質量爲70% 1.png:源文件 to1.jpng:壓縮後的文件 
convert -quality 70% 1.png to1.jpg && rm -f 1.png
# 如何用這個還是提示內存不足的話,再加上兩個參數即可。設置最大內存2mb
convert -limit memory 2mb -limit map 2mb -quality 70% 1.png to1.jpg && rm -f 1.png


Java執行shell實現壓縮

String cmd = "convert -limit memory 2mb -limit map 2mb -quality 70% 1.png to1.jpg && rm -f 1.png";
// "sh", "-c"不可省略,waitFor:阻塞線程等待shell執行結束
Runtime.getRuntime().exec(new String[]{"sh", "-c", cmd}).waitFor();
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章