Maison  >  Article  >  Java  >  Utiliser la technologie de conteneur de Docker pour présenter l'architecture de service du système DevOps - Architecture JAVA

Utiliser la technologie de conteneur de Docker pour présenter l'architecture de service du système DevOps - Architecture JAVA

php是最好的语言
php是最好的语言original
2018-07-27 11:59:403120parcourir
J'ai commencé à être exposé à la technologie des conteneurs basée sur Docker en 2015. Pendant plus de deux ans, en tant que praticien Docker DevOps, j'ai également été témoin du développement rapide du système technique de Docker. Cet article fait principalement un résumé simple basé sur le processus pratique d'architecture de microservices construit dans l'entreprise. J'espère donner quelques références aux étudiants DevOps qui explorent comment concevoir un système d'architecture de services dès les premiers stades du démarrage d'une entreprise, ou qui souhaitent avoir une compréhension préliminaire de l'architecture au niveau de l'entreprise.

Microservice et Docker

Concernant la configuration technique des startups, de nombreuses voix disent en gros que les startups doivent se mettre en ligne rapidement et faire des essais et des erreurs rapidement. Intégrez, développez et publiez rapidement en utilisant une seule application ou en séparant les applications front-end et back-end. Mais en réalité, les coûts cachés occasionnés par ce résultat seront plus élevés. Lorsque l'entreprise se développera et qu'il y aura plus de développeurs, elle sera confrontée au problème de l'efficacité du déploiement d'énormes systèmes et de l'efficacité de la collaboration en matière de développement. Ensuite, la structure est restructurée à travers le fractionnement des services, la séparation de la lecture et de l'écriture des données, des sous-bases de données et des sous-tables, etc. De plus, si cette méthode doit être réalisée de manière approfondie, elle nécessitera beaucoup de main d'œuvre et de matériel. ressources.

Ma suggestion personnelle est que DevOps devrait être basé sur votre propre jugement sur le développement actuel et à long terme de l'entreprise, et que vous pouvez utiliser l'architecture des microservices dès les premières étapes du projet, ce qui profitera à l'avenir générations.
Avec le développement de la communauté open source autour de Docker, le concept d'architecture de microservices peut avoir un meilleur plan de mise en œuvre. Et au sein de chaque application de microservice, l'architecture hexagonale de DDD (Domain-Drive Design) peut être utilisée pour la conception en service. Pour certains concepts sur DDD, vous pouvez également vous référer à plusieurs articles rédigés précédemment : Organisation de conception basée sur le domaine - concepts et architecture, organisation de conception basée sur le domaine - conception d'entités et d'objets de valeur, services de domaine, événements de domaine.

Division claire du domaine des microservices, mise en œuvre élégante des niveaux architecturaux au sein du service, IPC nécessaire entre les services via RPC ou basé sur des événements, et passerelle API pour le transfert des demandes de tous les microservices, résultats de demande non bloquants à fusionner. L'article suivant présentera en détail comment créer rapidement une architecture de microservices avec Docker avec les caractéristiques ci-dessus dans un environnement distribué.

Modèle de découverte de services

Si vous utilisez la technologie Docker pour créer un système de microservices, la découverte de services est un sujet inévitable. Il existe actuellement deux modes de découverte de services courants : le mode de découverte de client et le mode de découverte de serveur.
Mode de découverte de client
Le schéma d'architecture du mode de découverte de client est le suivant :
Utiliser la technologie de conteneur de Docker pour présenter larchitecture de service du système DevOps - Architecture JAVA

L'implémentation typique du mode de découverte de client est la technologie du système Netflix. Le client interroge toutes les instances de service disponibles à partir d'un centre de services d'enregistrement de service. Le client utilise un algorithme d'équilibrage de charge pour sélectionner l'une des multiples instances de service disponibles, puis effectue une demande. Une implémentation open source typique est Eureka de Netflix.

Netflix-Eureka
Le client d'Eureka adopte un mode d'auto-enregistrement. Le client doit être responsable du traitement de l'enregistrement et de la désenregistrement des instances de service et de l'envoi de battements de cœur.
Lorsque vous utilisez SpringBoot pour intégrer un microservice, l'enregistrement automatique peut être facilement réalisé en le combinant avec le projet SpringCloud. Ajoutez @EnableEurekaClient à la classe de démarrage du service pour enregistrer le service auprès du serveur Eureka configuré lorsque l'instance de service est démarrée et envoyez régulièrement des pulsations. L'équilibrage de charge côté client est implémenté par Netflix Ribbon. La passerelle de services utilise Netflix Zuul et le disjoncteur utilise Netflix Hystrix.

En plus du cadre de support pour la découverte de services, Netflix-Feign de SpringCloud fournit une interface déclarative pour gérer les demandes Rest de services. Bien entendu, en plus d'utiliser FeignClient, vous pouvez également utiliser Spring RestTemplate. Si vous utilisez @FeignClient dans le projet, le code sera plus lisible et l'API Rest sera claire en un coup d'œil.

