>  기사  >  백엔드 개발  > 

WBOY
WBOY원래의
2023-07-25 09:04:541327검색

Go에서 컨텍스트를 사용하여 요청 회로 차단기를 구현하는 방법

마이크로서비스 아키텍처의 인기로 인해 다양한 서비스 간의 통신이 점점 더 빈번해졌습니다. 서비스 간 통신에서는 호출 체인이 매우 길 수 있으며, 한 요청의 실패 또는 시간 초과로 인해 전체 호출 체인이 실패하여 전체 시스템의 가용성에 영향을 미칠 수 있습니다. 단일 서비스의 장애로부터 전체 시스템을 보호하기 위해 요청 회로 차단 기능을 사용하여 특정 서비스에 대한 액세스를 제어하고 제한할 수 있습니다. 이 기사에서는 Go에서 컨텍스트를 사용하여 요청 회로 차단기를 구현하는 방법을 소개합니다.

요청 차단기란 무엇인가요?

회로 차단 요청은 전체 시스템을 보호하기 위해 사용되는 전략입니다. 서비스의 요청 실패율이 미리 정해진 임계값을 초과하면 요청 회로 차단기가 서비스에 대한 액세스를 신속하게 거부하여 연속적인 실패 발생을 방지합니다. 요청 차단기 모드는 일반적으로 서킷 브레이커 패턴(Circuit Breaker Pattern)과 결합하여 사용되며, 요청이 실패하면 서킷 브레이커가 신속하게 개방되어 서비스에 대한 요청을 거부하고 대량의 요청이 쌓이는 것을 방지합니다. 시스템 리소스가 고갈됩니다.

Go에서 컨텍스트를 사용하여 요청 회로 차단기를 구현하는 샘플 코드는 다음과 같습니다.

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("请求成功")
        }
    }
}

위 샘플 코드에서는 CircuitBreaker 구조를 통해 간단한 요청 회로 차단기를 구현했습니다. CircuitBreaker 구조에는 다음과 같은 속성이 있습니다.

  • context 및 cancel: 요청 차단기의 수명 주기를 제어하는 ​​데 사용됩니다. 퓨즈가 열린 후 요청이 거부됩니다.
  • maxFail: 최대 실패 횟수를 설정합니다. 실패 횟수가 설정된 값을 초과하면 퓨즈가 열립니다.
  • fail: 실패한 요청 수를 기록합니다.
  • 차단기: 퓨즈 상태를 기록합니다. true인 경우 퓨즈가 열려 있음을 의미합니다.
  • resetTime: 퓨즈 재설정 시간. 퓨즈를 연 후 이 시간이 지나면 퓨즈가 다시 닫힙니다.

Do 메서드를 통해 특정 요청 작업을 수행할 수 있습니다. 요청이 성공하면 실패 횟수가 재설정되고 nil이 반환됩니다. 요청이 실패하면 실패 횟수가 증가하고, 실패 횟수가 설정 값에 도달하면 퓨즈가 열립니다.
퓨즈가 열리면 새 요청이 즉시 오류 정보를 반환한다는 점에 유의하세요.

메인 함수에서는 샘플 CircuitBreaker를 생성하고 10개의 요청을 시뮬레이션했습니다. 실패 횟수가 설정 값에 도달하면 퓨즈가 열리고 새 요청이 거부됩니다.

컨텍스트 패키지와 사용자 정의 CircuitBreaker 구조를 사용하면 Go에서 요청 차단기 기능을 쉽게 구현할 수 있습니다. 요청 회로 차단기를 사용하면 단일 서비스 장애의 영향으로부터 전체 시스템을 효과적으로 보호하고 시스템의 가용성과 안정성을 향상시킬 수 있습니다.

위 내용은 의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
이전 기사:다음 기사: