Funciones Serverless en PHP: AWS Lambda — de la teoría a la práctica avanzada
\n\nLa arquitectura Serverless dejó de ser una exótica hace tiempo, y PHP, gracias a herramientas como Bref y Laravel Vapor, se ha ganado un lugar firme en el mundo de la computación sin servidor. En este artículo, analizaremos técnicas avanzadas para trabajar con AWS Lambda en PHP: cómo vencer el arranque en frío, configurar el trabajo dentro de una VPC y procesar eficientemente eventos de S3 y SQS. El material está dirigido a desarrolladores que ya conocen los fundamentos del despliegue de aplicaciones PHP en Lambda.
\n\n1. Optimización del arranque en frío: de 2 segundos a 200 milisegundos
\n\nEl principal enemigo de las aplicaciones serverless en PHP es el arranque en frío. A diferencia de Node.js o Python, PHP requiere cargar el intérprete y el framework. Así es como se minimizan las demoras.
\n\n1.1. Uso de Bref y capas precompiladas
\n\nBref es el estándar de facto para ejecutar PHP en Lambda. Proporciona capas (Layers) listas con el intérprete de PHP. Para acelerar, use bref/extra-php-extensions y conecte solo las extensiones necesarias.
Ejemplo de configuración básica de serverless.yml:
\nservice: my-php-app\n\nprovider:\n name: aws\n runtime: provided.al2\n region: eu-central-1\n\nplugins:\n - ./vendor/bref/bref\n\nfunctions:\n api:\n handler: public/index.php\n layers:\n - ${bref:layer.php-81}\n events:\n - httpApi: '*'\n\n\n1.2. Carga diferida y almacenamiento en caché de configuraciones
\n\nNo cargue todo el framework (Laravel, Symfony) en cada solicitud. Use Laravel Octane con Swoole o RoadRunner, pero para Lambda es mejor Bref Laravel Bridge, que almacena en caché las configuraciones y rutas.
\n\nCódigo para almacenar en caché la configuración en bootstrap.php:
\n// public/index.php (punto de entrada para Lambda)\nrequire_once __DIR__ . '/../vendor/autoload.php';\n\n$app = require_once __DIR__ . '/../bootstrap/app.php';\n\n// Almacenamos en caché la configuración en el primer inicio\nif (! file_exists(__DIR__ . '/../bootstrap/cache/config.php')) {\n $app->make('config')->get('app');\n // Guardamos la configuración compilada\n file_put_contents(\n __DIR__ . '/../bootstrap/cache/config.php',\n '<?php return ' . var_export($app->make('config')->all(), true) . ';'\n );\n} else {\n $config = require __DIR__ . '/../bootstrap/cache/config.php';\n $app->instance('config', $config);\n}\n\n$kernel = $app->make(Illuminate\\Contracts\\Http\\Kernel::class);\n$response = $kernel->handle(\n $request = Illuminate\\Http\\Request::capture()\n);\n$response->send();\n$kernel->terminate($request, $response);\n\n\nConsejo: Establezca memorySize en 1024 MB y timeout en 30 segundos para un equilibrio entre velocidad y costo. Más memoria significa un procesador más rápido.
2. Trabajo con VPC: conexión a RDS y ElastiCache
\n\nLas funciones Lambda, por defecto, funcionan fuera de su VPC. Para acceder a bases de datos (RDS, Aurora) o caché (ElastiCache), es necesario colocar la función dentro de una VPC. Esto añade complejidad y aumenta el arranque en frío de 5 a 10 segundos.
\n\n2.1. Configuración de VPC en serverless.yml
\n\nfunctions:\n processUser:\n handler: src/handlers/userHandler.php\n layers:\n - ${bref:layer.php-81}\n vpc:\n securityGroupIds:\n - sg-0123456789abcdef0\n subnetIds:\n - subnet-abc123\n - subnet-def456\n events:\n - sqs:\n arn: arn:aws:sqs:eu-central-1:123456789012:user-queue\n\n\n2.2. Gestión de conexiones mediante PDO
\n\nUse RDS Proxy o ElastiCache para reutilizar conexiones dentro de un mismo contenedor Lambda.
\n\nEjemplo de clase para trabajar con la base de datos con reutilización