Comment utiliser le contexte pour implémenter un disjoncteur de requête dans Go
Avec la popularité de l'architecture des microservices, la communication entre les différents services est devenue de plus en plus fréquente. Dans la communication interservices, la chaîne d'appels peut être très longue, et l'échec ou l'expiration d'une demande peut entraîner l'échec de l'ensemble de la chaîne d'appels, affectant ainsi la disponibilité de l'ensemble du système. Afin de protéger l'ensemble du système contre la panne d'un seul service, nous pouvons utiliser la coupure de circuit sur demande pour contrôler et limiter l'accès à un certain service. Cet article explique comment utiliser le contexte pour implémenter un disjoncteur de demande dans Go.
Qu'est-ce qu'un disjoncteur demandé ?
La demande de coupure de circuit est une stratégie utilisée pour protéger l'ensemble du système. Lorsque le taux d'échec des requêtes d'un service dépasse un seuil prédéterminé, le disjoncteur de requêtes refusera rapidement l'accès au service, évitant ainsi l'apparition de pannes en cascade. Le mode de demande de disjoncteur est généralement utilisé en combinaison avec le modèle de disjoncteur (Circuit Breaker Pattern). Lorsqu'une demande échoue, le disjoncteur s'ouvre rapidement, rejetant ainsi les demandes de service et empêchant un grand nombre de demandes de s'accumuler et de s'accumuler. provoquant l'épuisement des ressources du système.
L'exemple de code pour utiliser le contexte pour implémenter un disjoncteur de demande dans Go est le suivant :
package main import ( "context" "fmt" "sync" "time" ) type CircuitBreaker struct { context context.Context cancel context.CancelFunc maxFail int fail int breaker bool resetTime time.Duration breakerMux sync.Mutex } func NewCircuitBreaker(maxFail int, resetTime time.Duration) *CircuitBreaker { ctx, cancel := context.WithCancel(context.Background()) circuitBreaker := &CircuitBreaker{ context: ctx, cancel: cancel, maxFail: maxFail, fail: 0, breaker: false, resetTime: resetTime, breakerMux: sync.Mutex{}, } return circuitBreaker } func (c *CircuitBreaker) Do(req func() error) error { select { case <-c.context.Done(): return fmt.Errorf("circuit breaker is open") default: if !c.breaker { err := req() if err == nil { c.reset() } else { c.fail++ if c.fail >= c.maxFail { c.breakerMux.Lock() c.breaker = true c.breakerMux.Unlock() go time.AfterFunc(c.resetTime, c.reset) } } return err } else { return fmt.Errorf("circuit breaker is open") } } } func (c *CircuitBreaker) reset() { c.fail = 0 c.breakerMux.Lock() c.breaker = false c.breakerMux.Unlock() c.cancel() } func main() { circuitBreaker := NewCircuitBreaker(3, 2*time.Minute) // 进行模拟请求 for i := 0; i < 10; i++ { err := circuitBreaker.Do(func() error { // 这里执行实际的请求操作,此处只是模拟 fmt.Println("执行请求...") if i%5 == 0 { return fmt.Errorf("request failed") } return nil }) if err != nil { fmt.Printf("请求失败: %v ", err) } else { fmt.Println("请求成功") } } }
Dans l'exemple de code ci-dessus, nous avons implémenté un simple disjoncteur de demande via la structure CircuitBreaker. La structure CircuitBreaker a les attributs suivants :
Des opérations de requête spécifiques peuvent être effectuées via la méthode Do. Si la requête réussit, le nombre d'échecs sera réinitialisé et zéro sera renvoyé. Si la demande échoue, le nombre de défaillances sera incrémenté et lorsque le nombre de défaillances atteindra la valeur définie, le fusible sera ouvert.
Il convient de noter que lorsque le fusible est ouvert, les nouvelles requêtes renverront immédiatement des informations d'erreur.
Dans la fonction principale, nous avons créé un exemple de CircuitBreaker et simulé 10 requêtes. Lorsque le nombre de pannes atteint la valeur définie, le fusible s'ouvrira et les nouvelles demandes seront rejetées.
En utilisant le package de contexte et la structure CircuitBreaker personnalisée, nous pouvons facilement implémenter la fonction de disjoncteur de requête dans Go. L'utilisation d'un disjoncteur sur demande peut protéger efficacement l'ensemble du système contre l'impact d'une seule panne de service et améliorer la disponibilité et la stabilité du système.
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!