Fondateur Securities - Pratique de construction de microservices natifs dans le cloud pour la technologie financière

Cet article est basé sur le discours « Financial Technology Go Microservices » prononcé par Liu Yi, ingénieur R&D senior du Founder Securities Financial Technology Engineering Institute, au salon de technologie CloudWeGo « Cloud Native✖️Microservice Architecture and Technical Practice in the AI ​​Era ». Événement de Pékin organisé à Pékin le 30 mars 2024. Compilé à partir de « Construction Practice ».

Présentation : Cet article présentera en détail l'expérience pratique du Founder Securities Financial Technology Engineering Institute dans la construction de microservices cloud natifs. Le partage comprend trois aspects :

  1. Travail de gouvernance des microservices
  2. Travaux d'observabilité des microservices
  3. Les capacités ci-dessus de gestion des interfaces de microservices sont unifiées et intégrées à la plate-forme de développement Quark de Founder.

Introduction à la pratique de la construction de microservices de titres fondateurs

Début 2023, nous avons lancé la construction d'un système de microservices, dans lequel le centre d'enregistrement utilise ZooKeeper et les frameworks d'application Web et RPC utilisent respectivement Hertz et Kitex de CloudWeGo .    

À l'heure actuelle, nous sommes entrés dans le domaine profond de la construction de microservices, qui implique principalement la gouvernance des microservices , les capacités d'observabilité , la gestion des interfaces et d'autres travaux connexes. Ce qui suit présentera en détail les concepts et les principes de mise en œuvre.

Renforcement des capacités de gouvernance des microservices

concept

Dans le cadre de l'architecture des microservices, à mesure que le volume d'activité augmente progressivement, le nombre de services augmentera également progressivement. Dans ce contexte, à mesure que l'entreprise se développe, il deviendra de plus en plus difficile de gérer et de contrôler les services. Le rôle de la gouvernance des services est de résoudre une série de problèmes causés par la division des services afin que les services puissent fonctionner de manière plus stable. fournit l'enregistrement et la découverte des services, l'équilibrage de charge, le disjoncteur de service, la dégradation du service, la limitation du courant de service, etc. Les fonctions de délai d'attente, de nouvelle tentative et de limitation de courant côté serveur fournies par la plate-forme Quark sont toutes basées sur les capacités associées de Kitex . Le centre d'enregistrement actuellement utilisé est ZooKeeper (en abrégé zk), de sorte que la configuration dynamique associée est également implémentée avec l'aide. de zk, via Écrivez la configuration sur zk pour informer le serveur et le client de terminer l'activation des fonctions associées.  

introduire

  1. contrôle de flux

    La granularité du contrôle de flux dépend du niveau de service. Comme le montre la figure ci-dessous, le service peut gérer jusqu'à 1 000 requêtes par seconde, et les requêtes excessives seront directement arrêtées : huaxing_ratelimit

  2. Réessayer la configuration

    La granularité de la configuration des nouvelles tentatives est au niveau de la méthode, qui est utilisée pour configurer la manière de réessayer lorsque le service actuel ne parvient pas à envoyer une requête à une méthode du service spécifié : huaxing_retry

  3. Configuration du délai d'attente

    La granularité de la configuration du timeout se situe au niveau de la méthode, qui permet de configurer le temps maximum nécessaire au service actuel pour demander une méthode du service spécifié. Lorsque cette valeur est dépassée, le service actuel se déconnectera : voir la configuration. description des fonctions spécifiques de chaque configuration. huaxing_timeout 

Principes et détails de mise en œuvre

Le côté serveur et le côté client complètent l'injection dynamique des configurations pertinentes en étendant la suite de Kitex .  

du côté serveur

Configurez le serveur Kitex via le code suivant :

server.WithSuite(zooKeeperServer.NewSuite("Kitex-server", zooKeeperClient))
Copie

Parmi eux, zooKeeperServer.NewSuite("Kitex-server", zooKeeperClient)une instance de suite sera renvoyée, et la configuration du limiteur injectée dans le serveur sera incluse : Options 

