runtime/bref

Bref运行时

维护者

详细信息

github.com/php-runtime/bref

源代码

资助包维护!
nyholm

0.4.0 2023-11-22 12:38 UTC

This package is auto-updated.

Last update: 2024-09-22 14:45:47 UTC


README

使用Bref在AWS Lambda上部署应用程序。

我们支持所有类型的应用程序。有关详细信息,请参阅以下部分。

  1. 安装和使用
  2. Symfony应用程序
  3. Laravel应用程序
  4. PSR-15应用程序
  5. 控制台应用程序
  6. PSR-11容器应用程序
    1. 本地调用处理程序
    2. 简化serverless.yml
    3. 类型化处理程序
    4. Symfony Messenger集成

如果您是Symfony Runtime组件的新手,请阅读主README中的更多内容。

安装

composer require runtime/bref

要开始,我们需要在项目根目录中有一个serverless.yml文件。我们还将使用./vendor/runtime/bref-layer插件。现在我们可以告诉AWS我们想要使用名为${runtime-bref:php-80}的“层”来运行我们的应用程序。

接下来,我们需要定义环境变量APP_RUNTIME,以便Runtime组件知道要使用哪个运行时。

# serverless.yml
service: my-app-name

plugins:
    - ./vendor/runtime/bref-layer # <----- Add the extra Serverless plugin

provider:
    name: aws
    region: eu-central-1
    runtime: provided.al2
    memorySize: 1792
    environment:
       APP_ENV: prod
       APP_RUNTIME: Runtime\Bref\Runtime
       BREF_LOOP_MAX: 100 # Optional


functions:
    website:
        handler: public/index.php
        layers:
            - ${runtime-bref:php-80}
        events:
            # Specify that we want HTTP requests
            -   httpApi: '*'

这就是全部内容!

我们使用此文件来支持各种应用程序。我们唯一在events中更改的事情是,假设我们想监听S3或新SQS消息的更改。或者,我们可以让此函数由系统中的另一个应用程序使用Bref\Event\Handler来调用。

Symfony应用程序

如果您需要Bref的一些额外功能,请使用以下命令安装:

composer req bref/bref

使用标准的Symfony 5.3+ public/index.php

// public/index.php

use App\Kernel;

require_once dirname(__DIR__).'/vendor/autoload_runtime.php';

return function (array $context) {
    return new Kernel($context['APP_ENV'], (bool) $context['APP_DEBUG']);
};

您不需要做任何特殊的事情。

这里有一个示例应用程序。使用此运行时,您可以在本地开发和生产中使用完全相同的应用程序。

Laravel应用程序

如果您需要Bref的一些额外功能,请使用以下命令安装:

composer req bref/bref

要运行Laravel应用程序,您需要更新您的入口控制器,使其看起来像这样

// public/index.php

use Illuminate\Contracts\Http\Kernel;

define('LARAVEL_START', microtime(true));

require_once dirname(__DIR__).'/vendor/autoload_runtime.php';

return function (): Kernel {
    static $app;

    if (null === $app) {
        $app = require dirname(__DIR__).'/bootstrap/app.php';
    }

    return $app->make(Kernel::class);
};

现在您已经在AWS Lambda上启动并运行了!

有关如何在本地运行此应用程序的信息,请参阅runtime/laravel

PSR-15应用程序

如果您需要Bref的一些额外功能,请使用以下命令安装:

composer req bref/bref

Bref使用nyholm/psr7来提供PSR-7和PSR-15体验。有关如何在本地运行您的应用程序的信息,请参阅runtime/psr-nyholm

以下代码是一个使用Runtime组件的PSR-15应用程序示例。如果它在本地工作,它将在AWS Lambda上工作。

// public/index.php

use Nyholm\Psr7\Response;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\RequestHandlerInterface;

require_once dirname(__DIR__).'/vendor/autoload_runtime.php';

return function () {
    return new class implements RequestHandlerInterface {
        public function handle(ServerRequestInterface $request): ResponseInterface
        {
            $name = $request->getQueryParams()['name'] ?? 'world';

            return new Response(200, [], "Hello $name");
        }
    };
};

控制台应用程序

使用标准的Symfony 5.3+ bin/console

// bin/console

use App\Kernel;
use Symfony\Bundle\FrameworkBundle\Console\Application;

require_once dirname(__DIR__).'/vendor/autoload_runtime.php';

return function (array $context) {
    $kernel = new Kernel($context['APP_ENV'], (bool) $context['APP_DEBUG']);

    return new Application($kernel);
};
# serverless.yml

# ...

functions:
    console:
        handler: bin/console
        timeout: 120
        layers:
           - ${runtime-bref:php-80}
        events:
            - schedule:
                rate: rate(30 minutes)
                input: '"app:invoice:send"'

