本文来自,欢迎关注
本文翻译自
备注:Go已经在2018/01/15成为了AWS Lambda原生支持的语言,你可以从这里了解到更多信息
在与合作伙伴与顾客一起的日常工作中,我们看到过很多不同领域、不同寻常的专业技能和经验,以及很多不同的编程语言。这些语言有些很老旧,而有一些非常前沿,很多团队都对它们的其中之一专研颇深,他们很可能想,在AWS上的新组件,比如上也使用这些语言。
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时,请使用在中的一个AMI,请设定你想要运行PHP代码和启动EC2的区域。有关更多信息,请参阅。
选择t2.large实例类型,它具有两个内核和8 GB内存,可以缩短PHP编译时间。
选择Review and Launch,使用存储的默认值,并且把实例加入到一个只开放SSH访问的由向导生成的安全组中。
选择Launch继续;在启动对话框中,您可以为登录选择现有的密钥对值,也可以创建一个新的密钥对值。在这个例子中,我们创建一个名为php
的新密钥对并下载它。
下载密钥后,命令行进入到文件所在的文件夹并运行以下命令:
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 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-bincd 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复制代码
编译完成后,可以通过运行以下命令快速确认PHP是否正常运行:
cd ~/php-7-bin/bin/./php -vPHP 7.0.7 (cli) (built: Jun 16 2016 09:14:04) ( NTS )Copyright (c) 1997-2016 The PHP GroupZend Engine v3.0.0, Copyright (c) 1998-2016 Zend Technologies复制代码
代码时间
使用你最喜欢的编辑器,创建一个入口PHP文件,在这个例子中,我们从Linux管道读取输入,获取一个简单的JSON文档,并计算此JSON数据的顶层节点数量,将结果输出stdout。
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:
// Javascriptprocess.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方式大同小异,所以在此就不做翻译,感兴趣的读者请阅读原文。