func (s *zooKeeperServerSuite) Options() []server.Option {
    opts := make([]server.Option, 0, 2)
    // WithLimiter实现中,在zk中注册了监听器,每当数据变化,动态更新Limiter的相关配置,以达到限流目的
    opts = append(opts, WithLimiter(s.service, s.zooKeeperClient, s.opts))
    return opts
}
Copie

Sur la base du contenu ci-dessus, nous pouvons constater que seuls les limiteurs sont configurés par défaut dans la suite côté serveur. Le framework Kitex  ne prend actuellement en charge que deux types de limiteurs :

  1. Limiteur de connexions (limiter le nombre maximum de connexions)
  2. Limiteur Qps (limiter le qps maximum)

Lorsque vous utilisez zk comme centre d'enregistrement, les deux peuvent être ajustés dynamiquement via la configuration. Après modifications, les valeurs de configuration sont obtenues via l'écouteur de zk :

// zk数据变化时的回调方法
onChangeCallback := func(restoreDefault bool, data string, parser zooKeeper.ConfigParser) {
   lc := &limiter.LimiterConfig{}
   if !restoreDefault && data != "" {
      err := parser.Decode(data, lc)
      if err != nil {
         klog.Warnf("[zooKeeper] %s server zooKeeper config: unmarshal data %s failed: %s, skip...", dest, data, err)
         return
      }
   }
   // 将zk中的数据动态更新到配置中
   opt.MaxConnections = int(lc.ConnectionLimit)
   opt.MaxQPS = int(lc.QPSLimit)
   u := updater.Load()
   if u == nil {
      klog.Warnf("[zooKeeper] %s server zooKeeper limiter config failed as the updater is empty", dest)
      return
   }
   if !u.(limit.Updater).UpdateLimit(opt) {
      klog.Warnf("[zooKeeper] %s server zooKeeper limiter config: data %s may do not take affect", dest, data)
   }
}
// path,对于limiter,其值为:/KitexConfig/{ServiceName}/limit
zooKeeperClient.RegisterConfigCallback(context.Background(), path, uniqueID, onChangeCallback)
Copie

côté client

Semblable au côté serveur, le côté client a également la même configuration :

bizService.NewClient("Kitex-client",
client.WithSuite(zooKeeperclient.NewSuite("Kitex-server", "Kitex-client", zooKeeperClient)))
Copie

La suite côté client contient les options suivantes :

func (s *zooKeeperClientSuite) Options() []client.Option {
    opts := make([]client.Option, 0, 7)
    opts = append(opts, WithRetryPolicy(s.service, s.client, s.zooKeeperClient, s.opts)...)
    opts = append(opts, WithRPCTimeout(s.service, s.client, s.zooKeeperClient, s.opts)...)
    opts = append(opts, WithCircuitBreaker(s.service, s.client, s.zooKeeperClient, s.opts)...)
    return opts
}
Copie

Autrement dit, le client prend en charge trois configurations dynamiques : nouvelle tentative, délai d'attente et disjoncteur. Le traitement pertinent est effectué via la méthode de rappel du client zk pour obtenir l'effet de mise à jour dynamique.

Notes supplémentaires sur la configuration du délai d'attente

Pour le timeout, l'implémentation spécifique de sa méthode de configuration est la suivante :

func WithRPCTimeout(dest, src string, zooKeeperClient zooKeeper.Client, opts utils.Options) []client.Option {
    // ...
    return []client.Option{
        client.WithTimeoutProvider(initRPCTimeoutContainer(path, uid, dest, zooKeeperClient)),
        client.WithCloseCallbacks(func() error {
            // cancel the configuration listener when client is closed.
            zooKeeperClient.DeregisterConfig(path, uid)
            return nil
        }),
    }
}
Copie

client.WithTimeoutProviderEnfin, la configuration spécifique liée au timeout se complète en appelant la méthode fournie par Kitex . Pour les délais d'attente, il existe les différentes méthodes de configuration suivantes :

func WithRPCTimeout(d time.Duration) Option {
    // ...
}

