
Pourquoi parler de gouvernance des services?
Avec la popularité croissante d'Internet, l'architecture MVC traditionnelle est devenue de plus en plus gonflée et très difficile à maintenir à mesure que l'échelle des applications continue de s'étendre.
Nous devons prendre des mesures pour diviser un grand système en plusieurs applications en fonction des caractéristiques de l'entreprise. Par exemple, un grand système de commerce électronique peut inclure un système utilisateur, un système produit, un système de commande, un système d'évaluation, etc., et nous pouvons les séparer en plusieurs applications individuelles. Les caractéristiques de l'architecture multi-applications sont que les applications s'exécutent indépendamment et qu'elles ne peuvent pas s'appeler les unes les autres.
Bien que plusieurs applications résolvent le problème des applications gonflées, les applications sont indépendantes les unes des autres et les services ou codes communs ne peuvent pas être réutilisés.
Lien officiel
Pour un grand système Internet, il contient généralement plusieurs applications avec des services communs, et chaque application a une relation d'appel entre elles. En outre, il existe d'autres défis pour le système Internet à grande échelle, tels que la manière de gérer les utilisateurs en croissance rapide, de gérer les équipes de R&D pour itérer rapidement le développement du système, de maintenir la mise à niveau du système de manière stable, etc.
Par conséquent, afin de bien réutiliser les services et de maintenir les modules à développer facilement. Nous voulons que les services soient séparés de l'application. Un service n'est plus dans une application, mais est maintenu en tant que service séparé. L'application elle-même n'est plus une pile de modules gonflée, mais un composant de service modulaire.
Servitisation
CARACTÉRISTIQUES
Alors, quelle est la fonctionnalité de l'utilisation de "Servitization"?
- Une application se divise en services par les entreprises
- Le service individuel peut être déployé indépendamment
- Le service peut être partagé par plusieurs applications
- Les services peuvent communiquer entre eux
- L'architecture du système est plus claire
- Les modules de base sont stables et la mise à niveau des composants de service dans les unités peut éviter le risque de nouvelles versions fréquentes
- Facilité de développement et de gestion
- La maintenance peut être effectuée par une équipe individuelle avec un flux de travail et des responsabilités clairs
- Réutilisation des services, réutilisation des codes
- Très facile à étendre
Le défi de la servitisation
Après la servitisation du système, la dépendance du système est compliquée et le nombre d'interactions entre les services augmente. Dans le mode de développement de fpm
, parce que la mémoire résidente ne peut pas être fournie, chaque demande doit commencer à partir de zéro en commençant à charger un processus pour quitter le processus, ajoutant beaucoup de surcharge inutile. De plus, la connexion à la base de données ne peut pas être réutilisée et ne peut pas être protégée car fpm
est basé sur le processus et le nombre de processus fpm
détermine également le nombre de concurrents. Ce sont les problèmes que nous pose le simple développement fpm
. Donc, ce sont les raisons pour lesquelles Java
est plus populaire maintenant sur la plate-forme Internet par rapport à .NET
et PHP
. Hormis PHP non-memory resident
, de nombreux autres problèmes doivent être résolus.
- Plus de services, plus de complexité dans la gestion de la configuration
- Dépendances de services complexes
- Équilibrage de charge entre les services
- Extension de service
- Suivi des services
- Rétrogradation du service
- Authentification de service
- Service en ligne et hors ligne
- Documentation de service
......
Vous pouvez imaginer les avantages que la mémoire des résidents nous apporte.
Ne commencez l'initialisation du framework qu'une fois que nous pouvons nous concentrer sur le traitement des requêtes car le framework ne peut être initialisé en mémoire qu'au démarrage en une fois pour la mémoire résidente
Multiplexage de connexion , certains ingénieurs ne peuvent pas comprendre s'ils n'utilisent pas le pool de connexions, quelle est la conséquence de l'établissement de connexions pour chaque demande? Cela provoque trop de ressources backend dans les connexions. Pour certains services de base, tels que Redis, les bases de données, les connexions sont un drain coûteux.
Alors, y a-t-il une bonne solution? La réponse est oui, et de nombreuses personnes utilisent le framework appelé Swoft
. Swoft
est un framework RPC avec la Service Governance
. Swoft
est le premier framework à pile complète de coroutine de mémoire résidente PHP, basé sur le concept de base de Spring Boot
, la convention est supérieure à la configuration.
Swoft
offre un moyen plus élégant d'utiliser des services RPC
comme Dubbo
et Swoft
a de grandes performances similaires aux performances de Golang
. Voici le résultat du test de Swoft
performances Swoft
qui se produit sur mon PC
.