La gestion de l'enregistrement et l'interrogation des instances de service se font toutes en appelant l'interface API REST fournie par Eureka au sein de l'application (bien entendu, il n'est pas nécessaire d'écrire cette partie du code lors de l'utilisation de SpringCloud-Eureka) . Étant donné que l'enregistrement et la désinscription du service sont demandés via le client lui-même, un problème majeur avec ce modèle est que différents services seront enregistrés pour différents langages de programmation et que la logique de découverte de services doit être développée séparément pour chaque langage de développement. De plus, la prise en charge des vérifications de l'état doit être configurée explicitement lors de l'utilisation d'Eureka.

Mode découverte côté serveur
Le schéma d'architecture du mode découverte côté serveur est le suivant :
Utiliser la technologie de conteneur de Docker pour présenter larchitecture de service du système DevOps - Architecture JAVA

Le client envoie un demande à l'équilibreur de charge, et l'équilibreur de charge envoie une demande au registre de services, transmettant la demande aux instances de service disponibles dans le registre. Les instances de service sont également enregistrées et désinscrites dans le registre. L'équilibrage de charge peut utiliser Haproxy ou Nginx. Les solutions courantes actuelles pour le mode de découverte côté serveur basé sur Docker sont Consul, Etcd et Zookeeper.

Consul
Consul fournit une API qui permet aux clients de s'inscrire et de découvrir des services. Sa cohérence est basée sur l'algorithme RAFT. Gérez les membres et diffusez des messages via le protocole Gossip du WAN pour compléter la synchronisation entre les centres de données et prendre en charge le contrôle d'accès ACL. Consul fournit également un mécanisme de vérification de l'état et prend en charge le service de stockage kv (non pris en charge par Eureka). Pour une introduction plus détaillée à Consul, veuillez vous référer à l'article que j'ai écrit précédemment : Déploiement du conteneur Docker du cluster Consul.

Etcd
Etcd sont tous fortement cohérents (CP qui satisfont CAP) et hautement disponibles. Etcd est également basé sur l'algorithme RAFT pour obtenir une forte cohérence de la synchronisation des données KV. Kubernetes utilise la structure KV d'Etcd pour stocker le cycle de vie de tous les objets.
Pour certains principes internes d'Etcd, vous pouvez lire l'analyse des principes d'etcd v3

Zookeeper
ZK a été utilisé pour la première fois dans Hadoop. Son système est très mature et est souvent utilisé dans Hadoop. grandes entreprises. Si vous disposez déjà de votre propre cluster ZK, vous pouvez envisager d'utiliser ZK comme votre propre centre d'enregistrement de services.
Zookeeper est identique à Etcd, avec une forte cohérence et une haute disponibilité. L'algorithme de consensus est basé sur Paxos. Pour la phase initiale d'une architecture de microservices, il n'est pas nécessaire d'utiliser un ZK plus lourd pour la découverte de services.

Enregistrement des services

Le registre des services est un composant important dans la découverte des services. En plus de Kubernetes et Marathon, leur découverte de services est un module intégré. Les services doivent être enregistrés dans le registre. Eureka, consul, etcd et ZK présentés ci-dessus sont tous des exemples de registres de services.
Il existe deux méthodes d'enregistrement typiques pour l'enregistrement des microservices dans le registre : le mode d'auto-enregistrement et le mode d'enregistrement tiers.

Modèle d'auto-inscription
Le client Netflix-Eureka ci-dessus est un exemple typique du modèle d'auto-inscription. Autrement dit, chaque instance de microservice elle-même doit être responsable de l’enregistrement et de la désinscription du service. Eureka fournit également un mécanisme de battement de cœur pour garantir l'exactitude des informations d'enregistrement. L'intervalle d'envoi de battement de cœur spécifique peut être configuré dans le SpringBoot du microservice.

Comme suit, lors de l'utilisation d'Eureka comme registre, il y aura des informations d'enregistrement de service lorsque le microservice (application SpringBoot) démarre :

Utiliser la technologie de conteneur de Docker pour présenter larchitecture de service du système DevOps - Architecture JAVA

De même, lorsque l'application est désactivée, l'instance de service doit se déconnecter activement des informations de l'instance :

Utiliser la technologie de conteneur de Docker pour présenter larchitecture de service du système DevOps - Architecture JAVA

La méthode d'auto-enregistrement est une méthode d'enregistrement de service relativement simple qui ne nécessite pas d'installations supplémentaires ou des agents. L’instance de microservice gère elle-même l’enregistrement du service. Mais les inconvénients sont également évidents. Par exemple, Eureka ne fournit actuellement que des clients Java, ce qui ne convient donc pas à l'expansion de microservices multilingues. Étant donné que le microservice doit gérer lui-même la logique d’enregistrement du service, la mise en œuvre du microservice couple également l’enregistrement du service et le mécanisme de pulsation. Les performances multilingues sont relativement médiocres.

Ici, je recommande à tout le monde un groupe d'apprentissage et d'échange en architecture. Numéro du groupe de communication et d'apprentissage : 478030634. Il partagera quelques vidéos enregistrées par des architectes seniors : Spring, MyBatis, analyse du code source Netty, principes de haute concurrence, hautes performances, architecture distribuée et microservices, optimisation des performances JVM, architecture distribuée, etc. sont devenus un système de connaissances nécessaire pour les architectes. Vous pouvez également recevoir des ressources d'apprentissage gratuites, et vous en bénéficiez actuellement beaucoup

Modèle d'inscription de tiers

Inscription de tiers, c'est-à-dire la gestion de l'inscription aux services (inscription, annulation des services) via un Un responsable de service dédié (Registar) est responsable. Registrator est une implémentation de gestionnaire de services open source. Le registrateur fournit un support de service de registre pour Etcd et Consul. Le registrateur, en tant que service proxy, doit être déployé et exécuté sur le serveur ou la machine virtuelle où se trouve le microservice. La méthode d'installation la plus simple consiste à l'exécuter en tant que conteneur via Docker.
Le schéma d'architecture du modèle d'enregistrement tripartite est le suivant :

Utiliser la technologie de conteneur de Docker pour présenter larchitecture de service du système DevOps - Architecture JAVA

En ajoutant un gestionnaire de service, les instances de microservice ne s'enregistrent plus directement et ne se déconnectent plus avec l'enregistrement centre. Le gestionnaire de services (Registar) découvre les instances de service disponibles en s'abonnant aux services, en suivant les battements de cœur, en s'inscrivant auprès du centre d'enregistrement (consul, etc.), en désenregistrant les instances et en envoyant des battements de cœur. De cette manière, le découplage des composants de découverte de services et de l'architecture des microservices peut être réalisé.

Registrator coopère avec Consul et Consul Template pour créer un centre de découverte de services. Vous pouvez vous référer à : Architecture évolutive DR CoN : Docker, Registrator, Consul, Consul Template et Nginx. Cet article fournit un exemple d'utilisation de Nginx pour l'équilibrage de charge. Dans le processus de mise en œuvre spécifique, Haproxy ou d'autres solutions peuvent également être utilisées à la place.

Résumé

En plus des technologies de découverte de services ci-dessus, Kubernetes est livré avec son propre module de découverte de services, qui est responsable du traitement de l'enregistrement et de la désinscription des instances de service. Kubernetes exécute également un agent sur chaque nœud de cluster pour implémenter la découverte des routeurs côté serveur. Si la technologie d'orchestration utilise k8n, vous pouvez utiliser l'ensemble complet de solutions de microservices Docker de k8n. Ceux qui sont intéressés par k8n peuvent lire la conception de l'architecture et les principes fondamentaux de Kubernetes.

Dans la sélection technologique actuelle, la chose la plus importante est de porter des jugements raisonnables basés sur les caractéristiques de développement futur de l'entreprise et du système.

  • En théorie CAP. Eureka satisfait AP, Consul est CA, ZK et Etcd sont CP. Eureka et Consul peuvent garantir la disponibilité dans des scénarios distribués. La création d'un service Eureka sera relativement plus rapide car il n'est pas nécessaire de créer un centre d'enregistrement de service à haute disponibilité supplémentaire. Lors de l'utilisation d'instances de serveur à petite échelle, l'utilisation d'Eureka peut permettre d'économiser certains coûts.

  • Eureka et Consul fournissent tous deux des composants WebUI qui peuvent afficher les données d'enregistrement du service. Consul fournit également un stockage KV et prend en charge les interfaces http et DNS. Pour les startups qui commencent à créer des microservices, ces deux-là sont recommandés.

  • En termes de multi-centres de données, Consul est livré avec sa propre solution WAN de centre de données. Ni ZK ni Etcd ne prennent en charge les fonctionnalités multi-centres de données et ne nécessitent un développement supplémentaire.

  • En termes de multilingue, Zookeeper doit utiliser l'API client qu'il fournit, et la prise en charge multilingue est faible. Etcd et Eureka prennent tous deux en charge http, et Etcd prend également en charge grpc. En plus de http, Consul fournit également un support DNS.

  • En termes de sécurité, Consul et Zookeeper prennent en charge ACL, et Consul et Etcd prennent en charge le canal sécurisé HTTPS.

  • SpringCloud dispose actuellement d'un support correspondant pour Eureka, Consul, Etcd et ZK.

  • Consul, comme Docker, est implémenté en langage Go. Les applications de microservices basées sur le langage Go peuvent donner la priorité à l'utilisation de Consul.

Mécanisme IPC entre services

Après avoir résolu le problème de découverte de services selon le système d'architecture des microservices. Vous devez choisir un mécanisme de communication approprié entre les services. Si vous êtes dans une application SpringBoot, utiliser l'API REST basée sur le protocole HTTP est une solution synchrone. De plus, l'API de style Restful peut rendre chaque application de microservice plus orientée vers les ressources, et l'utilisation de protocoles légers a également été préconisée par les microservices.

Si chaque microservice utilise l'idée DDD (Domain-Driven Design), alors chaque microservice doit essayer de ne pas utiliser le mécanisme RPC synchrone. Les méthodes asynchrones basées sur des messages telles qu'AMQP ou STOMP seraient un bon choix pour coupler de manière lâche les dépendances entre les microservices. Actuellement, il existe de nombreuses options pour les frameworks de publication/sous-poste point à point basés sur des messages. Ce qui suit est une introduction détaillée à certaines solutions des deux IPC.

Synchronisation
Pour une communication synchrone en mode demande/réponse. Vous pouvez choisir de communiquer entre les services basés sur le protocole Http de style Restful ou sur le protocole Thrift avec de bonnes capacités multilingues. Si vous utilisez des microservices en langage Java pur, vous pouvez également utiliser Dubbo. S'il s'agit d'un système d'architecture de microservices intégré à SpringBoot, il est recommandé de choisir RPC avec de bonnes performances multilingues et un meilleur support de la communauté Spring.

Dubbo
Dubbo est un framework RPC client Java open source développé par Alibaba. Dubbo transmet des données basées sur de longues connexions du protocole TCP. Le format de transfert utilise la sérialisation binaire hessienne. Le centre d'enregistrement des services peut être mis en œuvre via Zookeeper.

ApacheThrift
ApacheThrift est un framework RPC développé par Facebook. Son moteur de génération de code peut créer des services efficaces dans plusieurs langages, tels que C++, Java, Python, PHP, Ruby, Erlang, Perl, etc. Les données transmises sont au format binaire et ses paquets sont plus petits que le protocole HTTP utilisant le format Json ou XML. Une concurrence élevée est plus avantageuse dans les scénarios Big Data.

Rest
Rest est basé sur le protocole HTTP, et le protocole HTTP lui-même a une sémantique riche. Comme Springboot est largement utilisé, de plus en plus d'API de style Restful deviennent populaires. REST est basé sur le protocole HTTP et la plupart des développeurs connaissent HTTP.

Un autre point à mentionner ici est que de nombreuses entreprises ou équipes utilisent également Springboot, et elles disent également qu'elles sont basées sur le style Restful. Mais la réalité est que, bien souvent, la mise en œuvre n’est pas en place. Pour savoir si votre Restful est vraiment Restful, vous pouvez vous référer à cet article, qui réalise une analyse à quatre niveaux de la maturité des API de style Restful : Richardson Maturity Model marche vers la gloire de REST.

Si vous utilisez Springboot, quel que soit le mécanisme de découverte de service utilisé, vous pouvez utiliser RestTemplate de Spring pour encapsuler les requêtes HTTP de base.

Si vous utilisez Netflix-Eureka mentionné ci-dessus, vous pouvez utiliser Netflix-Feign. Feign est un client de service Web déclaratif. L'équilibrage de charge côté client utilise Netflix-Ribbon.

Asynchrone
Dans l'architecture de microservices, la pure « architecture basée sur les événements » est exclue. Le scénario d'utilisation de la file d'attente de messages est généralement destiné au découplage entre les microservices. Les services n'ont pas besoin de savoir quelle instance de service consomme ou publie des messages. Gérez simplement la logique au sein de votre propre domaine, puis publiez-la via le canal de messagerie ou abonnez-vous aux messages qui vous intéressent. Il existe actuellement de nombreuses technologies de file d'attente de messages open source. Par exemple, Apache Kafka, RabbitMQ, Apache ActiveMQ et RocketMQ d'Alibaba font désormais partie des projets Apache. Dans le modèle de file d'attente de messages, les trois composants principaux sont :
Producteur : produit des messages et écrit des messages sur les canaux.
Message Broker : Message Broker, gère les messages écrits sur le canal en fonction de la structure de la file d'attente. Responsable du stockage/transfert des messages. Le courtier est généralement un cluster qui doit être créé et configuré séparément et doit être hautement disponible.
Consommateur : Le consommateur du message. La plupart des files d'attente de messages actuelles garantissent que les messages sont consommés au moins une fois. Par conséquent, selon la fonction de file d'attente de messages utilisée, les consommateurs doivent être idempotents.
Différentes implémentations de file d'attente de messages ont différents modèles de message. Les caractéristiques de chaque framework sont également différentes :

RabbitMQ
RabbitMQ est une implémentation open source basée sur le protocole AMQP, écrit en Erlang, réputé pour ses hautes performances et son évolutivité. . Actuellement, le client prend en charge Java, .Net/C# et Erlang. Parmi les composants AMQP (Advanced Message Queuing Protocol), Broker peut contenir plusieurs composants Exchange (switch). Exchange peut lier plusieurs files d'attente ainsi que d'autres échanges. Les messages seront envoyés à la file d'attente de messages correspondante conformément aux règles de routage définies dans Exchange. Une fois que le consommateur aura consommé le message, il établira une connexion avec le courtier. Envoyez des notifications pour les messages consommés. Ensuite, Message Queue supprimera le message.

Kafka
Kafka est un système de messagerie distribué multilingue hautes performances basé sur la publication/l'abonnement. Le langage de développement de Kafka est Scala. Ses fonctionnalités les plus importantes sont :
Persistance rapide des messages avec une complexité temporelle de O(1) ;
Débit élevé
Prend en charge le partitionnement des messages entre les services et la consommation distribuée, tout en garantissant que les messages sont transmis de manière séquentielle ; expansion horizontale en ligne et est livré avec l'équilibrage de charge ;
prend en charge le mode de consommation uniquement et une seule fois (Exactly Once), etc.
Parlons d'une lacune : l'interface de gestion est un peu inutile. Vous pouvez utiliser le kafka-manager open source
Ses caractéristiques à haut débit peuvent non seulement être utilisées comme file d'attente de messages entre microservices, mais peuvent également être utilisées. pour la collecte de journaux, l'analyse hors ligne, l'analyse en temps réel, etc.
Kafka fournit officiellement une version Java de l'API client, et la communauté Kafka prend actuellement en charge plusieurs langages, notamment PHP, Python, Go, C/C++, Ruby, NodeJS, etc.

ActiveMQActiveMQ est un JMSProvider implémenté sur la base de JMS (Java Messaging Service). JMS fournit principalement deux types de messages : point à point et publication/abonnement. Actuellement, le client prend en charge Java, C, C++, C#, Ruby, Perl, Python et PHP. Et ActiveMQ prend en charge plusieurs protocoles : Stomp, AMQP, MQTT et OpenWire.

RocketMQ/ONSRocketMQ est une file d'attente de messages distribuée open source à haute disponibilité développée par Alibaba. ONS est un cluster haute disponibilité qui propose une version commerciale. ONS prend en charge le pull/push. Il peut prendre en charge le push actif et l'accumulation de dizaines de milliards de messages. ONS prend en charge les messages séquentiels globaux et dispose d'une page de gestion conviviale qui peut surveiller la consommation des files d'attente de messages et prend en charge le déclenchement manuel de plusieurs renvois de messages.

Résumé

Grâce au mécanisme de découverte de services des microservices dans l'article précédent et à l'ajout de l'API Restful, la synchronisation de la communication inter-processus entre les microservices peut être résolue. Bien entendu, puisque des microservices sont utilisés, nous espérons que tous les microservices pourront avoir des contextes délimités raisonnables (limites du système). La communication synchrone entre les microservices doit être évitée autant que possible pour éviter que les modèles de domaine entre les services ne s'empiètent les uns sur les autres. Afin d'éviter cette situation, vous pouvez utiliser une couche de passerelle API (qui sera présentée ci-dessous) dans l'architecture du microservice. Tous les microservices transmettent et fusionnent les requêtes unifiées via la passerelle API. Et la passerelle API doit également prendre en charge les requêtes synchrones et les requêtes asynchrones NIO (ce qui peut améliorer l'efficacité et les performances de la fusion des requêtes).

La file d'attente de messages peut être utilisée pour le découplage entre les microservices. Dans un environnement de cluster de services basé sur les microservices Docker, l'environnement réseau sera plus complexe qu'un cluster distribué général. Choisissez simplement une implémentation de file d’attente de messages distribuée hautement disponible. Si vous créez vous-même un environnement de cluster tel que Kafka ou RabbitMQ, vous aurez des exigences élevées en matière de haute disponibilité des installations du Broker. Pour les microservices basés sur Springboot, il est recommandé d'utiliser Kafka ou ONS. Bien que ONS soit disponible dans le commerce, il est facile à gérer et présente une grande stabilité. Il est plus adapté aux architectures de microservices qui s'appuient sur des files d'attente de messages pour la communication uniquement dans les scénarios nécessaires. Si vous considérez qu'il y aura une collecte de journaux, une analyse en temps réel et d'autres scénarios, vous pouvez également créer un cluster Kafka. À l'heure actuelle, Alibaba Cloud dispose également d'installations de cluster commerciales basées sur Kafka.

Utilisez API Gateway pour gérer le transfert et la fusion des demandes de microservices
La section précédente présente principalement comment résoudre les problèmes de découverte de services et de communication des microservices. Dans le système d'architecture de microservices, lors de l'utilisation de la pensée DDD pour diviser des contextes délimités entre services, les appels entre microservices seront minimisés. Afin de découpler les microservices, il existe une solution d'optimisation basée sur API Gateway.

Appels de microservice découplés
Par exemple, le scénario de demande courante suivant : une page d'agrégation de "liste de commandes d'utilisateurs". Vous devez demander le « Service utilisateur » pour obtenir des informations utilisateur de base et le « Service de commande » pour obtenir des informations de commande, puis demander le « Service produit » pour obtenir des photos de produits, des titres et d'autres informations dans la liste de commande. Comme le montre la figure ci-dessous :

Utiliser la technologie de conteneur de Docker pour présenter larchitecture de service du système DevOps - Architecture JAVA

Si le client (tel que H5, Android, iOS) est autorisé à émettre plusieurs requêtes pour résoudre plusieurs agrégations d'informations, la complexité du client. Une méthode plus raisonnable consiste à ajouter une couche API Gateway. Comme les microservices, API Gateway peut également être déployée et exécutée dans des conteneurs Docker. Il s'agit également d'une application Springboot. Comme suit, après transfert via l'API Gateway :

Utiliser la technologie de conteneur de Docker pour présenter larchitecture de service du système DevOps - Architecture JAVA

Toutes les informations demandées sont agrégées par la passerelle, qui est également le seul nœud entrant dans le système. Et Gateway et tous les microservices, ainsi que ceux fournis aux clients, sont également des API de style Restful. L'introduction de la couche Gateway peut bien résoudre le problème de l'agrégation des informations. Et il peut mieux s'adapter aux demandes des différents clients. Par exemple, les pages H5 n'ont pas besoin d'afficher les informations utilisateur et les clients iOS doivent afficher les informations utilisateur. Il vous suffit d'ajouter une API Gateway pour demander des ressources. La couche de microservice n'a pas besoin d'être affichée. Des modifications sont requises.

Fonctionnalités de la passerelle API

La passerelle API peut non seulement fusionner et transférer des demandes. Il a également besoin d’autres fonctionnalités pour devenir une passerelle complète.

Programmation adaptative
Gateway est le point d'entrée pour toutes les demandes des clients. Similaire au mode Façade. Afin d’améliorer les performances des requêtes, il est préférable de choisir un framework d’E/S non bloquant. Dans certains scénarios où plusieurs microservices doivent être demandés, les demandes pour chaque microservice ne doivent pas nécessairement être synchronisées. Dans l'exemple de « liste de commandes utilisateur » donné ci-dessus, l'obtention d'informations utilisateur et l'obtention de la liste de commandes sont deux requêtes indépendantes. Uniquement pour obtenir les informations sur le produit de la commande, vous devez attendre que les informations de la commande soient renvoyées, puis demander le microservice du produit en fonction de la liste d'ID de produit de la commande. Afin de réduire le temps de réponse de l'ensemble de la requête, Gateway doit être capable de traiter simultanément des requêtes indépendantes. Une solution consiste à adopter une programmation réactive.

Les méthodes de programmation réactive actuelles utilisant la pile technologique Java incluent CompletableFuture de Java8 et l'implémentation basée sur JVM fournie par ReactiveX - RxJava.

ReactiveX est une interface de programmation qui utilise des flux de données observables pour la programmation asynchrone. ReactiveX combine l'essence du modèle d'observateur, du modèle d'itérateur et de la programmation fonctionnelle. En plus de RxJava, il existe également des implémentations multilingues telles que RxJS et RX.NET.

Pour Gateway, l'Observable fourni par RxJava peut très bien résoudre les requêtes d'E/S indépendantes parallèles, et si Java8 est utilisé dans des projets de microservices, les membres de l'équipe apprendront et absorberont les fonctions RxJava plus rapidement. Une programmation réactive également basée sur le style Lambda peut rendre le code plus concis. Pour une introduction détaillée à RxJava, vous pouvez lire la documentation et les didacticiels RxJava.

Grâce au mode Observable de programmation réactive, vous pouvez facilement et commodément créer des flux d'événements et des flux de données, et utiliser des fonctions simples pour combiner et convertir des données. En même temps, vous pouvez vous abonner à n'importe quel flux de données observable et. exécutez-le.
En utilisant RxJava, le diagramme de séquence de demande de ressources de la « Liste de commandes utilisateur » :

Utiliser la technologie de conteneur de Docker pour présenter larchitecture de service du système DevOps - Architecture JAVA

La programmation réactive peut mieux gérer diverses synchronisations de threads et requêtes simultanées, via les observables et les planificateurs. fournir un flux de données transparent et un traitement par thread du flux d'événements. Dans le modèle de développement agile, la programmation réactive rend le code plus concis et plus facile à maintenir.

Authentification
Gateway est la seule entrée du système. Toute authentification basée sur des microservices peut être effectuée autour de Gateway. Dans le projet Springboot, l'autorisation de base peut utiliser spring-boot-starter-security et Spring Security (Spring Security peut également être intégré dans le projet Spring MVC).
Spring Security utilise principalement AOP pour intercepter les demandes de ressources et maintient la chaîne de filtrage d'un rôle en interne. Étant donné que les microservices sont tous demandés via Gateway, le @Secured des microservices peut être défini en fonction des niveaux de rôle des différentes ressources dans Gateway.

Spring Security fournit les spécifications de base de l'interface de vérification des rôles. Cependant, le cryptage, le stockage et la vérification des informations du jeton demandées par le client doivent être effectués par l'application elle-même. Redis peut être utilisé pour stocker des informations cryptées par jeton. Une autre chose à mentionner ici est que afin de garantir la variabilité de certaines informations cryptées, il est préférable d'envisager de prendre en charge plusieurs clés de version lors de la conception du module Token au début afin d'éviter que la clé interne ne soit divulguée (j'ai entendu un ami dire avant que le code de cryptage du Token de son entreprise ne soit divulgué par les employés). Quant à l’algorithme de chiffrement et à sa mise en œuvre spécifique, nous ne nous y attarderons pas ici. Une fois l'authentification de la passerelle réussie, les informations du jeton analysées peuvent être directement transmises à la couche de microservice qui doit poursuivre la demande.

Si l'application nécessite une autorisation (les demandes de ressources doivent gérer différents rôles et autorisations), cela peut être fait sur la base de l'idée AOP basée sur l'API Rest de Gateway. La gestion unifiée de l'authentification et de l'autorisation est également l'un des avantages de l'utilisation de l'API Gateway similaire au mode Facade.

Équilibrage de charge
API Gateway, comme Microservice, fournit l'API Rest en tant qu'application Springboot. Il fonctionne donc également dans un conteneur Docker. La découverte de services entre Gateway et les microservices peut toujours utiliser le mode de découverte de client ou le mode de découverte de serveur mentionné ci-dessus.
Dans un environnement de cluster, API Gateway peut exposer un port unifié et ses instances s'exécuteront sur des serveurs avec des adresses IP différentes. Étant donné que nous utilisons ECS d'Alibaba Cloud comme infrastructure de conteneurs, le SLB d'équilibrage de charge d'Alibaba Cloud est également utilisé pour l'équilibrage de charge dans l'environnement de cluster, et AliyunDNS est également utilisé pour la résolution de noms de domaine. La figure suivante est un schéma d'une requête réseau simple :

Utiliser la technologie de conteneur de Docker pour présenter larchitecture de service du système DevOps - Architecture JAVA

En pratique, afin de ne pas exposer le port du service et l'adresse de la ressource, le service Nginx peut également être déployé dans le cluster de services. En tant que proxy inverse, les installations d'équilibrage de charge externes telles que SLB peuvent transmettre les requêtes au serveur Nginx, puis transmettre les requêtes au port Gateway via Nginx. S'il s'agit d'un cluster dans une salle informatique auto-construite, un centre d'équilibrage de charge hautement disponible doit être construit. Afin de faire face aux demandes inter-machines, il est préférable d'utiliser Consul, Consul (Consul Template) + Registor + Haproxy comme centre de découverte de services et d'équilibrage de charge.

Mise en cache
Pour certaines requêtes QPS élevées, une mise en cache à plusieurs niveaux peut être effectuée dans API Gateway. Le cache distribué peut utiliser Redis, Memcached, etc. S'il s'agit de requêtes au niveau de la page qui n'ont pas d'exigences élevées en temps réel et ont une faible fréquence de modification mais un QPS élevé, la mise en cache locale peut également être effectuée au niveau de la couche passerelle. Et Gateway peut rendre la solution de mise en cache plus flexible et plus polyvalente.

  • Gestion des erreurs d'API Gateway

Dans le processus de mise en œuvre spécifique de Gateway, la gestion des erreurs est également une chose très importante. Pour la gestion des erreurs de passerelle, vous pouvez utiliser Hystrix pour gérer les disjoncteurs de demande. Et le rappel onErrorReturn fourni avec RxJava peut également gérer facilement le retour des informations d'erreur. Pour le mécanisme du disjoncteur, les aspects suivants doivent être traités :

  • Traitement tolérant aux pannes des demandes de service

En tant que passerelle raisonnable , il ne devrait être responsable que du flux de données de processus et du flux d'événements, et non de la logique métier. Lors du traitement des demandes de plusieurs microservices, les demandes de microservices peuvent expirer et devenir indisponibles. Dans certains scénarios spécifiques, les défaillances partielles doivent être gérées de manière raisonnable. Par exemple, dans la « Liste de commandes utilisateur » de l'exemple ci-dessus, lorsqu'une erreur se produit dans le microservice « Utilisateur », cela ne devrait pas affecter la demande de données « Commande ». La meilleure façon de gérer ce problème est de renvoyer des données par défaut à la mauvaise demande d'informations utilisateur à ce moment-là, comme l'affichage d'un avatar et d'un surnom d'utilisateur par défaut. Ensuite, les données correctes seront renvoyées pour demander des commandes normales et des informations sur les produits. Si une demande de microservice clé est anormale, par exemple lorsqu'un microservice dans le champ « Commande » est anormal, le client doit recevoir un code d'erreur et un message d'erreur raisonnable. Ce type de traitement peut tenter d'améliorer l'expérience utilisateur lorsqu'une partie du système est indisponible. Lors de l'utilisation de RxJava, la méthode d'implémentation spécifique consiste à écrire onErrorReturn et à rendre les données d'erreur compatibles pour différentes requêtes client.

  • Capture et enregistrement des exceptions

Gateway est principalement responsable du transfert et de la fusion des demandes. Afin de résoudre clairement les problèmes et de localiser le problème avec un service spécifique ou même avec quel conteneur Docker, Gateway doit être capable de capturer et d'enregistrer différents types d'exceptions et d'erreurs commerciales. Si vous utilisez FeignClient pour demander des ressources de microservice, vous pouvez filtrer davantage les résultats de la réponse et enregistrer toutes les informations de demande dans le journal en implémentant l'interface ErrorDecoder. Si vous utilisez Spring Rest Template, vous pouvez définir un RestTempate personnalisé et analyser le ResponseEntity renvoyé. Consigne les messages d'erreur avant de renvoyer l'objet de résultat sérialisé.

  • Mécanisme de délai d'attente

La plupart des threads de la passerelle sont des threads IO Afin d'éviter qu'une certaine demande de microservice ne soit bloquée, la passerelle aura trop de threads en attente et épuisera les ressources du système telles que les pools de threads et les files d'attente. Un mécanisme de délai d'attente doit être fourni dans la passerelle afin qu'une dégradation progressive du service puisse être effectuée sur l'interface de délai d'attente.
Hystrix est intégré au projet Feign de SpringCloud. Hystrix fournit un mécanisme de disjoncteur relativement complet pour le traitement des délais d'attente. Par défaut, le mécanisme de délai d'attente est activé. En plus de configurer les paramètres liés au délai d'attente, Netflix fournit également une surveillance en temps réel du tableau de bord Netflix basé sur Hytrix, et le service de cluster ne doit être déployé qu'avec Netflix-Turbine. Pour les éléments généraux de configuration Hytrix, veuillez vous référer à Hystrix-Configuration.
Si vous utilisez la programmation réactive Observable de RxJava et que vous souhaitez définir différents délais d'attente pour différentes requêtes, vous pouvez directement définir la méthode de rappel et le délai d'attente dans les paramètres de la méthode timeout() de l'Observable.

  • Mécanisme de nouvelle tentative

Pour certaines entreprises clés, afin de garantir un retour correct des données lorsque la demande expire, Gateway doit être en mesure de fournir un mécanisme de nouvelle tentative de test. Si vous utilisez SpringCloudFeign, son ruban intégré fournira une configuration de nouvelle tentative par défaut, qui peut être désactivée en définissant spring.cloud.loadbalancer.retry.enabled=false. Le mécanisme de nouvelle tentative fourni par Ribbon sera déclenché lorsque la demande expire ou lorsque le délai de lecture du socket expire. En plus de définir la nouvelle tentative, vous pouvez également personnaliser le seuil de temps de nouvelle tentative et le nombre de tentatives.

Pour les applications qui utilisent Spring RestTemplate en plus de Feign, vous pouvez utiliser un RestTemplate personnalisé pour analyser les résultats de l'objet ResponseEntity renvoyé si la demande doit être réessayée (comme une méthode de code d'erreur à format fixe). pour identifier la stratégie de nouvelle tentative), intercepter les requêtes via Interceptor et appeler plusieurs requêtes via des rappels.

Résumé

Pour l'architecture de microservices, via une passerelle API indépendante, le transfert de requêtes, la fusion et la conversion de protocole unifiés peuvent être effectués. Il peut s'adapter de manière plus flexible aux données de demande de différents clients. De plus, les requêtes compatibles avec différents clients (comme les données d'affichage H5 et iOS sont différentes) et les différentes versions peuvent être bien protégées dans Gateway pour rendre les microservices plus purs. Les microservices doivent uniquement se concentrer sur la conception des services de domaine internes et le traitement des événements.

La passerelle API peut également effectuer certaines tolérances aux pannes et dégradations de service sur les requêtes de microservices. L’utilisation d’une programmation réactive pour implémenter la passerelle API peut rendre la synchronisation des threads et le code de concurrence plus simple et plus facile à maintenir. Les demandes de microservices peuvent être unifiées via FeignClint. Le code sera également très hiérarchique. La figure ci-dessous est un exemple de la hiérarchie de classes demandée.

1Utiliser la technologie de conteneur de Docker pour présenter larchitecture de service du système DevOps - Architecture JAVA

  • Clint est responsable de l'intégration de la découverte de services (pour l'auto-enregistrement à l'aide d'Eureka), de l'équilibrage de charge, de la création de requêtes et de l'obtention d'objets ResponseEntity.

  • Translator convertit ResponseEntity en objets Observable et effectue une collecte de journaux unifiée des exceptions, similaire au concept de couche anti-corrosion dans DDD.

  • L'adaptateur appelle chaque traducteur et utilise la fonction Observable pour fusionner les flux de données demandés. S'il existe plusieurs assemblages de données, vous pouvez ajouter une couche d'Assembler pour gérer spécifiquement la conversion des objets DTO en modèles.

  • Le contrôleur assure la gestion des ressources Restful. Chaque contrôleur ne demande qu'une méthode d'adaptateur unique.

Déploiement d'intégration continue de microservices

L'article précédent présente principalement la découverte de services, la communication de services et la passerelle API des microservices. Le modèle de l’architecture globale des microservices est initialement vu. Dans des environnements réels de développement, de test et de production. Lors de l'utilisation de Docker pour implémenter des microservices, l'environnement réseau du cluster sera plus complexe. L'architecture des microservices elle-même signifie que plusieurs services de conteneurs doivent être gérés et que chaque microservice doit être déployé, étendu et surveillé indépendamment. Ce qui suit continuera à présenter comment effectuer un déploiement d'intégration continue (CI/CD) des microservices Docker.

Mirror Warehouse
Pour utiliser Docker pour déployer des microservices, vous devez empaqueter les microservices dans des images Docker, tout comme les déployer sur un serveur Web et les empaqueter dans des fichiers war. C'est juste que l'image Docker s'exécute dans un conteneur Docker.
S'il s'agit d'un service Springboot, Springboot incluant le serveur Apache Tomcat et l'application Java compilée incluant la bibliothèque d'exécution Java seront directement empaquetés dans une image Docker.
Afin de gérer uniformément les images de packaging et de distribution (pull/push). Les entreprises doivent généralement établir leur propre base de données miroir privée. La mise en œuvre est également très simple. La version conteneur de Registry2 de l'entrepôt miroir du hub Docker peut être déployée directement sur le serveur. La dernière version est actuellement la V2.

Entrepôt de code
La soumission, le rollback et autres gestions de code font également partie de l'intégration continue du projet. Généralement, il est également nécessaire d'établir un référentiel privé pour l'entrepôt de codes de l'entreprise. Vous pouvez utiliser des outils de gestion de versions de code tels que SVN et GIT.
Actuellement, l'entreprise utilise Gitlab, et les opérations d'installation et de déploiement via l'image Docker de Git sont également très pratiques. Pour des étapes spécifiques, veuillez vous référer à l'installation de docker gitlab. Afin de créer et de conditionner rapidement, Git et Registry peuvent également être déployés sur le même serveur.

Construction du projet
Dans le projet Springboot, l'outil de construction peut être Maven ou Gradle. Gradle est plus flexible que Maven et l'application Springboot elle-même est déconfigurable, il est donc plus approprié d'utiliser Gradle basé sur Groovy DSL lui-même, qui est également plus concis et efficace que XML.
Parce que Gradle prend en charge les tâches personnalisées. Par conséquent, une fois le Dockerfile du microservice écrit, vous pouvez utiliser le script de tâche de Gradle pour le créer et le conditionner dans une image Docker.
Il existe également des outils Gradle open source pour créer des images Docker, tels que le plug-in Transmode-Gradlew. En plus de créer des images Docker pour des sous-projets (microservices uniques), il peut également prendre en charge le téléchargement simultané d'images vers des entrepôts d'images distants. Sur la machine de build dans l'environnement de production, vous pouvez exécuter directement la build du projet, le packaging de l'image Docker et le push de l'image via une seule commande.

Technologie d'orchestration de conteneurs
Une fois l'image Docker créée, étant donné que chaque conteneur exécute une instance de microservice différente, les services sont déployés de manière isolée entre les conteneurs. Grâce à la technologie d'orchestration, DevOps peut gérer de manière légère le déploiement et la surveillance des conteneurs pour améliorer l'efficacité de la gestion des conteneurs.
À l'heure actuelle, certains outils d'orchestration courants, tels que Ansible, Chef et Puppet, peuvent également orchestrer des conteneurs. Mais aucun d'entre eux n'est un outil d'orchestration spécifiquement pour les conteneurs, vous devez donc écrire vous-même certains scripts et les combiner avec les commandes Docker lorsque vous les utilisez. Par exemple, Ansible peut en effet réaliser un déploiement et une gestion très pratiques de conteneurs de cluster. Ansible propose actuellement une solution d'intégration pour la technologie de conteneur développée par son équipe : Ansible Container.

Le système de gestion de cluster utilise l'hôte comme pool de ressources et décide sur quel hôte planifier le conteneur en fonction des besoins en ressources de chaque conteneur.
Actuellement, les technologies les plus matures entourant la planification et l'orchestration des conteneurs Docker incluent Kubernetes de Google (ci-après abrégé en k8s), Mesos combiné avec Marathon pour gérer les clusters Docker et Docker Swarm, qui est officiellement fourni dans la version 1.12.0 de Docker. et au-dessus. La technologie d’orchestration est l’un des axes de la technologie des conteneurs. Choisir une technologie d'orchestration de conteneurs adaptée à votre équipe peut également rendre l'exploitation et la maintenance plus efficaces et automatisées.

Docker Compose
Docker Compose est un simple outil d'orchestration de conteneurs Docker. Il configure les applications qui doivent être exécutées via des fichiers YAML, puis démarre les conteneurs correspondant à plusieurs services via. la commande composer up. Compose n'est pas intégré à Docker et doit être installé séparément.
Compose peut être utilisé pour l'intégration continue de projets de microservices, mais il ne convient pas à la gestion de conteneurs de grands clusters. Dans les grands clusters, Compose peut être combiné avec Ansible pour la gestion des ressources du cluster et la gouvernance des services.
Pour les situations où il n'y a pas beaucoup de serveurs dans le cluster, vous pouvez utiliser Compose. Les principales étapes sont :

  1. En combinaison avec l'environnement d'exploitation du microservice, définir le Dockerfile du service.

  2. Écrivez le fichier docker-compose.yml en fonction de l'image du service, du port, des variables en cours d'exécution, etc. afin que les services puissent être déployés ensemble. Exécutez le

  3. .
  4. exécutez la commande docker-compose up Démarrez et entrez l'instance de conteneur. Si vous devez l'exécuter en arrière-plan, utilisez docker-compose up-d.

Docker Swarm
En 2016, après la sortie de la version 1.12 de Docker, la nouvelle version de Docker est arrivée avec le mode Docker swarm. Pas besoin d'installer d'outils plug-ins supplémentaires. On peut voir que l'équipe Docker a également commencé à s'intéresser à la technologie d'orchestration de services depuis l'année dernière, grâce au mode Swarm intégré, elle souhaite également s'emparer d'une partie du marché de l'orchestration de services.
Si l'équipe commence à utiliser une nouvelle version de Docker, vous pouvez choisir le mode essaim Docker pour la planification et la gestion des conteneurs en cluster. Swarm prend également en charge les mises à jour progressives, le cryptage de sécurité de la couche de transport entre les nœuds, l'équilibrage de charge, etc.
Pour des exemples d'utilisation de DockerSwarm, veuillez vous référer à l'article que j'ai écrit auparavant : Utiliser docker-swarm pour créer un service de cluster d'intégration continue.

Kubernetes
Kubernetes est le système de gestion de cluster de conteneurs open source de Google, implémenté à l'aide du langage Go, qui assure le déploiement, la maintenance, le mécanisme d'extension et d'autres fonctions des applications. Actuellement, les k8 peuvent être utilisés sur GCE, vShpere, CoreOS, OpenShift, Azure et d'autres plateformes. À l'heure actuelle, Aliyun en Chine propose également une plateforme de gestion de services basée sur k8. S'il s'agit d'un cluster Docker construit à partir de machines physiques ou de machines virtuelles, vous pouvez également déployer et exécuter directement des k8. Dans un environnement de cluster de microservices, Kubernetes peut facilement gérer les instances de conteneurs de microservices sur plusieurs machines.

Actuellement, k8s est fondamentalement reconnu comme l'une des technologies de gouvernance de services open source les plus puissantes. Il fournit principalement les fonctions suivantes :

  1. Déploiement et réplication automatisés des instances de service basées sur Docker

  2. Exécuter en cluster et peut gérer des Conteneurs de machines, ainsi que mises à niveau progressives et orchestration du stockage.

  3. Module intégré de découverte de services et d'équilibrage de charge basé sur Docker

  4. K8s fournit un puissant mécanisme d'auto-réparation qui réparera les conteneurs en panne. Remplacement (sans aucune connaissance des utilisateurs ni même de l'équipe de développement), et la capacité peut être étendue ou réduite à tout moment. Rendre la gestion des conteneurs plus flexible.