func WithConnectTimeout(d time.Duration) Option {
    // ...
}

func WithTimeoutProvider(p rpcinfo.TimeoutProvider) Option {
    // ...
}
Copie

Parmi eux, WithTimeoutProviderle délai d'attente défini sera écrasé WithRPCTimeoutpar la valeur définie de , donc si ou WithConnectTimeoutest appelé lors de la création du client Kitex, la configuration dynamique ne prendra pas effet.WithRPCTimeoutWithConnectTimeout

Instructions de configuration

temps mort

Nœud zk correspondant :/kitexConfig/{ClientName}/{ServiceName}/rpc_timeout

Le format de configuration écrite est le suivant :

{
  "*": {
    "conn_timeout_ms": 100,
    "rpc_timeout_ms": 800
  },
  "GetDemoInfo": {
    "rpc_timeout_ms": 300
  },
  "GetDemoInfo3": {
    "rpc_timeout_ms": 300
  }
}
Copie

Signification du champ : le temps d'attente maximum pour établir une nouvelle connexion : le temps maximum pour un appel rpc ; conn_timeout_ms rpc_timeout_ms

Recommencez

Nœud zk correspondant :/kitexConfig/{ClientName}/{ServiceName}/retry

Le format de configuration écrite est le suivant :

{
  "GetDemoInfo": {
    "enable": true,
    "type": 0,
    "failure_policy": {
      "stop_policy": {
        "max_retry_times": 2,
        "max_duration_ms": 9000,
        "cb_policy": {
          "error_rate": 0.1
        }
      }
    }
  },
  "GetDemoInfo5": {
    "enable": true,
    "type": 0,
    "failure_policy": {
      "stop_policy": {
        "max_retry_times": 2,
        "max_duration_ms": 9000,
        "cb_policy": {
          "error_rate": 0.1
        }
      }
    }
  }
}
Copie

Signification du champ

Éléments de configuration valeur par défaut illustrer limite
max_retry_times 2 Le nombre maximum de tentatives, à l'exclusion de la première demande. S'il est configuré sur 0, cela signifie arrêter de réessayer. Valeurs légales : [0-5]
max_duration_ms 0 Le temps maximum cumulé écoulé, y compris le temps écoulé pour la première demande ayant échoué et la demande de nouvelle tentative. Si le temps écoulé atteint la limite, les tentatives suivantes seront arrêtées. 0 signifie aucune limite. Remarque : S'il est configuré, cet élément de configuration doit être supérieur au délai d'expiration de la demande.  
taux d'erreur dix% Seuil de taux d'erreur du disjoncteur de nouvelle tentative. Si le taux d'erreur de demande au niveau de la méthode dépasse le seuil, les tentatives seront arrêtées. Valeurs légales : (0-30 %]

Limiter

Cette configuration est une configuration globale pour le service, donc le chemin du nœud zk contient uniquement serviceName :/kitexConfig/{ServiceName}/limit

Le format de configuration écrite est le suivant :

{
  "qps_limit": 100
}
Copie

Renforcement des capacités d'observabilité des microservices

concept

La construction de l'observabilité des services fait référence à l'établissement et à l'amélioration de la surveillance, de la journalisation, du suivi et d'autres outils et technologies dans les systèmes distribués afin de comprendre de manière complète et opportune l'état de fonctionnement et les indicateurs de performance du système.

Un outil d’observation complet peut apporter de nombreux avantages aux systèmes d’entreprise :

  1. Capacité à détecter et à résoudre les problèmes en temps opportun ;
  2. Permettre à l’équipe d’avoir une compréhension plus claire du fonctionnement global et des interactions internes du système ;
  3. Peut comprendre l'état de charge, l'utilisation des ressources et les changements de tendance du système pour prendre en charge la planification de la capacité et l'optimisation des ressources ;
  4. En enregistrant les journaux d'opérations du système et les traces de demandes via le système de journalisation et de suivi, les comportements opérationnels des utilisateurs, les demandes anormales et les événements de sécurité peuvent être suivis et analysés pour améliorer la sécurité et la fiabilité du système.

