PHP sem servidor no AWS Lambda

Olá pessoal. Na segunda-feira, a primeira lição será realizada no novo grupo do curso "Backend PHP Developer" . Nesse sentido, continuamos a publicar material útil sobre o assunto. Vamos começar.



Como Simon Wordley , acredito que a computação sem servidor é uma área extremamente interessante, principalmente por causa do sistema de pagamento granular (pague apenas quando seu código é executado), e você não precisa se preocupar com a manutenção e preparação de servidores e contêineres. Tanto é assim que trabalho com o PHP Runtime aberto para Apache OpenWhisk , cuja versão comercial está disponível como um dos recursos do IBM Cloud .

Existem outros provedores sem servidor, e o AWS Lambda é líder de mercado, mas até recentemente, o suporte ao PHP era extremamente pesado e despretensioso. Isso mudou no final de 2018 com a nova API de tempo de execução Lambda e suporte de camada .

Vamos dar uma olhada nos aspectos práticos do PHP sem servidor no Lambda com o Serverless Framework .

TL; DR


O código fonte de um simples Hello World está no meu repositório lambda-php no Github. Vá para a seção Notas e podemos continuar.

Tempo de execução php


A API de tempo de execução permite que você use qualquer tempo de execução com o Lambda. De certa forma, isso é semelhante ao OpenWhisk, pois há uma API HTTP entre a plataforma sem servidor e o tempo de execução. Há uma grande diferença de que, com o Lambda, o tempo de execução envia uma solicitação à plataforma para receber os dados da chamada, enquanto o OpenWhisk chama o terminal que o tempo de execução deve fornecer. Para obter mais informações, consulte a postagem no blog de Michael Moussa na AWS que me inspirou a fazer o trabalho.

Para começar, precisamos do tempo de execução do PHP para o Lambda. Ele consistirá em um executável PHP, código PHP para chamar uma função sem servidor e um arquivo de bootstrap , conforme exigido pela plataforma. Dessas três coisas, coletamos uma camada. As camadas podem ser reutilizadas em contas diferentes, por isso estou surpreso que a AWS não nos forneça uma conta PHP. Incrível, mas verdadeiro, eles não usam o PHP 7.3, então teremos que construir o nosso.
Todos os arquivos que colocamos no diretório layer/php em nosso projeto.

Construindo um executável PHP


Precisamos de um executável PHP que funcione dentro de contêineres Lambda. A maneira mais fácil de fazer isso é compilá-lo na mesma plataforma que o Lambda, portanto, usaremos o EC2. O artigo de Michael explica como fazer isso, e agrupei esses comandos no script compile_php.sh e , em seguida, para copiá-lo para uma instância do EC2, execute e copie o arquivo executável de volta para o meu computador:

 $ export AWS_IP=ec2-user@{ipaddress} $ export SSH_KEY_FILE=~/.ssh/aws-key.rsa $ scp -i $SSH_KEY_FILE compile_php.sh $AWS_IP:doc/compile_php.sh $ ssh -i $SSH_KEY_FILE -t $AWS_IP "chmod a+x compile_php.sh && ./compile_php.sh 7.3.0" $ scp -i $SSH_KEY_FILE $AWS_IP:php-7-bin/bin/php layer/php/php 


Essa abordagem a tornará bem reproduzível e, com sorte, apenas atualizará para novas versões do PHP.

Bootstrapping


Como usamos a API de tempo de execução, precisamos de um arquivo de bootstrap . O próprio Lambda exige esse nome para especificar o arquivo; ele responde a uma chamada de função que corresponde às imagens chamando a API em um loop.

Em essência, precisamos estar em um loop e chamar o terminal /next para entender o que chamar a seguir, chamá-lo e enviar a resposta ao terminal /response .
A AWS fornece um exemplo no BASH usando curl :

 while true do HEADERS="$(mktemp)" # Get an event EVENT_DATA=$(curl -sS -LD "$HEADERS" -X GET "http://${AWS_LAMBDA_RUNTIME_API}/2018-06-01/runtime/invocation/next") REQUEST_ID=$(grep -Fi Lambda-Runtime-Aws-Request-Id "$HEADERS" | tr -d '[:space:]' | cut -d: -f2) # Execute the handler function from the script RESPONSE=$($(echo "$_HANDLER" | cut -d. -f2) "$EVENT_DATA") # Send the response curl -X POST "http://${AWS_LAMBDA_RUNTIME_API}/2018-06-01/runtime/invocation/$REQUEST_ID/response" -d "$RESPONSE" done 


