Comment tirer parti des caractéristiques de Serverless sans perdre le contrôle.
Raison
Le système principal de Simple Psychology, basé sur Ruby on Rails, fonctionne depuis plus de quatre ans. Au fur et à mesure que les affaires grandissent, les limites de l’application monolithique deviennent de plus en plus évidentes. Même avec la containerisation qui a considérablement amélioré sa capacité de charge et simplifié le processus de déploiement, pour les développeurs, au fil du temps, le couplage au sein du système est inévitablement de plus en plus sévère, et l’expérience de développement s’aggrave.
Dans ce contexte, nous avons d’abord essayé l’architecture de microservices. La forte cohésion des microservices peut résoudre efficacement le problème de couplage sévère du système sous la complexité actuelle des affaires. Cependant, si le temps passe, certains microservices complexes peuvent toujours évoluer vers une application monolithique avec un couplage interne sévère.
Nous avons donc continué à regarder vers l’avant et avons commencé à essayer Serverless.
Serverless, en termes simples, est un service de calcul entièrement géré piloté par des événements. Vous n’avez qu’à écrire le code métier, et le reste est confié au fournisseur de services.
Cela semble très simple, et c’est en effet très facile à mettre en œuvre. Mais le problème est qu’il est trop simple, de sorte qu’il n’y a aucun paradigme à se référer pour les besoins métier complexes.
Il existe de nombreux cadres matures pour les applications monolithiques, et la plupart de ces cadres peuvent également être utilisés dans les microservices. Mais lorsque cela concerne Serverless, vous tomberez soudainement dans une situation où il n’y a aucun cadre disponible. Bien que vous puissiez télécharger un cadre MVC en tant que “fonction super” capable de gérer plusieurs demandes, cela entraînera des difficultés dans le développement et la maintenance.
Serverless préconise qu’une fonction ne devrait résoudre qu’un seul problème, permettant aux développeurs de se concentrer sur les processus et les liens spécifiques métier, sans passer beaucoup de temps à se familiariser avec l’ensemble du système et des affaires pour une petite itération métier. Cependant, à mesure que le nombre de fonctions augmente, s’il n’y a pas de contraintes, les développeurs vont certainement se laisser aller, ce qui entraînera de nombreux problèmes fragmentés. Notre solution est d’établir un ensemble de mécanismes de contrainte artificiels pour rendre toutes les fonctions faciles à comprendre et à développer et à maintenir.
L’objectif principal de ce mécanisme est de permettre aux développeurs de comprendre et d’itérer rapidement les liens métier et de faciliter l’expansion de nouveaux commerces. (Parce que les tâches quotidiennes de Simple Psychology sont principalement l’optimisation de divers liens métier et la tentative de nouveaux commerces).
Guide de pratique
Ce guide de pratique n’est qu’une tentative interne de Simple Psychology, à titre de référence uniquement, et le bienvenue pour discuter et améliorer.
Tout d’abord, ce guide de pratique est basé sur la construction de Tencent Cloud, et n’est pas nécessairement adapté à d’autres fournisseurs de services. Nous utilisons principalement les services suivants :
Pour résoudre le problème de la fragmentation des fonctions, l’idée centrale de la pratique est :
Abstraire les fonctions en étapes métier déclenchées par des événements.
En même temps, basé sur la conception orientée domaine, nous avons abstrait les étapes métier en commandes
, et toutes les fonctions sont divisées en deux catégories : fonctions de traitement de commande
et fonctions de réponse à l'événement
.
Le processus de traitement de la commande
est comme suit :
- La
fonction de réponse à l'événement
transforme l’événement en une commande spécifique et la stocke dans la file d’attente de commande correspondante ; - La fonction de planification (en essence, une
fonction de réponse à la commande planifiée
) prend la commande de la file d’attente selon les règles définies ; - La commande prise est distribuée de manière asynchrone au
fonction de traitement de commande
correspondante ; - La
fonction de traitement de commande
termine la commande.
En fin de compte, nous avons établi les règles suivantes pour la dénomination des fonctions :
- Format de dénomination :
<NomDeType>--<NomDeDomaineMetier>--<NomDeRessource>--<NomDeCommande>
, un total de quatre niveaux ; - NomDeType est entièrement en majuscules, le reste est entièrement en minuscules ;
- Dans l’environnement de production, il y a les types suivants :
- PE Fonction de traitement de commande
- PC Fonction de réponse à la commande planifiée
- PI Fonction de réponse à la commande de la passerelle interne
- PO Fonction de réponse à la commande de la passerelle externe
- PW Fonction de réponse à la commande de la passerelle frontale
- PD Fonction de réponse à la commande de la passerelle arrière
- Dans l’environnement de test, la première lettre du type est
T
, commeTE
,TC
, etc. ; - Dans l’environnement de développement, la première lettre du type est
D
, commeDE
,DC
, etc. ; - Si le nom est composé de plusieurs mots, ils sont connectés avec
-
, commePE--user--user-account--create
.
Ainsi, le flux de travail réel pour les développeurs est le suivant :
- Si vous devez coopérer avec le client, commencez d’abord par créer ou modifier les données simulées de la passerelle API dans l’environnement de développement.
- Créez ou modifiez la fonction dans l’environnement de test et terminez l’acceptation des tests.
- Synchronisez le code de l’environnement de test vers l’environnement de production et terminez l’acceptation de la production.
Dans ce modèle de développement, une fonction ne peut être modifiée par qu’un seul développeur à la fois. Les développeurs peuvent décider de changer une ou plusieurs fonctions en fonction de la complexité des exigences.