【译】在AWS Lambda上运行脚本语言:PHP、Ruby和Go

本文来自Mobingi官方技术专栏,欢迎关注

本文翻译自Scripting Languages for AWS Lambda: Running PHP, Ruby, and Go

备注:Go已经在2018/01/15成为了AWS Lambda原生支持的语言,你可以从这里了解到更多信息https://aws.amazon.com/blogs/compute/announcing-go-support-for-aws-lambda/

在与合作伙伴与顾客一起的日常工作中,我们看到过很多不同领域、不同寻常的专业技能和经验,以及很多不同的编程语言。这些语言有些很老旧,而有一些非常前沿,很多团队都对它们的其中之一专研颇深,他们很可能想,在AWS上的新组件,比如AWS Lambda上也使用这些语言。

Lambda本身对很多语言提供原生支持,例如Java、Node.js、Python和C#。在这篇文章中我们想描述如何在Lambda中使用其他的脚本语言(非原生支持的)。

对于每一个你想要使用的语言,你需要完成下面的任务:

  • 准备: 从AMI启动一个实例,然后用SSH登陆。

  • 编译: 打包你要在Lambda使用的语言

  • 安装: 创建Lambda包并测试代码运行

每个编程语言的准备和安装步骤基本相同,所以我们在这里只提供PHP、Go、和Ruby的,一步一步编译打包的例子。

准备开始前共通步骤

Lambda允许你在Lambda运行环境中执行任何可执行文件。下面的步骤只是一个如何运行PHP、Go、Ruby在Lambda上面的大框。不管怎么说,你还是可以用这个方法,添加一些特定的库,扩展编译范围,使用JSON将你的Lambda函数和Amazon API Gateway或者其它服务互联。

在编译好二级制文件,并设定好基础文件结构之后,你就不需要再新建项目或者修改代码的时候重复做这些步骤。只需要简单编写代码接受STDIN的标准输入,然后输出结果到标准输出STDOUT,写好的Node.js包装器将会负责连接你的输入输出到运行环境。

为了简单起见,我们仅演示准备PHP的步骤,但这些步骤同样适用于后面描述的其他运行环境。

在EC2控制台,选择Lanch instance,选择AMI时,请使用在Lambda Execution Environment and Available Libraries中的一个AMI,请设定你想要运行PHP代码和启动EC2的区域。有关更多信息,请参阅Step 1: Launch an Instance

选择t2.large实例类型,它具有两个内核和8 GB内存,可以缩短PHP编译时间。

image

选择Review and Launch,使用存储的默认值,并且把实例加入到一个只开放SSH访问的由向导生成的安全组中。

选择Launch继续;在启动对话框中,您可以为登录选择现有的密钥对值,也可以创建一个新的密钥对值。在这个例子中,我们创建一个名为php的新密钥对并下载它。

image

下载密钥后,命令行进入到文件所在的文件夹并运行以下命令:

chmod 400 php.pem

基于SSH的安全标准,我们必须修改秘钥权限。现在可以使用EC2的公共DNS连接到实例。在控制台中选择实例并在屏幕右下方的公共DNS下查找实例,获得地址。

ssh -i php.pem ec2-user@[PUBLIC DNS]

当实例启动并运行后,你就在一个适当的区域中有了一个适当AMI,你可以用上面的命令登陆实例,继续执行其他步骤。

准备PHP运行环境

登录到正在运行的AMI后,你可以从源代码编译PHP7环境,并准备好为Lambda环境打包。

给实例配置PHP

下一步是编译PHP7,将PHP7编译器的输出配置到指定目录,最后编译PHP7到Lambda AMI。

运行以下命令更新程序包管理器:

sudo yum update –y

安装最少的必要的库,用于编译PHP7:

sudo yum install gcc gcc-c++ libxml2-devel -y 

安装依赖项后,您需要从PHP Downloads下载可用的PHP 7源代码。

在这个例子中,我们在爱尔兰运行一台EC2,因此我们选择了http://ie1.php.net/get/php-7.0.7.tar.bz2/from/this/mirror作为我们的镜像。运行以下命令将源下载到实例,读者可以根据你的Instance所在的区域选择自己的镜像。

cd ~
wget http://ie1.php.net/distributions/php-7.0.7.tar.bz2 .

使用以下命令提取文件:

tar -jxvf php-7.0.7.tar.bz2

上面的命令在你的home目录中创建php-7.0.7文件夹,然后通过下面的命令,创建一个专用的php-7二进制文件。

mkdir /home/ec2-user/php-7-bin
cd php-7.0.7
./configure --prefix=/home/ec2-user/php-7-bin/

这可以确保PHP编译很好地打包到您在home目录中创建的指定PHP文件夹中。请记住,我们只在此处编译最基本PHP以减少Lambda函数的依赖。

你可以使用./configure中提供的选项为Lambda中PHP二进制文件加入更多依赖项或者编译器选项。 运行./configure -h可以获取有关可以打包到PHP发行版中的内容的更多信息。但请记住,这将增加PHP二进制包的整体大小(可能影响PHP Lambda代码的整体启动时间,译者注)。