PSR-11容器

PSR-11容器很棒。它在内部微服务中特别出色,在这些微服务中,您不需要处理HTTP或安全性。应用程序只需使用AWS Lambda API客户端(例如aws/aws-sdk-phpasync-aws/lambda)调用微服务。它对于响应S3或SQS事件也非常出色。

我们首先需要的是一个返回PSR-11容器的文件。下面是Symfony的一个示例。

// bin/container.php

use App\Kernel;

require_once dirname(__DIR__).'/vendor/autoload_runtime.php';

return function (array $context) {
    $kernel =  new Kernel($context['APP_ENV'], (bool) $context['APP_DEBUG']);
    $kernel->boot();

    return $kernel->getContainer();
};

现在我们编写一个实现Bref\Event\Handler的类/服务。

namespace App\Lambda;

use Bref\Context\Context;
use Bref\Event\Handler;

class HelloWorld implements Handler
{
    public function handle($event, Context $context)
    {
        return 'Hello ' . $event['name'];
    }
}

现在我们需要更新serverless.yml,以表示“使用bin/container.php获取容器,然后加载服务App\Lambda\HelloWorld”。

# serverless.yml

# ...

functions:
    hello:
        handler: bin/container.php:App\Lambda\HelloWorld
        layers:
            - ${runtime-bref:php-80}

当部署时,可以通过以下方式调用

serverless invoke --function hello --data '{"name":"Tobias"}'

本地调用处理程序

从容器中使用服务可以使处理程序非常容易进行单元测试。但是,如果您很懒,您可能希望从CLI本地调用它们。

运行以下命令以调用App\Lambda\HelloWorld服务。

./vendor/bin/bref-local-handler.php ./bin/container.php:App\\Lambda\\HelloWorld

如果您的服务期望某些事件数据,请将其作为JSON字符串或包含JSON的文件的路径添加。

./vendor/bin/bref-local-handler.php ./bin/container.php:App\\Lambda\\HelloWorld '{"foo":"bar"}'

./vendor/bin/bref-local-handler.php ./bin/container.php:App\\Lambda\\HelloWorld example/input.json

简化serverless.yml

语法 handler: bin/container.php:App\Lambda\HelloWorld 可能有点难写,但你可以添加一个名为 FALLBACK_CONTAINER_FILE 的环境变量,其中包含我们可以获取PSR-11容器的文件。这可能有助于serverless.yml文件更加自然地读取。

 # serverless.yml

 provider:
     name: aws
     runtime: provided.al2
     # ...
     environment:
        APP_ENV: prod
        APP_RUNTIME: Runtime\Bref\Runtime
+       FALLBACK_CONTAINER_FILE: bin/container.php
        BREF_LOOP_MAX: 100 # Optional

 functions:
     hello:
-        handler: bin/container.php:App\Lambda\HelloWorld
+        handler: App\Lambda\HelloWorld
         layers:
           - ${runtime-bref:php-80}

类型化处理程序

为了更好地与不同的AWS事件集成,可以使用“类型化处理器”。这些是实现 Bref\Event\Handler 并提供一些辅助方法或类的类。

要使用它们,您需要安装Bref。

composer req bref/bref

我们使用与上面相同的PSR-11配置,并编写自定义处理器,如下所示:

namespace App\Lambda;

use Bref\Context\Context;
use Bref\Event\S3\S3Event;
use Bref\Event\S3\S3Handler;

class S3FileCreated extends S3Handler
{
    public function handleS3(S3Event $event, Context $context): void
    {
        $bucketName = $event->getRecords()[0]->getBucket()->getName();
        $fileName = $event->getRecords()[0]->getObject()->getKey();

        // do something with the file
    }
}
# serverless.yml

# ...

functions:
    s3_photos:
        handler: bin/container.php:App\Lambda\S3FileCreated
        layers:
            - ${runtime-bref:php-80}
        events:
            - s3:
                  bucket: photos
                  event: s3:ObjectCreated:*

有关不同类型处理器的更多信息,请参阅Bref文档

Symfony Messenger集成

类似于上面的类型化处理器,如果您使用bref/symfony-messenger,您可能还需要定义一个工作函数。

# serverless.yml

# ...

functions:
    worker:
        handler: bin/container.php:Bref\Symfony\Messenger\Service\Sqs\SqsConsumer
        timeout: 120
        layers:
            - ${runtime-bref:php-80}
        events:
            - sqs:
                  batchSize: 1 # Only 1 item at a time to simplify error handling
                  arn: !GetAtt workqueue.Arn

resources:
    Resources:
        workqueue:
            Type: "AWS::SQS::Queue"
            Properties:
                QueueName: ${self:service}-workqueue
                VisibilityTimeout: 600