手把手教您将 Ghostscript 移植到函数计算平台

本文涉及的产品
简介: 前言 首先介绍下在本文出现的几个比较重要的概念: 函数计算(Function Compute):函数计算是一个事件驱动的服务,通过函数计算,用户无需管理服务器等运行情况,只需编写代码并上传。函数计算准备计算资源,并以弹性伸缩的方式运行用户代码,而用户只需根据实际代码运行所消耗的资源进行付费。

前言

首先介绍下在本文出现的几个比较重要的概念:

函数计算(Function Compute):函数计算是一个事件驱动的服务,通过函数计算,用户无需管理服务器等运行情况,只需编写代码并上传。函数计算准备计算资源,并以弹性伸缩的方式运行用户代码,而用户只需根据实际代码运行所消耗的资源进行付费。函数计算更多信息参考
Fun:Fun 是一个用于支持 Serverless 应用部署的工具,能帮助您便捷地管理函数计算、API 网关、日志服务等资源。它通过一个资源配置文件(template.yml),协助您进行开发、构建、部署操作。Fun 的更多文档参考
Ghostscript:Ghostscript 是一套建基于Adobe、PostScript及可移植文档格式(PDF)的页面描述语言等而编译成的自由软件。参见维基百科词条

备注: 本文介绍的技巧需要 Fun 版本大于等于 3.0.0-beta.2 。

依赖工具

本项目是在 MacOS 下开发的,涉及到的工具是平台无关的,对于 Linux 和 Windows 桌面系统应该也同样适用。在开始本例之前请确保如下工具已经正确的安装,更新到最新版本,并进行正确的配置。

Fun 工具依赖于 docker 来模拟本地环境。

对于 MacOS 用户可以使用 homebrew 进行安装:

brew cask install docker
brew tap vangie/formula
brew install fun

Windows 和 Linux 用户安装请参考:

  1. https://github.com/aliyun/fun/blob/master/docs/usage/installation.md

安装好后,记得先执行 fun config 初始化一下配置。

注意, 如果你已经安装过了 fun,确保 fun 的版本在 3.0.0-beta.2 以上。

$ fun --version
3.0.0-beta.2

Linux 下将 PDF 转换成 JPG

函数计算默认的 linux 环境是 Debian Jessie,首先我们先解决 Debain Jessie 环境下如何将 PDF 文件转换成 JPG 文件的问题。使用 fun install sbox 启动一个沙箱环境,在沙箱环境进行如下操作:

$ fun install sbox -r nodejs10 -i
root@fc-nodejs10:/code# apt-get update && apt-get install -y ghostscript
....
root@fc-nodejs10:/code# ls
test.pdf
root@fc-nodejs10:/code# gs -sDEVICE=jpeg -dTextAlphaBits=4 -r144 -o test.jpg test.pdf
GPL Ghostscript 9.26 (2018-11-20)
Copyright (C) 2018 Artifex Software, Inc.  All rights reserved.
This software comes with NO WARRANTY: see the file PUBLIC for details.
Processing pages 1 through 1.
Page 1
root@fc-nodejs10:/code# ls
test.jpg  test.pdf

其中转换命令为 gs -sDEVICE=jpeg -dTextAlphaBits=4 -r144 -o test.jpg test.pdf,其选项为

  • -sDEVICE=jpeg 指定输出设备为 jpeg,另外一个可选值为 jpeggray
  • -o 指定输出文件
  • -dTextAlphaBits 指定文本采样抗锯齿,另一个类似的选项为 -dGraphicsAlphaBits 用于图像采样抗锯齿。
  • -r144 设定图像的 dpi 为 144。

更多选项参见 https://www.ghostscript.com/doc/9.21/Devices.htm

移植到函数计算

下面我们将上面在 sbox 中 ghostscript 转换的实验成果移植到函数计算的 nodejs10 runtime 中。首先初始化一个本地的 fun 项目,借助于 fun 可以本地方便地安装依赖,本地调试并打包上传。

初始化项目

$ fun init event-nodejs10
Start rendering template...
+ /Users/vangie/Desktop/test
+ /Users/vangie/Desktop/test/.funignore
+ /Users/vangie/Desktop/test/index.js
+ /Users/vangie/Desktop/test/template.yml
finish rendering template.

将 template.yml 的内容更新为