k8s complète principalement la gestion des clusters de conteneurs élastiques à travers les composants importants suivants :

  1. Pod est le plus petit élément de gestion de Kubernetes. Un ou plusieurs conteneurs s'exécutent dans un pod. Le cycle de vie d'un pod est très court et disparaîtra en cas d'échec de la planification, de panne du nœud ou de recyclage d'autres ressources.

  2. Le label est une structure de stockage clé/valeur qui peut être associée aux pods. Elle est principalement utilisée pour marquer les pods et les services de groupe. Les microservices utilisent des sélecteurs d'étiquettes (Sélecteurs) pour identifier les pods.

  3. Replication Controller est le composant principal du nœud k8sMaster. Utilisé pour garantir qu'un nombre spécifié de répliques de pods (répliques) sont exécutées à tout moment dans le cluster Kubernetes. Autrement dit, il fournit la fonction d'un mécanisme d'auto-guérison et est également utile pour la réduction, l'expansion et les mises à niveau progressives.

  4. Le service est une abstraction de la stratégie d'un groupe de Pods. C'est aussi l'un des éléments de base de la gestion des k8. Le service identifie un groupe de pods via Label. Une fois créé, le DNS d'un cluster local (qui stocke l'adresse de service du Pod correspondant au Service) sera également créé. Par conséquent, le client demande à obtenir les adresses IP d'un ensemble de pods actuellement disponibles en demandant DNS. La demande est ensuite transmise à l'un des pods via le proxy Kube exécuté dans chaque nœud. Cette couche d'équilibrage de charge est transparente, mais la stratégie actuelle d'équilibrage de charge de K8 n'est pas très complète et la valeur par défaut est aléatoire.

Résumé

Dans un système d'architecture de microservices, un outil d'intégration continue approprié peut grandement améliorer le fonctionnement, le développement et l'efficacité du développement de l'équipe. Actuellement, à l'instar de Jenkins, il existe des plug-ins d'intégration continue pour Docker, mais il existe encore de nombreuses imperfections. Par conséquent, il est recommandé de choisir Swarm, k8s et Mesos qui traitent spécifiquement de la technologie d'orchestration de conteneurs Docker. Ou combinez plusieurs technologies, telles que Jenkins pour CI+k8s pour CD.

Swarm, k8s et Mesos ont chacun leurs propres fonctionnalités et prennent en charge le déploiement, la gestion et la surveillance continus des conteneurs. Mesos prend également en charge la gestion des centres de données. Le mode essaim Docker étend l'API Docker existante Grâce à l'appel et à l'extension de l'API Docker Remote, les conteneurs peuvent être programmés pour s'exécuter sur des nœuds spécifiés. Kubernetes est actuellement la plus grande technologie d'orchestration du marché. De nombreuses grandes entreprises ont également rejoint la famille K8s. K8s est plus flexible dans l'expansion, la maintenance et la gestion des applications de cluster, mais la stratégie d'équilibrage de charge est relativement approximative. Mesos se concentre davantage sur la planification générale et propose une variété de planificateurs.

Pour l'orchestration des services, vous devez toujours choisir celui qui convient le mieux à votre équipe. Si le nombre de machines initiales est faible et que l'environnement du cluster n'est pas complexe, vous pouvez également utiliser Ansible+Docker Compose, plus Gitlab. CI pour une intégration continue.

Solutions de cluster de services
Lorsque les entreprises s'entraînent à utiliser Docker pour déployer et exécuter des applications de microservices, qu'elles présentent l'architecture des microservices depuis le début ou qu'elles partent de l'application unique traditionnelle Migrez le de l'architecture aux microservices. Tous doivent être capables de gérer la planification des services, l’orchestration, la surveillance et d’autres problèmes dans des clusters complexes. Ce qui suit présente principalement comment utiliser Docker de manière plus sûre et plus efficace dans un cluster de services distribués, ainsi que tous les aspects qui doivent être pris en compte dans la conception architecturale.

Équilibrage de charge
Ce dont nous parlons ici, c'est de l'équilibrage de charge dans le cluster. S'il s'agit d'une API purement côté serveur, cela fait référence à l'équilibrage de charge de l'API Gateway. . Si Nginx est utilisé, il s'agit de l'équilibrage de charge Nginx. Nous utilisons actuellement le service d'équilibrage de charge SLB d'Alibaba Cloud. L'une des principales raisons est qu'il peut être lié au service de noms de domaine DNS. Pour les entreprises qui démarrent tout juste leur activité, vous pouvez définir des poids d'équilibrage de charge via l'interface Web, ce qui est plus pratique pour la publication partielle, les tests et la vérification, la surveillance des contrôles de santé, etc. C'est un choix plus approprié en termes d'efficacité et d'économie sur les coûts d'exploitation et de maintenance.

Si vous créez vous-même un équilibrage de charge à sept couches, par exemple en utilisant Nginx ou Haproxy, vous devez également vous assurer que le cluster responsable de l'équilibrage de charge est également hautement disponible et fournit une surveillance pratique du cluster, bleu-vert déploiement et autres fonctions.

Persistance et mise en cache

Base de données relationnelle (SGBDR)
Pour les microservices, la technologie de stockage utilisée est principalement basée sur les besoins de l'entreprise. Afin de réduire les coûts, Mysql est généralement utilisé Lors du choix du moteur Mysql, il est recommandé de choisir le moteur InnoDB (MyISAM était la valeur par défaut avant la version 5.5). InnoDB est plus efficace dans la gestion de la concurrence, et son écart de performances des requêtes peut également être comblé grâce à la mise en cache, à la recherche et à d'autres solutions. Les solutions gratuites d'InnoDB pour gérer la copie et la sauvegarde des données incluent binlog et mysqldump. Cependant, pour obtenir une sauvegarde et une restauration automatisées et un centre de données contrôlable, un administrateur de base de données ou une équipe d'exploitation et de maintenance est toujours nécessaire. Le coût relatif est également plus élevé. Si vous êtes une start-up, vous pouvez également envisager de vous appuyer sur les services PaaS fournis par certaines plates-formes de cloud computing relativement importantes en Suisse et à l'étranger.

Les microservices sont généralement divisés selon les domaines d'activité, il est donc préférable de concevoir dès le début une sous-bibliothèque pour les microservices. La nécessité d'une subdivision des tables nécessite une analyse détaillée basée sur le développement des domaines d'activité spécifiques de chaque microservice et la taille des données. Cependant, il est recommandé que pour les modèles dans des domaines relativement essentiels, tels que les « commandes », les champs des sous-tableaux soient conçus et réservés à l'avance.

Base de données de modèles KV (Key-Value-stores)
Redis est une base de données de structure Key-Value open source. Il est basé sur la mémoire, offre des performances de mise en cache efficaces et prend également en charge la persistance. Redis dispose principalement de deux méthodes de persistance. L'un d'entre eux est RDB, qui génère des instantanés ponctuels de l'ensemble de données à des intervalles de temps spécifiés et les écrit de la mémoire sur le disque pour assurer leur persistance. La méthode RDB entraînera un certain degré de perte de données, mais les performances sont bonnes. L'autre est AOF. Son mécanisme d'écriture est quelque peu similaire à celui du fichier binlog d'InnoDB. Toutes les commandes sont enregistrées au format du protocole Redis. Ces deux types de persistance peuvent exister en même temps au redémarrage de Redis, le fichier AOF sera utilisé en premier pour restaurer les données. La persistance étant facultative, la persistance Redis peut également être désactivée.

Dans les scénarios réels, il est recommandé de conserver la persévérance. Par exemple, Redis peut être utilisé pour résoudre la vérification des codes de vérification SMS qui est actuellement populaire. Dans le système d'architecture de microservices, Redis peut également être utilisé pour gérer certains scénarios de structure de données KV. La solution légère de stockage de données est également très adaptée à l’idée de microservice qui met l’accent sur les solutions légères.

En pratique, nous mettons en cache et persistons Redis, et divisons les deux fonctionnalités fonctionnelles dans des bibliothèques distinctes.
Dans le projet Springboot intégré, spring-boot-starter-data-redis sera utilisé pour effectuer la connexion à la base de données Redis et la configuration de base, ainsi que les APIOperations de données riches fournies par spring-data-redis.
De plus, s'il s'agit d'une application qui nécessite un débit élevé, vous pouvez envisager d'utiliser Memcached pour mettre en cache des structures de données KV simples. Il est plus adapté à la lecture de grandes quantités de données, mais les types de structures de données pris en charge sont relativement uniques.

Base de données graphique (Base de données graphique)
Implantant le stockage de données de modèle liées aux réseaux sociaux, la base de données graphique est un choix plus efficace et flexible pour les bases de données relationnelles qui se croisent. La base de données graphique est également un type de Nosql. C'est différent de KV. Les données stockées sont principalement des nœuds de données (nœud), des relations directionnelles (Relationship) et des propriétés (Property) sur les nœuds et les relations.

Si vous utilisez Java comme principal langage de développement pour les microservices, il est préférable de choisir Neo4j. Neo4j est une base de données graphique basée sur Java qui prend en charge ACID. Il fournit une riche API Java. En termes de performances, la nature locale des bases de données de graphes rend les traversées très rapides, en particulier les traversées profondes à grande échelle. Ceci est hors de portée des associations multi-tables dans les bases de données relationnelles.

L'image ci-dessous est un exemple officiel de modèle de données Getting Started affiché à l'aide de l'outil WebUI de Neo4j. L'instruction MATCH p=()-[r:DIRECTED]->() RETURN p LIMIT 25 dans l'exemple est le langage de requête fourni par Neo4j - Cypher.

2Utiliser la technologie de conteneur de Docker pour présenter larchitecture de service du système DevOps - Architecture JAVA

Le projet Spring Data Neo4j de SpringData peut être intégré lorsqu'il est utilisé dans le projet. Et SpringBootStartersspring-boot-starter-data-neo4j

Base de données documentaire (base de données documentaire)
La base de données orientée document open source actuellement largement utilisée peut utiliser Mongodb. Mongo offre une haute disponibilité, une grande évolutivité et un stockage de structures de données flexible, en particulier pour le stockage de structures de données Json. Il est plus adapté au stockage de modèles tels que des blogs et des commentaires.

Technologie de recherche
Au cours du processus de développement, nous voyons parfois souvent des gens écrire des requêtes SQL multi-tables longues, alambiquées et difficiles à maintenir, ou diverses instructions de sous-requête pour plusieurs association de tables. Pour un certain modèle de domaine, lorsqu'il existe de nombreux scénarios de ce type, il est temps d'envisager l'ajout d'une solution de recherche. N'utilisez pas SQL pour tout résoudre, en particulier les scénarios de requêtes. Le problème des instructions de requête lentes peut parfois même faire tomber la base de données. Si le système de surveillance de la base de données n'est pas en place, le problème peut être difficile à résoudre.

Elasticsearch est un moteur de recherche et d'analyse distribué en temps réel open source basé sur Apache Lucene. Les projets Springboot fournissent également des méthodes d'intégration : spring-boot-starter-data-elasticsearch et spring-data-elasticsearch.
Pour créer un cluster de recherche, vous pouvez utiliser Docker. Pour les méthodes de construction spécifiques, veuillez vous référer à Création d'un cluster Elasticsearch avec Docker. Pour l'intégration des projets Springboot, veuillez vous référer à Intégration des services de recherche dans les microservices Springboot. Jusqu'à présent, la dernière version de Spring Data Elasticsearch prend en charge la version 5.x d'ES, ce qui peut résoudre de nombreux problèmes de la version 2.x.

S'il s'agit d'un cluster de recherche à petite échelle, vous pouvez utiliser trois machines à faible configuration, puis utiliser ES Docker pour le créer. Vous pouvez également utiliser certaines versions commerciales des services PaaS. Comment choisir dépend toujours de la taille et du scénario de l’équipe et de l’entreprise
.
À l'heure actuelle, en plus d'ES, le moteur de recherche open source le plus utilisé est Solr. Solr est également basé sur Lucene et se concentre sur la recherche de texte. La recherche de texte d'ES n'est en effet pas aussi bonne que celle de Solr. ES se concentre principalement sur la prise en charge du support distribué et dispose d'un composant de découverte de services intégré Zen pour maintenir l'état du cluster (qui nécessite l'aide de quelque chose comme Zookeeper pour y parvenir. distribution), le déploiement est également plus léger. En plus d'analyser les requêtes, ES peut également intégrer la collecte, l'analyse et le traitement des journaux.

Message Queue
Comme mentionné dans l'article précédent, la file d'attente de messages peut être utilisée comme une bonne méthode de communication de découplage pour les microservices. Dans le cas de clusters distribués, il peut également fournir une garantie technique de base pour la cohérence finale dans des conditions distribuées. Et les files d’attente de messages peuvent également être utilisées pour gérer les coupures de trafic.
La comparaison des files d'attente de messages ne sera pas répétée ici. La société utilise actuellement l'ONS d'Alibaba Cloud. Parce que l’utilisation de files d’attente de messages nécessite toujours une haute disponibilité ainsi qu’une gestion et une surveillance faciles, nous avons choisi une plateforme de file d’attente de messages sûre et fiable.

Technologie de sécurité
La sécurité est la base qui doit être prise en compte lors de la réalisation d'architecture. L'environnement Internet est complexe et la protection de la sécurité des services constitue également un engagement fondamental envers les utilisateurs. La technologie de sécurité couvre un large éventail de sujets. Cet article sélectionne quelques problèmes courants et méthodes couramment utilisées pour les présenter brièvement.

Sécurité des instances de service
Le cluster distribué lui-même est une garantie de la sécurité des instances de service. Lorsqu'il y a un problème avec un serveur ou une certaine instance de service, l'équilibrage de charge peut transmettre la demande à d'autres instances de service disponibles. Cependant, de nombreuses entreprises construisent leurs propres salles informatiques, et ce sont des salles monomachines. Cette disposition est en réalité plus dangereuse. Parce que la sauvegarde et la reprise après sinistre du serveur ne peuvent pas être entièrement garanties. Le plus effrayant est que la base de données se trouve également dans la même salle informatique et que les serveurs principaux et de sauvegarde sont tous réunis. Non seulement la sécurité n’est pas garantie, mais les coûts quotidiens d’exploitation et de maintenance seront également relativement élevés. Vous devez également faire attention à la configuration des politiques de sécurité du pare-feu.
Si possible, essayez d'utiliser des plateformes IaaS hautement disponibles, hautement évolutives et stables.

Sécurité du réseau

1. Prévenir les attaques réseau
Il existe actuellement plusieurs attaques réseau principales :
Injection SQL : selon différents frameworks de couche de persistance, y faire face les stratégies sont différentes. Si vous utilisez JPA, tant que vous suivez les spécifications de JPA, vous n'avez pratiquement pas à vous inquiéter.
Attaque XSS : faites un bon travail d'échappement et de vérification des paramètres. Pour plus de détails, veuillez vous référer à Prévention XSS
Attaque CSRF : faites du bon travail dans le jeton et référez-vous à la vérification des informations d'en-tête Http. Pour plus de détails, veuillez vous référer à CSRF Prevention
Attaque DDOS : les attaques DDoS à grand trafic utilisent généralement une IP haute défense. Vous pouvez également accéder à l’IP haute défense de certaines plateformes de cloud computing.
Ce qui précède répertorie simplement quelques attaques courantes. Si vous souhaitez en savoir plus à leur sujet, vous pouvez en savoir plus sur le tableau de prévention de sécurité REST. Dans le domaine de la sécurité des réseaux, il est généralement facile d'être ignoré par les start-ups. S'il n'y a pas d'équipe de sécurité d'exploitation et de maintenance, il est préférable d'utiliser des produits comme Alibaba Cloud-Cloud Shield. Économisez des soucis et des coûts.

2. Utiliser des protocoles de sécurité
Inutile de dire que cela va sans dire, que ce soit pour la communication de microservices utilisant l'API Restful, le CDN ou le service DNS utilisé. En ce qui concerne le protocole HTTP, il est recommandé d'utiliser HTTPS de manière uniforme. Quelle que soit la taille de l’application, il est nécessaire de se prémunir contre le détournement de trafic, sinon cela apportera une très mauvaise expérience aux utilisateurs.

3. Authentification
API Gateway a déjà introduit l'authentification des microservices auparavant. En plus des microservices eux-mêmes, certains des services que nous utilisons, tels que Mysql, Redis, Elasticsearch, Eureka, etc., doivent également configurer une authentification et essayer d'y accéder via l'intranet. N'exposez pas trop de ports au monde extérieur. Pour la passerelle API des microservices, en plus de l'authentification, il est préférable que le front-end demande la couche API via le proxy inverse Nginx.

Collecte et surveillance des journaux

Le système de surveillance des microservices basé sur la technologie des conteneurs est confronté à un environnement de réseau et de services plus complexe. La façon dont la collecte et la surveillance des journaux peuvent rendre les microservices moins intrusifs et plus transparents pour les développeurs est une chose à laquelle de nombreux DevOps de microservices réfléchissent et mettent constamment en pratique.

1. Collecte des journaux de microservices
La surveillance de la couche API des microservices nécessite le suivi, la collecte et l'analyse du chemin d'appel d'API Gateway vers chaque microservice. Si vous utilisez l'API Rest, afin de collecter toutes les requêtes, vous pouvez utiliser OncePerRequestFilter de Spring Web pour intercepter toutes les requêtes. Lors de la collecte des journaux, il est également préférable d'enregistrer le rt de la requête.

En plus de l'enregistrement des accès, des demandes et d'autres informations, le suivi des demandes d'appels d'API est également requis. Si vous enregistrez simplement les journaux de chaque service et de chaque passerelle, lorsqu'une exception se produit dans le journal de la passerelle, vous ne saurez pas quelle instance de conteneur du microservice présente un problème. Si le nombre de conteneurs atteint un certain niveau, il est impossible de vérifier les journaux de tous les conteneurs et instances de service. Une solution relativement simple consiste à ajouter une chaîne Trace identifiable de manière unique contenant des informations sur le conteneur à toutes les informations de journal.

Une fois le journal collecté, il doit encore être analysé. Si vous utilisez le système technique d'E.L.K, vous pouvez utiliser de manière flexible les fonctionnalités distribuées en temps réel d'Elasticsearch. Logstash peut collecter et analyser les journaux et synchroniser les données avec Elasticsearch. Kibana combine Logstash et ElasticSearch pour fournir une bonne interface Web qui facilite l'analyse des journaux et améliore la gestion visuelle des données de journaux.
Pour la collecte de journaux contenant de grandes quantités de données, afin d'améliorer les performances de collecte, la file d'attente de messages mentionnée ci-dessus doit être utilisée. L'architecture optimisée est la suivante :



2. Collecte des journaux d'appels des services de base
Par la collecte de micro-journaux et l'analyse de toutes les API Rest du service peuvent surveiller les informations sur les demandes.
Au sein du service, la collecte de journaux et l'analyse des performances des appels middleware et infrastructure (notamment Redis, Mysql, Elasticsearch, etc.) sont également nécessaires.

Pour la collecte de journaux des services middleware, nous pouvons actuellement utiliser un proxy dynamique pour intercepter et rappeler les méthodes de journalisation pour les méthodes de base appelées cache et référentiel (y compris la recherche et la base de données) appelées par le service. La méthode d'implémentation spécifique peut utiliser le framework de génération de bytecode ASM. Concernant l'injection logique des méthodes, vous pouvez vous référer à l'article ASM (4) précédemment écrit Si vous pensez que le code ASM est utilisé pour injecter dynamiquement la logique de la méthode. pas facile à maintenir, vous pouvez également utiliser Cglib relativement convivial pour les API.

Cinq éléments d'architecture :
Enfin, passons en revue le système technique que nous utilisons pour construire l'architecture de microservice Docker basée sur les cinq éléments centraux de l'architecture :

  1. Hautes performances
    File d'attente de messages, concurrence asynchrone RxJava, cache distribué, cache local, cache Http Etag, utilisation d'Elasticsearch pour optimiser les requêtes, CDN, etc.

  2. Cluster de services de conteneur de disponibilité, traitement du disjoncteur RxJava, dégradation du service, traitement idempotent des messages, mécanisme de délai d'attente, mécanisme de nouvelle tentative, cohérence éventuelle distribuée, etc.

  3. Évolutivité : évolutivité du cluster de serveurs, orchestration des conteneurs Kubernetes, partitionnement de bases de données et partitionnement de tables, évolutivité linéaire Nosql, évolutivité du cluster de recherche, etc.

  4. Évolutivité Les microservices basés sur Docker eux-mêmes sont nés pour l'évolutivité !

  5. Sécurité
    JPA/Hibernate, SpringSecurity, IP haute défense, surveillance des journaux, HTTPS, proxy inverse Nginx, HTTP/2.0, etc.

Résumé

Pour les solutions de cluster de services, en effet, qu'il s'agisse d'architecture microservice ou d'architecture SOA, elles sont relativement universelles. Docker peut être utilisé uniquement pour la construction de certains clusters middleware. Une seule phrase de Docker ps peut facilement interroger les informations sur le service en cours d'exécution, et il est également pratique de mettre à niveau les services de base.

La recherche d'une excellente conception d'architecture de cluster est sans fin. Après avoir contacté de nombreux amis techniques issus de startups, tout le monde préfère créer, développer et publier rapidement des services. Cependant, d’une part, nous craignons également que l’architecture des microservices ne soit plus compliquée, ce qui tuerait une poule aux œufs d’or. Mais les microservices en eux-mêmes constituent une excellente pratique du mode agile. Ces amis sont souvent confrontés à un problème lorsque leur entreprise se développe rapidement, à savoir l'embarras du fractionnement des services, des sous-bases de données et des tables de base de données et du découplage du code de synchronisation de type nouille via les messages. Ils veulent optimiser les performances mais n'ont aucun moyen de commencer.
Cet article sélectionne et présente principalement des solutions techniques pour la pratique des microservices de Docker. Différentes entreprises et équipes peuvent être adaptées à différents systèmes architecturaux et solutions techniques.

En tant qu'architecte, vous devez réaliser un aménagement à long terme basé sur la planification stratégique à court et à long terme de l'entreprise. À tout le moins, l'architecture de base doit être capable de prendre en charge trois années de développement, pendant lesquelles de nouvelles technologies peuvent être continuellement introduites, des mises à niveau de services et une reconstruction continue de la couche de code peuvent être effectuées.
Peut-être qu'il ne faut pas longtemps à un architecte pour construire un système complet à partir de zéro. Le plus important est de promouvoir continuellement le Domain-Driven Design au sein de l'équipe. Et permettre à l'équipe de suivre Clean Code et de mener un développement agile OvO.

Articles associés :

Analyse de l'architecture de microservices Microsoft eShopOnContainers

Vidéos associées :

Geek Academy Didacticiel vidéo en ligne gratuit Docker

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!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn