无服务器灯堆

2020-06-15 00:58:04

这是面向PHP开发人员的系列帖子中的第一篇。本系列将解释如何在PHP中使用无服务器技术。它涵盖了构建无服务器应用程序的可用工具、框架和策略,以及为什么现在是开始的合适时机。

在以后的文章中,我将演示如何将AWS Lambda用于使用Laravel和Symfony等PHP框架构建的Web应用程序。我展示了如何从使用Lambda作为web托管功能的替代品转向解耦的、事件驱动的方法。我将介绍如何将范围最小的多个Lambda函数与其他无服务器服务相结合,以创建高性能、可伸缩的微服务。

在这篇文章中,您将学习如何通过自定义运行时API在Lambda中使用PHP。请访问此GitHub存储库获取示例代码。

可伸缩性是传统LAMP堆栈固有的挑战。可伸缩的应用程序是可以处理高度可变的流量级别的应用程序。PHP应用程序通常通过根据需要添加更多Web服务器来水平扩展。这是通过负载均衡器进行管理的,负载均衡器将请求定向到各种Web服务器。每增加一台服务器都会带来额外的网络、管理、存储容量、备份和恢复系统以及资产管理库存更新方面的开销。此外,每个水平扩展的服务器都独立运行。这可能会导致配置同步挑战。

新的存储挑战出现了,因为每台服务器都有自己的磁盘和文件系统,通常需要开发人员添加一种机制来处理用户会话。使用无服务器技术,可以为开发人员管理可伸缩性。

如果流量激增,服务可以扩展以满足需求,而无需部署额外的服务器。这使得应用程序可以快速从原型过渡到生产。

对动态内容的所有请求(除/Assets/*以外的任何内容)都会转发到Amazon API Gateway。这是一个完全托管的服务,用于创建、发布和保护任何规模的API。它充当PHP应用程序的“前门”,将请求向下路由到Lambda函数。Lambda函数包含业务逻辑以及与MySQL数据库的交互。您可以将输入作为请求头、路径变量、查询字符串参数和正文的任意组合传递给Lambda函数。

在Re:Invent2017期间,AWS发布了Aurora Serverless,这是一种按需无服务器关系数据库,采用按使用付费模式。这为开发人员管理提供和扩展关系数据库的责任。

在Re:Invent2018上,AWS宣布了两项新的Lambda功能。这些使开发人员能够构建自定义运行时,并在函数之间共享和管理公共代码。

2019年9月,AWS宣布对私有网络内Lambda功能的冷启动进行了重大改进,从而提高了功能启动性能,提高了弹性网络接口的使用效率,减少了VPC冷启动。

在Re:Invent2019年,AWS宣布推出一项名为Amazon RDS Proxy的新服务。位于应用程序和关系数据库之间的完全托管数据库代理。它高效地汇集和共享数据库连接,以提高应用程序的可伸缩性。

将这些服务组合在一起,可以使用PHP和关系数据库构建安全、高效、可伸缩的无服务器应用程序。

自定义运行时API是一个简单的接口,用于支持以任何编程语言或特定语言版本执行Lambda函数。自定义运行时API需要一个称为引导的可执行文本文件。引导文件负责代码和Lambda环境之间的通信。

要创建自定义运行时,您必须首先在与Lambda执行环境兼容的Amazon Linux环境中编译所需版本的PHP。要执行此操作,请按照以下分步说明进行操作。

下面的文件是一个基本PHP引导文件的示例。此示例用于说明目的,因为没有发生错误处理或抽象。要确保正确处理异常,请在构建生产自定义运行时参考运行时API文档。

#!/opt/bin/php<;?PHP//这将调用Composer的自动加载器,这样我们就可以使用GUZZE和任何其他我们需要的第三方库。需要__DIR__。';/vendor/autoload.php;//这是请求处理循环。除非出现不可恢复的故障,否则此循环将一直运行,直到环境关闭。do{//向运行时API请求要处理的请求。$request=getNextRequest();//从_HANDLER环境变量获取函数名称,并确保函数的代码可用。$handlerFunction=ARRAY_SLICE(EXPLODE(';.';,$_ENV[';_HANDLER';]),-1)[0];REQUIRED_ONCE$_ENV[';LAMBDA_TASK_ROOT';]。';/src/';。$handlerFunction。';.php;//执行所需函数并获取响应。$Response=$handlerFunction($request[';payload';]);//将响应提交回运行时接口。sendResponse($request[';invocationId';],$Response);}While(TRUE);函数getNextRequest(){$Client=NEW\GuzzleHttp\Client();$Response=$Client->;GET(';http://';。$_ENV[';AWS_Lambda_Runtime_API';]。';/2018-06-01/runtime/invocation/next';);返回[';invocationId';=>;$response->;getHeader(';Lambda-Runtime-Aws-Request-Id';)[0],';有效负载';=>;json_decode((String)$Response->;getBody(),true)];}函数sendResponse($invocationId,$Response){$Client=NEW\GuzzleHttp\Client();$Client->;发布(';http://';。$_ENV[';AWS_Lambda_Runtime_API';]。';/2018-06-01/运行时/调用/';。$invocationId。';/Response';,[';Body';=>;$Response]);}

#!/opt/bin/php声明指示程序加载器使用为Amazon Linux编译的PHP二进制文件。

按照以下步骤将引导包和编译后的PHP二进制文件打包成`runtime.zip`。

运行时引导使用基于HTTP的本地接口。这将检索每个Lambda函数调用的事件有效负载,并返回函数的响应。此引导文件使用非常流行的PHP HTTP客户端GUZLE向自定义运行时API发出请求。GUZLE软件包是使用Composer软件包管理器安装的。以这种方式安装包创建了一种机制,用于随着应用程序的发展合并其他库和依赖项。

Lambda层提供了一种集中管理跨多个功能共享的代码和数据的机制。当Lambda函数配置了层时,层的内容会放入执行环境的/opt目录中。您可以在函数的部署包中包含自定义运行时,也可以将其作为层包含。Lambda执行部署包中的引导文件(如果可用)。如果没有,Lambda将在函数层中查找运行时。目前有几个开放源码PHP运行时层可用,最值得注意的是:

以下步骤展示了如何将之前创建的`runtime.zip`和`vendor.zip`二进制文件发布到Lambda层,并使用它们通过PHP运行时构建Lambda函数:

使用AWS命令行界面(CLI)发布先前创建的二进制文件中的图层。

记下每个命令的LayerVersionArn输出值(例如,下一步需要使用的arn:aws:lambda:eu-west-1:XXXXXXXXXXXX:layer:PHP-example-runtime:1),)。

您可以通过AWS CLI、AWS无服务器应用程序模型(SAM)或直接在AWS管理控制台中创建Lambda函数。要使用控制台执行此操作,请执行以下操作:

在Function Name字段中输入“PHPHello”,然后在Runtime字段中选择Provide Your Our Bootstrap。然后选择创建函数。

选择提供层版本ARN,然后将步骤1中的自定义运行时层的ARN复制并粘贴到层版本ARN字段中。

在function Code部分,创建一个名为src的新文件夹,并在其中创建一个名为index.php的新文件。

在处理程序输入字段中插入“index”。这将指示Lambda在调用时运行索引函数。

选择页面右上角的Test,在Event Name字段中输入“PHPTest”。在事件有效负载字段中输入以下内容,然后选择创建:{";name";:";world";}。

您可以看到,事件负载“name”值用于返回“hello world”。它取自提供给lambda函数的$data[';name';]参数。日志输出提供有关用于执行代码的实际持续时间、计费持续时间和内存量的详细信息。

这篇文章解释了如何使用Lambda层和自定义运行时API在PHP运行时创建Lambda函数。它介绍了可随应用流量扩展的无服务器LAMP堆栈的架构。

Lambda允许具有混合运行时的函数相互交互。现在,PHP开发人员可以加入其他专注于交付代码的无服务器开发团队。有了无服务器技术,您不再需要考虑重启网络主机、扩展或托管。