ROSTemplateFormatVersion: '2015-09-01'
Transform: 'Aliyun::Serverless-2018-04-03'
Resources:
  ghostscript:
    Type: 'Aliyun::Serverless::Service'
    Properties:
      Description: 'helloworld'
    pdf2jpg:
      Type: 'Aliyun::Serverless::Function'
      Properties:
        Handler: index.handler
        Runtime: nodejs10
        CodeUri: './'
        EnvironmentVariables:
          GS_LIB: ".fun/root/usr/share/ghostscript/9.26/Resource/Init:\
            .fun/root/usr/share/ghostscript/9.26/lib:\
            .fun/root/usr/share/ghostscript/9.26/Resource/Font:\
            .fun/root/usr/share/ghostscript/fonts:\
            .fun/root/var/lib/ghostscript/fonts:\
            .fun/root/usr/share/ghostscript/fonts:\
            .fun/root/usr/share/fonts"

其中环境变量 GS_LIB 是为了支持 ghostscript 安装在代码目录所需要的。

将 index.js 的内容更新为

const { exec } = require('child_process');

module.exports.handler = function (event, context, callback) {
  const cmd = 'gs -sDEVICE=jpeg -dTextAlphaBits=4 -r144 -o /tmp/test.jpg test.pdf';
  exec(cmd, (err, stdout, stderr) => {
    if (err) {
      console.log(stdout);
      console.log(stderr);
      callback(err, "convert fail.\n");
    } else {
      console.log(stdout)
      callback(null, 'convert success.\nJPG file save to /tmp/test.jpg\n');
    }
  });
};

安装 ghostscript

使用如下命令安装 ghostscript

$ fun install -p apt -r nodejs10 ghostscript --save

ghostscript 会被安装到当前目录下的 .fun 目录内

$  tree . -a -L 4
.
├── .fun
│   └── root
│       ├── etc
│       │   ├── fonts
│       │   ├── ghostscript
│       │   └── libpaper.d
│       ├── usr
│       │   ├── bin
│       │   ├── lib
│       │   ├── sbin
│       │   └── share
│       └── var
│           └── lib
├── .funignore
├── README.md
├── fun.yml
├── index.js
└── template.yml

16 directories, 7 files

本地测试

在代码目录放一个 test.pdf 文件

$  tree          
.
├── README.md
├── fun.yml
├── index.js
├── template.yml
└── test.pdf

然后通过 fun local invoke 本地调用

$  fun local invoke pdf2jpg     
using template: template.yml
FC Invoke Start RequestId: 3ea14d81-fd6b-4259-b9a5-dde29c2f022a
load code for handler:index.handler
2019-09-03T07:36:20.200Z 3ea14d81-fd6b-4259-b9a5-dde29c2f022a [verbose] stdout =================== START
2019-09-03T07:36:20.200Z 3ea14d81-fd6b-4259-b9a5-dde29c2f022a [verbose] GPL Ghostscript 9.26 (2018-11-20)
Copyright (C) 2018 Artifex Software, Inc.  All rights reserved.
This software comes with NO WARRANTY: see the file PUBLIC for details.
Warning: the map file cidfmap was not found.
Processing pages 1 through 1.
Page 1

2019-09-03T07:36:20.201Z 3ea14d81-fd6b-4259-b9a5-dde29c2f022a [verbose] stdout =================== END
FC Invoke End RequestId: 3ea14d81-fd6b-4259-b9a5-dde29c2f022a
convert success.
JPG file save to /tmp/test.jpg
2019-09-03T07:36:20.212Z 3ea14d81-fd6b-4259-b9a5-dde29c2f022a [error](node:23) [DEP0005] DeprecationWarning: Buffer() is deprecated due to security and usability issues. Please use the Buffer.alloc(), Buffer.allocUnsafe(), or Buffer.from() methods instead.


RequestId: 3ea14d81-fd6b-4259-b9a5-dde29c2f022a          Billed Duration: 1590 ms        Memory Size: 1998 MB    Max Memory Used: 32 MB

生成的 test.jpg 文件可以在 .fun/tmp/invoke 目录下找到

$  tree .fun/tmp/invoke -L 3
.fun/tmp/invoke
└── ghostscript
    └── pdf2jpg
        ├── agenthubout.log
        └── test.jpg

部署并调用

通过 fun deploy 命令快捷部署到函数计算平台

$  fun deploy              
using template: template.yml
using region: cn-shanghai
using accountId: ***********4733
using accessKeyId: ***********EUz3
using timeout: 60

Waiting for service ghostscript to be deployed...
        Waiting for function pdf2jpg to be deployed...
                Waiting for packaging function pdf2jpg code...
                package function pdf2jpg code done, the number of files you have packaged is:1048
        function pdf2jpg deploy success
service ghostscript deploy success

使用 fun invoke <function_name> 调用函数。