introduire

Les détails du service sont utilisés pour afficher le fonctionnement global du service lui-même, y compris les indicateurs de surveillance privilégiés (QPS, latence et taux d'erreur), les informations relatives au SLO et à l'exécution, etc. : huaxing_grafana

Le diagramme de topologie est utilisé pour montrer les dépendances en amont et en aval entre les services : huaxing_topologie

Les données de la chaîne d'appels contiennent des informations détaillées sur chaque appel entre services : huaxing_trace

Principes et détails de mise en œuvre

huaxing_otel

Actuellement, le client OpenTelemetry a été intégré dans le code du modèle et les services Hertz et Kitex générés disposent par défaut de capacités de reporting de données observables (Metrics + Tracing).    

Pour des informations détaillées, veuillez vous référer à : kitex-contrib/obs-opentelemetry  et hertz-contrib/obs-opentelemetry 

OpenTelemetry  (OTel) est un framework d'observabilité open source qui permet aux équipes de développement de générer, traiter et transmettre des données de télémétrie dans un format unique et unifié. Il a été développé par la Cloud Native Computing Foundation (CNCF) pour fournir des protocoles et des outils standard pour collecter et envoyer des métriques, des journaux et des traces aux plateformes de surveillance. OpenTelemetry fournit des SDK, des API et des outils indépendants du fournisseur. OpenTelemetry devient rapidement la norme dominante de données de télémétrie d'observabilité pour les applications cloud natives. L'adoption d'OpenTelemetry est essentielle pour les organisations qui souhaitent être prêtes à répondre à leurs futurs besoins en matière de données sans être enfermées dans un fournisseur spécifique ou limitées par leur technologie existante.

Tracer

Le traçage fournit une image complète de l’ensemble du cycle de vie, depuis la réception de la demande jusqu’à son achèvement.

Après réception de la demande, le service permet le suivi des liens à partir des méta-informations (Kitex) ou de l'en-tête http (Hertz). S'il n'y a aucune information de traçage dans les méta-informations ou l'en-tête HTTP, le nouveau traçage de lien sera automatiquement activé. Les informations de lien sont transmises au sein du processus de service via le contexte.

Méthode d'accès:

// for Hertz
tracer, cfg := hertztracing.NewServerTracer()
h := server.Default(tracer)
h.Use(hertztracing.ServerMiddleware(cfg))
Copie
// for Kitex
svr := echo.NewServer(new(DemoImpl),
    server.WithSuite(tracing.NewServerSuite()),
    server.WithServerBasicInfo(&rpcinfo.EndpointBasicInfo{ServiceName: serviceName}),)
Copie

Les informations de traçage sont signalées à OpenTelemetry Collector puis transmises de manière transparente à Jaeger. Les informations relatives au lien peuvent être interrogées dans Jaeger.

Fournit une imprimante de journaux unifiée fzlog, qui imprime les informations relatives au traçage par défaut.

{
  "file": "get_repositories.go:33",
  "func": "gitlab.fzzqft.com/ifte-quark/quark-api/biz/service.(*GetRepositoriesService).Run",
  "level": "info",
  "msg": "GetRepositoriesService Run req: page:1 limit:10 service_name:\"kitex\"",
  "span_id": "aa26bab58cdf6806",
  "time": "2024-04-23 15:59:40.609",
  "trace_flags": "01",
  "trace_id": "f714dbe2a96b1882dfc4b81909e55643"
}
Copie

Une fois les journaux collectés et traités, les informations de journal pertinentes de l'ensemble du lien peuvent être interrogées sur la plateforme de journalisation . trace_id 

Métrique

Les métriques sont des données clés qui mesurent les performances et le comportement du système, telles que le taux de requêtes, le temps de réponse, le taux d'erreur, etc. Les métriques sont généralement collectées, regroupées et visualisées afin de surveiller l'état du système et d'effectuer une analyse des tendances.

Actuellement, chaque service rapporte ses propres données Metrics et les stocke uniformément dans Prometheus/VictoriaMetrics, et utilise enfin grafana pour former un panneau de surveillance.

Ce qui suit utilise trois indicateurs de description de service courants : QPS, temps de demande et taux d'erreur pour montrer comment utiliser les données de métriques rapportées par le service.

  • QPS : sur la base de la définition du QPS, il nous suffit d'obtenir le nombre de requêtes en temps réel pour calculer le QPS. http_server_duration_count La valeur dans les données rapportées est cohérente avec le nombre de requêtes, cette métrique peut donc être utilisée pour compléter le calcul de. QPS.

    sum(rate(http_server_duration_count{service_name="$service_name"}[$__rate_interval]))
    
    Copie

    Dans le promQL ci-dessus, la fonction rate est utilisée pour calculer le taux de croissance d'une certaine métrique au cours d'une période de temps spécifiée, et le résultat final est le nombre moyen de requêtes au cours de la période de temps spécifiée.

  • Consommation de temps des requêtes : Puisqu'il s'agit d'une donnée statistique, nous choisissons ici d'utiliser la moyenne pour représenter la consommation de temps des demandes de service. La consommation de temps moyenne est obtenue par la consommation de temps totale de toutes les requêtes au cours de la période spécifiée ➗Le nombre de. demandes dans le délai imparti :

    sum(rate(http_server_duration_sum{service_name="$service_name"}[$__rate_interval])) by (application) /
    sum(rate(http_server_duration_count{service_name="$service_name"}[$__rate_interval])) by (application)
    
    Copie
  • Taux d'erreur : filtrez d'abord le nombre de requêtes erronées et divisez-le par le nombre total de requêtes pour obtenir le taux d'erreur.

    round((1 - (sum(rate(http_server_duration_count{service_name="$service_name",http_status_code=~"^(2|3).*"}
    [$__interval]))/sum(rate(http_server_duration_count{service_name="$service_name"}[$__interval])))), 0.0001)
    
    Copie

Topologie

Les dépendances globales inter-services sont affichées via les données métriques mentionnées dans l'agrégation. Les données rapportées contiennent service_namedes informations, sourceet les informations en amont et en aval du service peuvent être obtenues targetvia l'opérateur PromSQL .sum

Renforcement des capacités de gestion des interfaces de microservices

concept

  • IDL

    Interface Description Language (IDL) est un langage informatique utilisé pour décrire l'interface des composants logiciels. IDL décrit les interfaces d'une manière indépendante du langage de programmation, permettant aux objets exécutés sur différentes plates-formes et aux programmes écrits dans différents langages de communiquer entre eux.

  • Gestion des interfaces

    Les services Kitex (RPC) sont tous implémentés sur la base d'IDL. La plate-forme de gestion d'interface fournit principalement une plate-forme d'interface pour gérer les produits IDL des services RPC, permettant aux développeurs de gérer et d'appeler plus facilement les interfaces RPC.

  • Test d'interface

    Le service Kitex (RPC) est inaccessible pour les tests. Les utilisateurs de la plate-forme de test d'interface résolvent ce problème pour faciliter les tests et le développement en lançant des requêtes RPC via la plate-forme pour terminer le débogage.

introduire

  • Plateforme de gestion d'interface (voir photo pour la méthode de fonctionnement) huaxing_interface_1 huaxing_interface_2 huaxing_interface_3
  • Plateforme de test d'interface (interface de débogage Kitex (RPC)) huaxing_interface_test

Principes et détails de mise en œuvre

  • Gestion des interfaces

    Auparavant, nous utilisions un entrepôt indépendant avec gitlabci pour gérer les produits IDL du service Kitex : lors de l'utilisation réelle, il y avait les problèmes suivants :   huaxing_interface_impl 

    1. L'appelant doit obtenir l'adresse, la succursale ou le numéro de version de l'entrepôt de produits IDL via une petite fenêtre (chat privé)
    2. La méthode de prestation de services doit prêter attention à la fois à l'entrepôt du projet de service et à l'entrepôt de produits correspondant.
    3. Gitlabci s'appuie fortement sur Runner et les nouveaux groupes doivent être configurés par l'administrateur avant de pouvoir être utilisés.
    4. Impossible de se lier profondément au processus CICD existant

    Afin de résoudre les problèmes et points douloureux ci-dessus, une plate-forme de gestion d’interface a été conçue et développée. huaxing_interface_platform

    Lorsque le service est construit et empaqueté, le processus de mise à jour du produit IDL est déclenché. La plateforme détectera automatiquement le type de service, générera le produit IDL correspondant et le soumettra à l'entrepôt indépendant de gitlab. Les utilisateurs peuvent également créer ou mettre à jour manuellement des produits IDL sur la plateforme. L'appelant n'a qu'à copier et exécuter la commande import path pour obtenir la version correspondante de la dépendance du service.

  • Le test d'interface est implémenté sur la base de l'appel de généralisation de mappage JSON de Kitex PB. L'utilisateur sélectionne le service et l'interface correspondants sur la plateforme, et la plateforme analyse automatiquement le fichier IDL correspondant et donne les paramètres de requête par défaut (format json). Après l'envoi de la requête, la plateforme initie une requête RPC au service cible via un appel généralisé et renvoie le résultat. huaxing_interface_test_logic 

résumé

Le système de microservices actuel peut déjà répondre à la plupart des besoins techniques, mais nous prévoyons d'aller plus loin dans le cadre du système cloud natif :

  1. La gouvernance des services s'appuie sur des capacités de maillage de services cloud natif (ServiceMesh) pour gérer le trafic, tout en intégrant également le trafic est-ouest provenant d'autres frameworks d'applications.
  2. Observabilité, OpenTelemetry est un ensemble de solutions indépendantes du langage et du cadre d'application, grâce à une sémantique unifiée, il prévoit d'incorporer les systèmes Java Web (Springboot) et RPC (Dubbo).
  3. Gestion des interfaces, à l'avenir, il est prévu de gérer unifiéement les interfaces RPC et HTTP et de générer automatiquement des cas d'utilisation d'interface.

activités récentes

Les utilisateurs et développeurs d'entreprise sont sincèrement invités à participer au salon technologique CloudWeGo . L'événement se tiendra à Shanghai le 25 mai 2024 ( samedi) , invitant des collègues techniques à discuter de la manière dont les entreprises peuvent créer une architecture de microservices cloud native pour prendre en charge l'itération et le développement rapides de produits sous la vague de xAI cloud native . Scannez le code QR sur la photo pour vous inscrire immédiatement, à bientôt ! 

 

Les ressources piratées de "Celebrating More Than Years 2" ont été téléchargées sur npm, obligeant npmmirror à suspendre le service unpkg. L'équipe chinoise d' IA de Microsoft a fait ses valises et s'est rendue aux États-Unis, impliquant des centaines de personnes. La bibliothèque de visualisation frontale et le projet open source bien connu de Baidu, ECharts - "aller à la mer" pour soutenir les escrocs Fish ont utilisé TeamViewer pour transférer 3,98 millions ! Que doivent faire les fournisseurs de postes de travail à distance ? Zhou Hongyi : Il ne reste plus beaucoup de temps à Google. Il est recommandé que tous les produits soient open source. Un ancien employé d'une société open source bien connue a annoncé la nouvelle : après avoir été interpellé par ses subordonnés, le responsable technique est devenu furieux et. a licencié l'employée enceinte. Google a montré comment exécuter ChromeOS sur une machine virtuelle Android. Veuillez me donner quelques conseils, quel rôle joue ici time.sleep(6). Microsoft réagit aux rumeurs selon lesquelles l'équipe chinoise d'IA "fait ses valises pour les États-Unis" Le Quotidien du Peuple commente en ligne la charge de type matriochka des logiciels de bureau : Ce n'est qu'en résolvant activement les "ensembles" que nous pourrons avoir un avenir
{{o.name}}
{{m.nom}}

Je suppose que tu aimes

Origine my.oschina.net/u/4843764/blog/11181511
conseillé
Classement