Maison >développement back-end >tutoriel php >Construction d'un cluster de microservices PHP - Hyperf
Architecture des microservices
Le concept de microservices a été proposé par Martin Fowler en mars 2014 :
L'architecture des microservices est un modèle architectural qui préconise une seule application divisée en un ensemble de petits services, et les services se coordonnent et coopèrent les uns avec les autres pour offrir une valeur ultime aux utilisateurs. Chaque service s'exécute selon son propre processus indépendant et les services utilisent des mécanismes de communication légers pour communiquer entre eux. Chaque service est construit autour d'un métier spécifique et peut être déployé indépendamment dans des environnements de production, des environnements de type production, etc. De plus, un mécanisme de gestion de service unifié et centralisé doit être évité autant que possible. Pour un service spécifique, des langages et des outils appropriés doivent être sélectionnés pour le construire en fonction du contexte commercial.
La figure suivante est un schéma d'architecture de microservices d'un système de commerce électronique :
L'architecture de microservices présente les avantages suivants par rapport aux applications uniques :
1. Chaque service est relativement simple et se concentre uniquement sur une fonction commerciale
2. L'architecture du microservice est faiblement couplée et chaque service peut être testé, déployé, mis à niveau et publié indépendamment ; >
3. Chaque microservice peut être développé indépendamment par différentes équipes, et chacun peut choisir les langages et outils de programmation les meilleurs et les plus appropriés 4. Chaque service peut être nivelé en fonction des besoins. améliorer les capacités de concurrence du système. Il n'y a pas de solution miracle. Bien que l'architecture des microservices apporte de nombreux avantages, elle présente également les inconvénients suivants : 1. coût. Par exemple, une seule application peut n'avoir besoin d'être déployée que sur un petit cluster de services d'application, tandis qu'une architecture de microservices peut nécessiter la création/test/déploiement/exécution de dizaines de services indépendants et peut devoir prendre en charge plusieurs langages et environnements ; 🎜>2. En tant que système distribué, l'architecture des microservices introduit plusieurs autres problèmes, tels que la sérialisation des messages, le délai du réseau, le mécanisme asynchrone, le traitement de tolérance aux pannes, l'avalanche de services, etc. Complexité, telle que l'enregistrement du service, la découverte, le déclassement, le disjoncteur, etc. ;
4. Il y a des appels mutuels entre les services, ce qui pose d'énormes défis pour le dépannage des pannes du système.
On peut dire que ce sont précisément les systèmes dotés d'une architecture d'application traditionnelle qui sont devenus de plus en plus volumineux et confrontés à des problèmes difficiles à maintenir et à développer. Parallèlement, le développement en plein essor de la technologie de conteneurisation (Docker) et la maturité croissante des idées DevOps ont donné naissance à un nouveau style de conception architecturale : l'émergence de l'architecture des microservices.
RPC FrameworkChaque service dans une architecture de microservices n'est généralement pas sur la même machine, ni même dans le même environnement réseau, alors comment les microservices interagissent-ils les uns avec les autres ? L'appel est un problème urgent qui doit être résolu. Nous utilisons généralement le protocole RPC pour le résoudre : RPC (Remote Procedure Call), c'est-à-dire l'appel de procédure à distance, est un protocole de communication informatique. Ce protocole permet à un programme exécuté sur un ordinateur d'appeler un sous-programme sur un autre ordinateur sans que le programmeur ait à programmer en plus l'interaction. ——Wikipedia
implémente le cadre de protocole RPC, qui permet au serveur et à l'appelant de protéger divers détails sous-jacents, permettant à l'appelant d'appeler des fonctions (services) distants tout comme l'appel de fonctions locales. Le framework RPC fournit généralement la sérialisation, la désérialisation, la gestion du pool de connexions, l'équilibrage de charge, le basculement, la gestion des files d'attente, la gestion des délais d'attente, la gestion asynchrone et d'autres fonctions pour le serveur et le client. J'ai trouvé sur Internet un schéma illustrant le principe de fonctionnement du framework RPC :
Actuellement, selon les différentes technologies utilisées pour sérialiser les données, on peut le diviser en deux types : JSON-RPC et gRPC :1. JSON-RPC est un standard de protocole RPC léger basé sur le format JSON, qui peut être transmis sur la base du protocole HTTP ou directement sur la base du protocole TCP. L’avantage de JSON-RPC est qu’il est facile à utiliser et à lire.
2. gRPC est un framework RPC open source hautes performances à usage général. Il est développé par Google principalement pour les applications mobiles et conçu sur la base du protocole HTTP/2. (Protocol Buffers) protocole de sérialisation et prend en charge de nombreux langages de développement. gRPC présente les avantages d'une faible latence, d'une efficacité élevée, d'une évolutivité élevée et d'une prise en charge de la distribution.
ConsulDésormais, avec le framework RPC, nous ne pouvons considérer que les appels professionnels entre services sans prendre en compte les détails de transmission sous-jacents. À ce stade, si le service A souhaite appeler le service B, nous pouvons configurer l'adresse IP et le port du service B dans le service A, puis laisser les détails de transmission restants au framework RPC. Cela ne pose aucun problème lorsque l’échelle des microservices est petite, mais cela sera confronté à d’énormes défis lorsque l’échelle des services est grande et que plus d’une instance de chaque service est déployée. Par exemple, le service B dispose de trois instances déployées. À ce stade, le service A souhaite appeler le service B. Quelle adresse IP d'instance doit-il demander ? Si deux des trois instances déployées par le service B sont en panne, le service A peut toujours demander les instances suspendues et le service sera indisponible. Il est très rigide d'écrire des adresses IP et des ports dans des fichiers de configuration. L'architecture des microservices doit souvent garantir une haute disponibilité et une mise à l'échelle dynamique. Par conséquent, nous avons besoin d'un outil d'enregistrement et de découverte de services capable de modifier dynamiquement les informations sur les services et de trouver les adresses IP et les ports des services disponibles. Il existe actuellement de nombreux outils de découverte de services sur le marché, tels que Consul, ZooKeeper, Etcd, Doozerd, etc. Cet article prend principalement comme exemple le logiciel Consul. Consul est un logiciel de service qui prend en charge plusieurs centres de données, la découverte de services distribués à haute disponibilité et le partage de configuration. Il a été développé par HashiCorp en langage Go et est open source basé sur l'accord Mozilla Public License 2.0. Consul prend en charge les vérifications de l'état et permet aux protocoles HTTP, gRPC et DNS d'appeler des API pour stocker des paires clé-valeur. Voici le schéma d'architecture après l'introduction des outils d'enregistrement et de découverte de services : Dans cette architecture : Première instance de S-B Après le démarrage, enregistrez ses propres informations de service (principalement l'adresse IP et le numéro de port du service) dans Consul. Consul effectuera des contrôles de santé sur tous les services enregistrés pour déterminer quelles instances de service sont disponibles et lesquelles ne le sont pas. Après le démarrage de S-A, il peut obtenir les adresses IP et les ports de toutes les instances S-B saines en accédant à Consul, et mettre ces informations dans sa propre mémoire. S-A peut utiliser ces informations pour appeler S-B. S-A peut mettre à jour les informations de service de S-B stockées dans la mémoire en écoutant Consul. Par exemple, si S-B-1 raccroche, le mécanisme de vérification de l'état le marquera comme indisponible. Ces modifications d'informations seront surveillées par S-A, et S-A mettra à jour les informations de service de S-B-1 dans sa propre mémoire. On peut voir qu'en plus des fonctions d'enregistrement et de découverte de services, le logiciel Consul fournit également des fonctions de contrôle de santé et de notification de changement de statut. Hyperf Pour les développeurs Java, vous avez le choix entre des frameworks de microservices Dubbo et Spring Cloud assez matures. En tant que PHPer, j'ai utilisé Google pour vérifier "PHP + Microservices" et j'ai constaté qu'il y avait très peu de contenu connexe utile, aucune valeur de référence substantielle, et j'ai été infiniment déçu. . . Heureusement, certains experts ont implémenté Hyperf, le framework de coroutines PHP hautes performances et très flexible, basé sur l'extension Swoole, et ont fourni les composants associés de l'architecture des microservices. Hyperf est un framework de coroutine PHP hautes performances et très flexible basé sur Swoole 4.3+. Il dispose d'un serveur de coroutines intégré et d'un grand nombre de composants couramment utilisés. Ses performances sont qualitativement améliorées par rapport au traditionnel. framework basé sur PHP-FPM Tout en offrant des performances ultra élevées, il maintient également une évolutivité extrêmement flexible. Les composants standard sont implémentés sur la base de la norme PSR et basés sur une conception d'injection de dépendances puissante, il garantit que la plupart des composants ou classes sont remplaçables et. réutilisable. Ainsi, après avoir acquis les connaissances de base liées à l'architecture des microservices, j'ai utilisé le framework Hyperf pour créer un cluster de microservices basé sur PHP. Voici l'adresse du code source du projet : https://github.com/Jochen-. z/p…. Le projet est construit à l'aide de Dokcer. Le code docker-compose.yml est le suivant : Un conteneur Consul consul-server-leader est démarré ici en tant que composant d'enregistrement de service et de découverte de service. 1 et microservice-2 fournissent respectivement des opérations d'ajout et de division. En tant qu'appelant du service, l'application conteneur configure l'URL du conteneur consul-server-leader, obtient les adresses IP et les ports des services microservice-1 et microservice-2 en accédant à consul-server-leader, puis l'application appelle l'ajout et division via le protocole RPC. Le service informatique obtient les résultats et les renvoie à l'utilisateur. Le conteneur d'applications est une application Web qui déploie un projet Hyperf et fournit des services HTTP au monde extérieur. Par exemple, il existe une méthode add dans le contrôleur AppControllerIndexController : L'implémentation de add dans AppJsonRpcAdditionService : Hérite AbstractServiceClient pour créer une classe de requête client de microservice, et Hyperf aide en bas Nous avons implémenté les détails de l'interaction avec Consul et les fournisseurs de services. Nous n'avons besoin que de la méthode add dans la classe AdditionService pour appeler à distance les services fournis par le microservice-1 et le microservice-2. À ce stade, la construction du cluster de microservices PHP est terminée ! version: "3"
services:
consul-server-leader:
image: consul:latest
container_name: consul-server-leader
command: "agent -server -bootstrap -ui -node=consul-server-leader -client=0.0.0.0"
environment:
- CONSUL_BIND_INTERFACE=eth0
ports:
- "8500:8500"
networks:
- microservice
microservice-1:
build:
context: .
container_name: "microservice-1"
command: "php bin/hyperf.php start"
depends_on:
- "consul-server-leader"
volumes:
- ./www/microservice-1:/var/www
networks:
- microservice
tty: true
microservice-2:
build:
context: .
container_name: "microservice-2"
command: "php bin/hyperf.php start"
depends_on:
- "consul-server-leader"
volumes:
- ./www/microservice-2:/var/www
networks:
- microservice
tty: true
app:
build:
context: .
container_name: "app"
command: "php bin/hyperf.php start"
depends_on:
- "microservice-1"
volumes:
- ./www/web:/var/www
ports:
- "9501:9501"
networks:
- microservice
tty: true
networks:
microservice:
driver: bridge
volumes:
microservice:
driver: local
public function add(AdditionService $addition)
{
$a = (int)$this->request->input('a', 1); # 接受前端用户参数
$b = (int)$this->request->input('b', 2);
return [
'a' => $a,
'b' => $b,
'add' => $addition->add($a, $b) # RPC调用
];
}
class AdditionService extends AbstractServiceClient
{
/**
* 定义对应服务提供者的服务名称
* @var string
*/
protected $serviceName = 'AdditionService';
/**
* 定义对应服务提供者的服务协议
* @var string
*/
protected $protocol = 'jsonrpc-http';
public function add(int $a, int $b): int
{
return $this->__request(__FUNCTION__, compact('a', 'b'));
}
}
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!