$  fun invoke pdf2jpg
using template: template.yml
========= FC invoke Logs begin =========
FC Invoke Start RequestId: 99cc8b32-6084-4a6b-a1ff-444e06e10eca
load code for handler:index.handler
2019-09-03T07:49:47.454Z 99cc8b32-6084-4a6b-a1ff-444e06e10eca [verbose] stdout =================== START
2019-09-03T07:49:47.455Z 99cc8b32-6084-4a6b-a1ff-444e06e10eca [verbose] GPL Ghostscript 9.26 (2018-11-20)
Copyright (C) 2018 Artifex Software, Inc.  All rights reserved.
This software comes with NO WARRANTY: see the file PUBLIC for details.
Warning: the map file cidfmap was not found.
Processing pages 1 through 1.
Page 1

2019-09-03T07:49:47.455Z 99cc8b32-6084-4a6b-a1ff-444e06e10eca [verbose] stdout =================== END
FC Invoke End RequestId: 99cc8b32-6084-4a6b-a1ff-444e06e10eca

Duration: 526.16 ms, Billed Duration: 600 ms, Memory Size: 128 MB, Max Memory Used: 57.09 MB
========= FC invoke Logs end =========

FC Invoke Result:
convert success.
JPG file save to /tmp/test.jpg

参考阅读

  1. 源码项目
相关实践学习
基于函数计算一键部署掌上游戏机
本场景介绍如何使用阿里云计算服务命令快速搭建一个掌上游戏机。
建立 Serverless 思维
本课程包括: Serverless 应用引擎的概念, 为开发者带来的实际价值, 以及让您了解常见的 Serverless 架构模式
目录
相关文章
|
1月前
|
人工智能 Serverless API
在函数计算上部署专属的Agent平台
Agent及Agent平台的相关概念和应用价值已经在《智能体(Agent)平台介绍》 文章进行了介绍,接下来我们要进行实际的操作,在阿里云函数计算上快速获取专属的Agent平台-AgentCraft
83153 6
在函数计算上部署专属的Agent平台
|
2月前
|
人工智能 Serverless API
AI 绘画平台难开发,难变现?试试 Stable Diffusion API Serverless 版解决方案
AI 绘画平台难开发,难变现?试试 Stable Diffusion API Serverless 版解决方案
|
3月前
|
人工智能 Serverless API
AI 绘画平台难开发,难变现?试试 Stable Diffusion API Serverless 版解决方案
AI 绘画平台难开发,难变现?试试 Stable Diffusion API Serverless 版解决方案
7685 132
|
3月前
|
人工智能 Serverless API
AI 绘画平台难开发,难变现?试试 Stable Diffusion API Serverless 版解决方案
为了帮助用户高效率、低成本应对企业级复杂场景,函数计算团队正式推出 Stable Diffusion API Serverless 版解决方案,通过使用该方案,用户可以充分利用 Stable Diffusion +Serverless 技术优势快速开发上线 AI 绘画应用,期待为广大开发者 AI 绘画创业及变现提供思路。
87308 4
|
3月前
|
前端开发 JavaScript 小程序
亚马逊云科技 Build On -Serverless低代码平台初体验-快速完成vue前端订单小程序
亚马逊云科技 Build On -Serverless低代码平台初体验-快速完成vue前端订单小程序
47 0
|
4月前
|
机器学习/深度学习 运维 安全
阿里云 ACK One Serverless Argo 助力深势科技构建高效任务平台
阿里云 ACK One Serverless Argo 助力深势科技构建高效任务平台
101173 8
|
4月前
|
运维 中间件 Java
淘宝权益玩法平台的Serverless化实践
淘宝权益玩法平台的Serverless化实践
224 0
|
7月前
|
关系型数据库 MySQL Serverless
使用函数计算挂载NAS并搭建照片管理平台
本场景主要介绍如何基于函数计算、数据库RDS和文件存储NAS一键部署相册应用。
750 0
|
9月前
|
监控 Cloud Native Oracle
Serverless是什么?如何使用?有哪些优势?国内外有哪些Serverless平台?
Serverless 是云计算的一种模型。以平台即服务(PaaS)为基础,无服务器运算提供一个微型的架构,终端客户不需要部署、配置或管理服务器服务,代码运行所需要的服务器服务皆由云端平台来提供, Serverless computing(无服务器运算,又被称为函数即服务 Function-as-a-Service,缩写为 FaaS),以 Amazon Lambda 为典型服务。
|
11月前
|
缓存 运维 监控
《2023云原生实战案例集》——04 互联网——网易云音乐 基于函数计算FC创建音视频算法处理平台
《2023云原生实战案例集》——04 互联网——网易云音乐 基于函数计算FC创建音视频算法处理平台

相关产品

  • 函数计算