La vitesse de traitement est très étonnante dans le test de résistance ab
. Avec le processeur i7 generation 8
et la mémoire de 16GB
, 100000
requêtes n'utilisent que 5s
. Le temps est fondamentalement impossible à atteindre dans le mode de développement fpm
. Le test est également suffisant pour démontrer les hautes performances et la stabilité de Swoft
.
Gouvernance de service élégante
Dans le processus de gouvernance des microservices, l'enregistrement des services initiés auprès de clusters tiers, tels que consul / etcd, est souvent impliqué. Ce chapitre utilise le composant swoft-consul dans le framework Swoft pour implémenter l'enregistrement et la découverte des services.

Logique d'implémentation
<?php declare(strict_types=1); namespace App\Common; use ReflectionException; use Swoft\Bean\Annotation\Mapping\Bean; use Swoft\Bean\Annotation\Mapping\Inject; use Swoft\Bean\Exception\ContainerException; use Swoft\Consul\Agent; use Swoft\Consul\Exception\ClientException; use Swoft\Consul\Exception\ServerException; use Swoft\Rpc\Client\Client; use Swoft\Rpc\Client\Contract\ProviderInterface; class RpcProvider implements ProviderInterface { private $agent; public function getList(Client $client): array {
Dans un environnement distribué, en particulier un système distribué d'architecture de microservices, il est très courant qu'un système logiciel appelle un autre système distant. L'appelé d'un tel appel distant peut être un autre processus ou un autre hôte sur le réseau. La plus grande différence entre cet appel distant et l'appel interne du processus est que l'appel distant peut échouer ou se bloquer. Aucune réponse jusqu'à l'expiration du délai. Pire, s'il y a plusieurs appelants appelant le même service suspendu, il est très probable que le délai d'attente d'un service se propage rapidement à l'ensemble du système distribué, provoquant une réaction en chaîne qui consomme l'intégralité Une grande quantité de ressources dans les systèmes distribués. À terme, cela peut entraîner une paralysie du système.
Le mode Disjoncteur est conçu pour prévenir les catastrophes causées par de telles réactions en chaîne de type cascade dans les systèmes distribués.

En mode disjoncteur de base, pour garantir que le fournisseur n'est pas appelé lorsque le disjoncteur est à l'état ouvert, mais nous avons également besoin d'une méthode supplémentaire pour réinitialiser le disjoncteur après la reprise du service par le fournisseur. Une solution possible est que le disjoncteur détecte périodiquement si le service du fournisseur est repris. Une fois repris, le statut est défini pour se fermer. L'état est un état semi-ouvert lorsque le disjoncteur réessaye.
L'utilisation du fusible est simple et puissante. Il peut être annoté avec un @Breaker
. Le fusible du Swoft
peut être utilisé dans n'importe quel scénario, tel qu'un service est appelé. Il peut être déclassé ou non appelé lors de la demande d'un service tiers.
<?php declare(strict_types=1); namespace App\Model\Logic; use Exception; use Swoft\Bean\Annotation\Mapping\Bean; use Swoft\Breaker\Annotation\Mapping\Breaker; class BreakerLogic { public function loop(): string {
Restriction de débit, disjoncteur, déclassement de service Ceux-ci peuvent être soulignés à plusieurs reprises car ils sont vraiment importants. Lorsque le service ne fonctionne pas, il doit être interrompu. La restriction de débit est un outil pour se protéger. S'il n'y a pas de mécanisme d'autoprotection et que les connexions sont reçues, peu importe leur nombre, le serveur frontal se bloquera définitivement lorsque le trafic est très important alors que le serveur principal ne peut pas gérer toutes les connexions.
La restriction de flux est de limiter le nombre de demandes simultanées et le nombre de demandes lors de l'accès à des ressources rares, telles que les ventes flash, afin de réduire efficacement le pic et de lisser la courbe de flux. Le but de la restriction de flux est de limiter le taux d'accès simultané et les demandes simultanées, ou de limiter la vitesse de la demande dans une fenêtre de temps pour protéger le système. Une fois la limite de débit atteinte ou dépassée, les demandes peuvent être refusées ou mises en file d'attente.
La couche inférieure de la restriction de flux de Swoft
utilise l'algorithme du Swoft
jetons, et la couche sous-jacente s'appuie sur Redis
pour implémenter la restriction de flux distribué.
La restriction de flux Swoft limite non seulement les contrôleurs, elle limite également les méthodes dans n'importe quel bean et contrôle le taux d'accès des méthodes. L'exemple suivant est l'explication détaillée.
<?php declare(strict_types=1); namespace App\Model\Logic; use Swoft\Bean\Annotation\Mapping\Bean; use Swoft\Limiter\Annotation\Mapping\RateLimiter; class LimiterLogic { public function requestLimiter2(Request $request): array { $uri = $request->getUriPath(); return ['requestLimiter2', $uri]; } public function limiterFallback(Request $request): array { $uri = $request->getUriPath(); return ['limiterFallback', $uri]; } }
Cela prend en charge l' symfony/expression-language
. Si la vitesse est limitée, la méthode limiterFallback
définie dans fallback
sera appelée.
Avant de parler du centre de configuration, parlons du fichier de configuration. Nous n'y sommes pas étrangers. Il nous donne la possibilité de modifier dynamiquement le programme. Une citation de quelqu'un est:
Ajustement dynamique de l'assiette de vol du runtime du système!
Je peux appeler notre travail pour réparer des pièces sur des avions volant rapidement. Nous, les humains, sommes toujours incapables de tout contrôler et de tout prévoir. Pour notre système, nous devons toujours réserver certaines lignes de contrôle pour effectuer des ajustements lorsque nous en avons besoin, pour contrôler la direction du système (comme le contrôle des gris, le réglage de la restriction de débit), ce qui est particulièrement important pour l'industrie Internet qui accepte les changements.
Pour la version autonome, nous l'appelons la configuration (fichier); pour le système de cluster distribué, nous l'appelons le centre de configuration (système);
Qu'est-ce qu'un centre de configuration distribué exactement?
Avec le développement de l'entreprise et la mise à niveau de l'architecture des micro-services, le nombre de services et la configuration des programmes augmentent (divers micro-services, différentes adresses de serveur, divers paramètres), ainsi que la méthode traditionnelle du fichier de configuration et la méthode de la base de données ne peut pas répondre aux besoins des développeurs en gestion de configuration:
- Sécurité: La configuration suit le code source stocké dans la base de code, ce qui est facile à provoquer des fuites de configuration;
- Rapidité: modifiez la configuration et redémarrez le service pour prendre effet.
- Limitations: les ajustements dynamiques ne peuvent pas être pris en charge: par exemple, les commutateurs de journal, les commutateurs de fonction;
Par conséquent, nous devons configurer le centre pour gérer la configuration! Libérant les développeurs commerciaux de configurations complexes et encombrantes, ils n'ont qu'à se concentrer sur le code métier lui-même, ce qui peut améliorer considérablement le développement et l'efficacité opérationnelle. Dans le même temps, la configuration et la libération du package amélioreront encore le taux de réussite de la libération et fourniront un support solide pour le contrôle de réglage fin et la gestion d'urgence du fonctionnement et de la maintenance.
À propos des centres de configuration distribués, il existe de nombreuses solutions open source sur le Web, telles que:
Apollo est un centre de configuration distribué développé par le département framework de Ctrip. Il peut gérer de manière centralisée la configuration de différents environnements et différents clusters d'applications. Il peut être poussé vers la fin de l'application en temps réel après modification de la configuration. Il présente les caractéristiques d'une gestion normalisée des autorisations et des processus et convient aux scénarios de configuration et de gestion des microservices.
Ce chapitre utilise Apollo
comme exemple pour extraire la configuration et sécuriser les services de redémarrage à partir du centre de configuration distant. Si vous n'êtes pas familier avec Apollo
, vous pouvez d'abord consulter le Swoft
extension Swoft
Apollo
et lire la documentation officielle d' Apollo
.
Ce chapitre utilise Apollo
dans Swoft
comme exemple. Lorsque la configuration d' Apollo
change, redémarrez le service (http-server / rpc-server / ws-server). Voici un exemple d'agent:
<?php declare(strict_types=1); namespace App\Model\Logic; use Swoft\Apollo\Config; use Swoft\Apollo\Exception\ApolloException; use Swoft\Bean\Annotation\Mapping\Bean; use Swoft\Bean\Annotation\Mapping\Inject; class ApolloLogic { private $config; public function pull(): void { $data = $this->config->pull('application');
Ce qui précède est une simple traction de configuration Apollo, en plus de cette méthode, Swoft-Apollo
fournit plus de façons d'utiliser.
Lien officiel