Déployer une application Laravel Serverless avec stockage des sessions et du cache applicatif dans DynamoDB

Published in BrefDynamoDBLaravelServerlessCache on Aug 25, 2020

On va repartir du code du post précédent introduisant le déploiement d’une application Laravel Serverless avec stockage des sessions dans DynamoDB, mais on va l’améliorer et ajouter la gestion du cache applicatif dans DynamoDB.

Utilisation de Async AWS

Cette notion est désormais très répandue, les performances d’une Lambda dépendent également du poids de l’artefakt que vous déployez sur Lambda : https://docs.aws.amazon.com/fr_fr/lambda/latest/dg/best-practices.html

De ce fait, on ne va plus utiliser le SDK AWS qui inclue l’ensemble des services, mais n’ajouter que le strict nécessaire.

Dans notre cas, nous avons besoin de lire et écrire dans une table DynamoDB à partir de notre application.

AsyncAws for Laravel

Nous allons utiliser pour cela Async AWS, et il y a un package spécifique pour DynamoDB et en relation avec Laravel : async-aws/illuminate-cache

Suite à cela, il est nécessaire d’ajuster la configuration du cache pour utiliser le nouveau driver :

https://miro.medium.com/max/712/1*CwbNmiz1KLiHd2does_OQw.png

Exemple d’utilisation du cache applicatif

On va désormais utiliser DynamoDB comme cache applicatif. Pour cela, rien de plus simple, car une grosse partie de la configuration a déjà été effectuée pour le stockage des sessions.

Usecase

A chaque nouvelle session, on va incrémenter une valeur “connected” dans notre cache applicatif.

A chaque expiration d’une session, on va décrémenter cette même valeur “connected” dans notre cache applicatif.

DynamoDB TTL

Rappelez vous que nous utilisons la feature TTL de DynamoDB, c’est à dire que l’item sera supprimé de manière automatique par DynamoDB à l’issue du TTL :

https://miro.medium.com/max/1400/1*YR_VJbBOtdT2c7jDi98J4A.png

https://miro.medium.com/max/1342/1*hExk-5IsD-X_grW54LeMnQ.png

DynamoDB Stream

De plus, grâce aux streams, nous allons pouvoir être en capacité lorsqu’une nouvelle session est créée, et lorsqu’une session est périmée — l’item correspondant étant supprimé à l’issue du TTL.

Plus d’informations sur DynamoDB Stream

Nous allons donc créer une nouvelle lambda qui va écouter l’event DynamoDB Stream, et qui agira en conséquence s’il s’agit d’un nouvel item ou de la suppression d’un item.

https://miro.medium.com/max/1046/1*mVDl6qa99pBB_hrngkWAvQ.png

Il faut également activer le Stream côté DynamoDB, dans notre cas nous avons besoin du minimum d’information au sein de l’event envoyé.

https://miro.medium.com/max/432/1*NAD1M7XVFZ8uLBtvnRa0BQ.png

Au sein de notre handler, il n’y a plus qu’à y développer la logique de notre use case :

https://miro.medium.com/max/1214/1*ZB_4gEo6MWRpC1GJ1bOaFQ.png

A noter les éléments de debug — dump à supprimer

Voilà

https://miro.medium.com/max/1400/1*SiTY-hhEtcH1hJceK2hS4A.png

Il ne reste plus qu’à mettre à jour notre home pour y ajouter l’affichage de notre valeur de cache “connected”.

Pour conclure, je vous l’avoue, pour avoir en finalité le nombre de connecté simultané, nous aurions pu faire un count sur le nombre d’item de session, mais ce usecase permet de voir les 2 côtés.

Le code est accessible ici : https://github.com/pmayet/laravel-lambda-5min/compare/dynamodb-session-improve

Le résultat est visible ici : https://3c3fygo941.execute-api.eu-west-1.amazonaws.com/

Enfin comme évoqué précédemment, point d’importance avant de stocker les sessions ou le cache applicatif dans DynamoDB dans un environnement de Production, pensez bien à stresser votre application afin de déterminer comme il faut le provisionning de votre table DynamoDB en configurant le ReadCapacity et le WriteCapacity, bien sûr vous pouvez appliquer de l’autoscaling, mais sur des sessions ou du cache applicatif, le temps de l’autoscale risque d’être problématique.

Je vous propose de poursuivre mes posts sur les sujets suivants :

  • Traitements de queue SQS au sein de la même application
  • Traitements de queue SQS entre applications tierces (micro-services)
  • Gérer des évènements asynchrones avec un délai supérieur à 15min (limite de SQS)
  • Déploiement via Gitlab CI
  • Déploiement via Github Action
  • Parsing d’email via SES
  • Gestion des migrations de base de données
  • Connexion à RDS
  • Indexation Elastic en asynchrone via Laravel Scout

N’hésitez pas à m’indiquer quels cas d’architecture vous souhaiteriez que j’aborde.

A vos commentaires et critiques !