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

本文涉及的产品
Serverless 应用引擎免费试用套餐包,4320000 CU,有效期3个月
函数计算FC,每月15万CU 3个月
简介: 前言 首先介绍下在本文出现的几个比较重要的概念: 函数计算(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。

移植到函数计算

下面我们将上面在 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. 源码项目
相关实践学习
【文生图】一键部署Stable Diffusion基于函数计算
本实验教你如何在函数计算FC上从零开始部署Stable Diffusion来进行AI绘画创作,开启AIGC盲盒。函数计算提供一定的免费额度供用户使用。本实验答疑钉钉群:29290019867
建立 Serverless 思维
本课程包括: Serverless 应用引擎的概念, 为开发者带来的实际价值, 以及让您了解常见的 Serverless 架构模式
目录
相关文章
|
7月前
|
人工智能 Serverless 数据库
在函数计算上部署专属的Agent平台
Agent 是公认的可以将AI能力跟具体业务结合的技术方案,而Agent Platform 是将Agent开发流程进行整合抽象后的平台工程,能够极大的提升Agent的构建和发布效率,帮助企业获取先机。本篇文章介绍如何在函数计算上部署一套Serverless架构的Agent平台- [AgentCraft](https://agentcraft-docs.serverless-developer.com/)
83408 7
在函数计算上部署专属的Agent平台
|
14天前
|
消息中间件 运维 安全
C5GAME 游戏饰品交易平台借助 RocketMQ Serverless 保障千万级玩家流畅体验
游戏行业蓬勃发展,作为国内领先的 STEAM 游戏饰品交易的服务平台,看 C5GAME 如何利用 RocketMQ Serverless 技术,为千万级玩家提供流畅的游戏体验,同时降低成本并提升运维效率。
C5GAME 游戏饰品交易平台借助 RocketMQ Serverless 保障千万级玩家流畅体验
|
4月前
|
存储 人工智能 JSON
基于函数计算FC一键部署ComfyUI绘画平台体验
【8月更文挑战第11天】基于函数计算FC一键部署ComfyUI绘画平台体验
144 1
|
5月前
|
弹性计算 分布式计算 Serverless
全托管一站式大规模数据处理和分析Serverless平台 | EMR Serverless Spark 评测
【7月更文挑战第6天】全托管一站式大规模数据处理和分析Serverless平台 | EMR Serverless Spark 评测
23725 42
|
4月前
|
Cloud Native Java Serverless
一键上天!如何将Spring PetClinic瞬间迁移到云端函数计算平台
【8月更文挑战第8天】在现代云原生开发中,将Spring应用迁移到Serverless环境正成为趋势。本文通过对比传统部署与函数计算,指导如何快速部署Spring PetClinic应用。传统部署需手动配置服务器和中间件,而函数计算则免除了这些步骤,仅需上传代码。首先,准备好Spring PetClinic源码或jar包;接着选择函数计算平台,本文以阿里云为例;随后对应用进行适配,并使用Maven构建部署包;登录阿里云控制台上传jar包并配置HTTP触发器;最后测试应用确保正常运行。
48 3
|
5月前
|
人工智能 前端开发 搜索推荐
详解基于百炼平台及函数计算快速上线网页AI助手
通过阿里云百炼平台,企业可在10分钟内为其网站添加智能客服系统,提升用户体验并降低成本。流程包括:创建大模型应用、配置参数(如温度系数以控制回复的随机性)、发布应用获取API密钥;使用函数计算快速搭建示例网站,并通过简单的代码更改启用AI助手功能;还可导入私有知识库增强助手的能力。前端基于NLUX开发,支持定制化需求如样式调整和历史会话管理。服务端代码提供了调用大模型获取答案的接口。借助百炼平台,企业能迅速部署即时且个性化的在线服务,适应数字化转型的需求。
|
4月前
|
Kubernetes Serverless 调度
异步任务处理系统问题之在阿里云函数计算平台上用户提交异步任务的问题如何解决
异步任务处理系统问题之在阿里云函数计算平台上用户提交异步任务的问题如何解决
|
4月前
|
监控 Java Serverless
美团 Flink 大作业部署问题之想在Serverless平台上实时查看Spring Boot应用的日志要怎么操作
美团 Flink 大作业部署问题之想在Serverless平台上实时查看Spring Boot应用的日志要怎么操作
|
4月前
|
运维 安全 Serverless
Serverless 平台问题之面临的挑战如何解决
全托管Serverless计算平台优势包括:免运维一站式应用管理降低运营成本;精益成本按实际用量计费;支持毫秒级弹性伸缩确保业务连续性;简化容器化部署流程;内置微服务治理功能;集成多种云服务便于Web应用管理;支持开源任务调度框架;基于标准容器接口易于集成第三方工具;提供安全隔离的应用环境;以及与云生态产品的自动集成提供全面解决方案。
77 0
|
5月前
|
Java Serverless API
云原生应用问题之将文档中的代码部署在函数计算平台上会提升用户体验如何解决
云原生应用问题之将文档中的代码部署在函数计算平台上会提升用户体验如何解决
46 0

相关产品

  • 函数计算