最后,运行以下命令,开始编译:

make install
image

https://xkcd.com/303/

编译完成后,可以通过运行以下命令快速确认PHP是否正常运行:

cd ~/php-7-bin/bin/
./php -v
PHP 7.0.7 (cli) (built: Jun 16 2016 09:14:04) ( NTS )
Copyright (c) 1997-2016 The PHP Group
Zend Engine v3.0.0, Copyright (c) 1998-2016 Zend Technologies

代码时间

使用你最喜欢的编辑器,创建一个入口PHP文件,在这个例子中,我们从Linux管道读取输入,获取一个简单的JSON文档,并计算此JSON数据的顶层节点数量,将结果输出stdout。

<?php
 $data = stream_get_contents(STDIN);
 $json = json_decode($data, true);
 $result = json_encode(array('result' => count($json)));
 echo $result."\n";
?>

创建Lambda包

既然PHP的编译和准备已经就绪了,现在需要做的就是创建Lambda包,然后将Node.js包装器作为入口点。

首先,使用以下命令对二进制文件所在的php-7-bin文件夹进行tar压缩:

tar -zcvf php-7-bin.tar.gz php-7-bin/

然后,退出远程主机,x运行下面的命令以下载压缩文件到本地计算机(Linux、OSX或者在windows上用类似WinSCP的工具)

scp -i php.pem ec2-user@[EC2_HOST]:~/php-7-bin.tar.gz .

下载玩压缩包之后,新建一个Lambda项目,将所有文件解压缩到此文件夹中,项目的目录结构如下:

php-lambda 
+-- php-7-bin

下一步是创建一个Node.js包装器文件。该文件接受Lambda调用的输入,使用helloLambda.php作为参数调用PHP可执行文件,并通过Linux管道向PHP提供输入以进行处理。复制如下内容到php.js:

// Javascript
process.env['PATH'] = process.env['PATH'] + ':' + process.env['LAMBDA_TASK_ROOT'];

const spawn = require('child_process').spawn;

exports.handler = function(event, context) {

    //var php = spawn('php',['helloLambda.php']); //local debug only
    var php = spawn('php-7-bin/bin/php',['helloLambda.php']);
    var output = "";

    //send the input event json as string via STDIN to php process
    php.stdin.write(JSON.stringify(event));

    //close the php stream to unblock php process
    php.stdin.end();

    //dynamically collect php output
    php.stdout.on('data', function(data) {
          output+=data;
    });

    //react to potential errors
    php.stderr.on('data', function(data) {
            console.log("STDERR: "+data);
    });

    //finalize when php process is done.
    php.on('close', function(code) {
            context.succeed(JSON.parse(output));
    });
}

//local debug only
//exports.handler(JSON.parse("{"hello":"world"}"));

最终,所有文件结构如下:

php-lambda
+-- php-7-bin
-- helloLambda.php
-- php.js

部署之前的最后一步是将项目压缩成可以上传到Lambda上的压缩包LambdaPHP.zip。如果你想,可以从php-7-bin / bin文件夹中删除不必要的文件,如phpdebug,以减少压缩包的大小。 有关如何创建部署包的更多详细信息,请参阅文档

译者总结

其实,使用Lambda运行PHP的原理很简单,Lambda本身不原生支持PHP,但其实Lambda的背后也是一台Linux的Instance。那么你要做的就是,用一台和Lambda运行环境一样的机器来编译PHP可执行文件,它可以执行PHP代码,然后在你的Lambda项目中包含这个PHP可执行文件。然后再以node.js为入口,启动PHP可执行文件,这个可执行文件会运行你指定的PHP脚本。在node.js的包装器中,将Lambda参数传递给标准输入,并等待标准输出的结果,得到结果后,将其作为Lambda的运行结果返回。 而在这个过程中PHP代码会等待标准输入,处理,并将结果输出到标准输出。

原文还写了如何运行Go和Ruby在方法,因为跟运行PHP方式大同小异,所以在此就不做翻译,感兴趣的读者请阅读原文。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,457评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,837评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,696评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,183评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,057评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,105评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,520评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,211评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,482评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,574评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,353评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,213评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,576评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,897评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,174评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,489评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,683评论 2 335

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,497评论 18 139
  • Awesome PHP 一个PHP资源列表,内容包括:库、框架、模板、安全、代码分析、日志、第三方库、配置工具、W...
    guanguans阅读 5,735评论 0 47
  • Lambda test 知识点 1 Lambda function可以配置所用内存大小,当程序所需内存大小超出配置...
    K1024阅读 2,104评论 0 0
  • 只有真正买了房之后,才能体会到房产升值的意义。很多人都是买了房之后后悔当初为什么不买大一点,不多买几套。 1、看中...
    家有小屁孩阅读 185评论 0 0
  • 努力三组 日期:2018年8月4日 名称:宁波大发化纤有限公司 六项精进403期努力三组 【日精进打卡第55天】 ...
    努力三组阅读 147评论 0 0