Queremos fazer o mesmo em PHP, e embora eu possa escrever por mim mesmo, o Pariksit Agnihotri já está à minha frente no PHP-Lambda-Runtime / runtime.php , então copiamos isso para layer/php/runtime.php . Na minha versão, fiz várias alterações, adicionei json_encoding e aprimorei o manipulador de erros.
A layer/php/bootstrap arquivo layer/php/bootstrap muito simples, e tudo o que é necessário é executar o executável PHP com este arquivo:

 #!/bin/sh cd $LAMBDA_TASK_ROOT /opt/php /opt/runtime.php 


Isso é tudo. Agora temos três arquivos em layer / php:

  • php - arquivo executável em php ;
  • runtime.php - arquivo de trabalho da API em tempo de execução;
  • bootstrap é o arquivo Lambda necessário.


Como resultado, tudo isso se tornará uma camada PHP (camada) em nosso aplicativo Lambda.

Configurar estrutura sem servidor


A estrutura sem servidor fornece configuração e implantação repetíveis de um aplicativo sem servidor. Sou fã desse conceito e quero usar mais dessas ferramentas. Usaremos o Framework sem servidor para o nosso PHP Hello World.
Como não há um modelo conveniente para aplicativos em PHP no Serverless Framework, simplesmente criamos o arquivo serverless.yml no diretório com o nosso projeto.
Para iniciantes, o mais básico:

 service: php-hello-world provider: name: aws runtime: provided region: eu-west-2 memorySize: 128 


Chamaremos nosso aplicativo php-hello-world e usaremos a AWS como provedor. Desde que estou no Reino Unido, estabeleci a região de Londres . Como não precisamos de muita memória, 128 MB serão suficientes.
O tempo de execução geralmente é o idioma em que você deseja que sua função seja executada. Para usar a runtime API que nosso arquivo de bootstrap executará, defina esse campo como fornecido .
E você precisará de um arquivo .gitignore contendo:

 .serverless 


Como no git , não precisamos deste diretório.
Em seguida, vamos adicionar nossa camada ao serverless.yml adicionando:

 layers: php: path: layer/php 


Isso criará uma camada da AWS e fornecerá o nome PhpLambdaLayer , ao qual podemos referenciar em nossa função.

Vamos escrever a função Hello World
Agora podemos escrever nossa função PHP sem servidor. Isso deve ser inserido no arquivo handler.php :

 <?php function hello($eventData) : array { return ["msg" => "hello from PHP " . PHP_VERSION]; } 


A função pega informações sobre o evento e retorna uma matriz associativa.
Para informar a Serverless Framework sobre a implantação de nossa função, você precisa adicionar o seguinte ao arquivo serverless.yml :

 functions: hello: handler: handler.hello layers: - {Ref: PhpLambdaLayer} 


O Serverless Framework suporta várias funções para um aplicativo. Cada um deles tem um nome, neste caso, hello , e, no nosso caso, um manipulador, que é um nome de arquivo sem extensão, seguido por um ponto e, em seguida, o nome da função nesse arquivo. Portanto, o manipulador handler.hello significa que executaremos a função hello() em handler.php .
Por fim, também reportamos funções à nossa camada PHP para que ela possa executar o código PHP.

Implantação no Lambda


Para expandir nossa função com sua camada, executamos o seguinte comando:

 $ sls deploy 


Se o comando for executado pelo maior tempo possível, será obtida uma saída semelhante a esta:



Cumprimento da nossa função


Após a implantação, podemos chamar a função usando o comando:

 $ sls invoke -f hello -l 




E pronto!

Resumir


Com novas camadas e APIs de tempo de execução, agora você pode executar facilmente funções sem servidor PHP no Lambda. Esta é uma boa notícia para desenvolvedores de PHP vinculados à AWS.

Esperando seus comentários, amigos!

Source: https://habr.com/ru/post/pt453116/


All Articles