限流、熔断库sentinel-golang

文章目录

    • 限流
      • 文档
      • 简单示例
      • 预热(冷启动)方式
      • 排队策略
    • 熔断
      • 状态切换术语
      • 错误数量策略
      • 慢查询比例策略
      • 错误比例策略

限流

文档

github链接
官方文档

简单示例

package main

import (
	sentinel "github.com/alibaba/sentinel-golang/api"
	"github.com/alibaba/sentinel-golang/core/base"
	"github.com/alibaba/sentinel-golang/core/flow"
	"log"
)

func main() {
	if err := sentinel.InitDefault();err != nil {
		log.Fatal(err)
	}

	_, err := flow.LoadRules([]*flow.Rule{
		{
			Resource:               "test",
			TokenCalculateStrategy: flow.Direct,
			ControlBehavior:        flow.Reject,	//流量超过阈值就拒绝
			Threshold:              10,		//阈值
			StatIntervalInMs:       1000,	//流量统计周期
		},
	})
	if err != nil {
		log.Fatalf("Unexpected error: %+v", err)
		return
	}

	for i := 0;i<12;i++ {
		e,err := sentinel.Entry("test",sentinel.WithTrafficType(base.Inbound))
		if err != nil {
			log.Println(err)
			continue
		}
		log.Println("没出错")
		e.Exit()
	}
}

预热(冷启动)方式

当系统长期处于低水位的情况下,当流量突然增加时,直接把系统拉升到高水位可能瞬间把系统压垮。通过"冷启动",让通过的流量缓慢增加,在一定时间内逐渐增加到阈值上限,给冷系统一个预热的时间,避免冷系统被压垮。

package main

import (
	"fmt"
	sentinel "github.com/alibaba/sentinel-golang/api"
	"github.com/alibaba/sentinel-golang/core/base"
	"github.com/alibaba/sentinel-golang/core/flow"
	"log"
	"sync"
	"time"
)

func main() {
	if err := sentinel.InitDefault(); err != nil {
		log.Fatal(err)
	}

	_, err := flow.LoadRules([]*flow.Rule{
		{
			Resource:               "test",
			TokenCalculateStrategy: flow.WarmUp, // 预热模式
			ControlBehavior:        flow.Reject,
			WarmUpPeriodSec:        5, // 预热时间
			WarmUpColdFactor:       6, // 预热因子,默认是 3
			Threshold:              800,
			StatIntervalInMs:       1000,
		},
	})
	if err != nil {
		log.Fatalf("Unexpected error: %+v", err)
		return
	}

	var passCount int
	var lock sync.Mutex
	for i := 0; i < 8; i++ {
		go func() {
			for  {
				e, err := sentinel.Entry("test", sentinel.WithTrafficType(base.Inbound))
				if err != nil {
					continue
				}
				e.Exit()
				lock.Lock()
				passCount ++
				lock.Unlock()
			}
		}()

	}
	for i:=1;i<=10;i++{
		pre := passCount
		time.Sleep(time.Second)
		cur := passCount

		fmt.Printf("第 %d 秒通过数量 %d \n",i,cur-pre)
	}
}
$ go run warmup.go
第 1 秒通过数量 2812 秒通过数量 1693 秒通过数量 2004 秒通过数量 2575 秒通过数量 3916 秒通过数量 8007 秒通过数量 8008 秒通过数量 8019 秒通过数量 80010 秒通过数量 802

排队策略

package main

import (
	"fmt"
	sentinel "github.com/alibaba/sentinel-golang/api"
	"github.com/alibaba/sentinel-golang/core/base"
	"github.com/alibaba/sentinel-golang/core/flow"
	"log"
	"sync"
	"time"
)

func main() {
	if err := sentinel.InitDefault(); err != nil {
		log.Fatal(err)
	}

	_, err := flow.LoadRules([]*flow.Rule{
		{
			Resource:               "test",
			TokenCalculateStrategy: flow.Direct,
			ControlBehavior:        flow.Throttling,
			Threshold:              100, // 排队时间是 1000/100 = 10ms
			StatIntervalInMs:       1000,
			MaxQueueingTimeMs:      100, // 允许的最长排队等待时间,默认0,直接拒绝,设置此项sentinel.Entry会阻塞等待
		},
	})
	if err != nil {
		log.Fatalf("Unexpected error: %+v", err)
		return
	}
	start := time.Now()
	var wg sync.WaitGroup
	for i := 0; i < 20; i++ {
		wg.Add(1)
		go func() {
			defer wg.Done()
			e, err := sentinel.Entry("test", sentinel.WithTrafficType(base.Inbound))
			if err != nil {
				fmt.Print("拒绝  ")
				return
			}
			fmt.Print("通过 ")
			e.Exit()
		}()
	}
	wg.Wait()
	fmt.Println()
	fmt.Printf("时长:%v", time.Since(start))
}

结果:

$ go run Throttling.go
通过 拒绝  拒绝  拒绝  拒绝  拒绝  拒绝  拒绝  拒绝  拒绝  通过 通过 通过 通过 通过 通过 通过 通过 通过 通过
时长:101.8116ms

可以看到,当并发收到20个请求时,9个请求立刻被拒绝,10个请求加入了排队,阻塞等待,根据 Threshold (排队时间)进行后续的请求处理

熔断

状态切换术语

熔断状态相互切换解释
限流、熔断库sentinel-golang_第1张图片

错误数量策略

package main

import (
	"errors"
	"fmt"
	"log"
	"math/rand"
	"time"

	sentinel "github.com/alibaba/sentinel-golang/api"
	"github.com/alibaba/sentinel-golang/core/circuitbreaker"
	"github.com/alibaba/sentinel-golang/core/config"
	"github.com/alibaba/sentinel-golang/logging"
	"github.com/alibaba/sentinel-golang/util"
)

type stateChangeTestListener struct {
}

func (s *stateChangeTestListener) OnTransformToClosed(prev circuitbreaker.State, rule circuitbreaker.Rule) {
	fmt.Printf("rule.steategy: %+v, From %s to Closed, time: %d\n", rule.Strategy, prev.String(), util.CurrentTimeMillis())
}

func (s *stateChangeTestListener) OnTransformToOpen(prev circuitbreaker.State, rule circuitbreaker.Rule, snapshot interface{}) {
	fmt.Printf("rule.steategy: %+v, From %s to Open, snapshot: %d, time: %d\n", rule.Strategy, prev.String(), snapshot, util.CurrentTimeMillis())
}

func (s *stateChangeTestListener) OnTransformToHalfOpen(prev circuitbreaker.State, rule circuitbreaker.Rule) {
	fmt.Printf("rule.steategy: %+v, From %s to Half-Open, time: %d\n", rule.Strategy, prev.String(), util.CurrentTimeMillis())
}

func main() {
	conf := config.NewDefaultConfig()
	// for testing, logging output to console
	conf.Sentinel.Log.Logger = logging.NewConsoleLogger()
	err := sentinel.InitWithConfig(conf)
	if err != nil {
		log.Fatal(err)
	}
	ch := make(chan struct{})
	// Register a state change listener so that we could observer the state change of the internal circuit breaker.
	circuitbreaker.RegisterStateChangeListeners(&stateChangeTestListener{})

	_, err = circuitbreaker.LoadRules([]*circuitbreaker.Rule{
		// Statistic time span=5s, recoveryTimeout=3s, maxErrorCount=50
		{
			Resource:                     "abc",
			Strategy:                     circuitbreaker.ErrorCount,  // 根据错误数量熔断
			RetryTimeoutMs:               3000,  // 熔断触发后,进入探测恢复模式(HALF-OPEN)之间的等待时间
			MinRequestAmount:             10,	// 静默数据,小于此数量,不会触发熔断
			StatIntervalMs:               5000,  // 统计周期
			StatSlidingWindowBucketCount: 10,
			Threshold:                    50,  // 超过此错误量,就熔断
		},
	})
	if err != nil {
		log.Fatal(err)
	}

	logging.Info("[CircuitBreaker ErrorCount] Sentinel Go circuit breaking demo is running. You may see the pass/block metric in the metric log.")
	go func() {
		for {
			e, b := sentinel.Entry("abc")
			if b != nil {
				// g1 blocked
				fmt.Print("g1:拒绝  ")
				time.Sleep(time.Duration(rand.Uint64()%20) * time.Millisecond)
			} else {
				if rand.Uint64()%20 > 9 {
					// 调用错误
					fmt.Print("g1:错误  ")
					sentinel.TraceError(e, errors.New("biz error"))
				}else {
					fmt.Print("g1:通过  ")
				}
				
				time.Sleep(time.Duration(rand.Uint64()%80+10) * time.Millisecond)
				e.Exit()
			}
		}
	}()
	go func() {
		for {
			e, b := sentinel.Entry("abc")
			if b != nil {
				// g2 blocked
				fmt.Print("g2:拒绝  ")
				time.Sleep(time.Duration(rand.Uint64()%20) * time.Millisecond)
			} else {
				// g2 passed
				fmt.Print("g2:通过  ")
				time.Sleep(time.Duration(rand.Uint64()%80) * time.Millisecond)
				e.Exit()
			}
		}
	}()
	<-ch
}

看下测试结果:
当一段时间内,错误数量到达我们设置的值时,从closed进入open状态,以后的请求都拒绝。
在这里插入图片描述
经过 RetryTimeoutMs 时间后,进入Half-Open状态,此时允许一定的流量不拒绝,并且没有发生错误,就会进入Closed状态(如图)
在Half-Open状态下,如果发现错误,会进入Open状态。
在这里插入图片描述

g2:通过  g1:错误  g2:通过  g1:错误  g2:通过  g1:错误  g2:通过  g1:通过  g1:通过  g2:通过  g1:错误  g2:通过  g1:错误  g2:
通过  g1:错误  g2:通过  g2:通过  g2:通过  g1:错误  g2:通过  g1:错误  g1:通过  g2:通过  g1:错误  g2:通过  g1:错误  g2:通过
  g2:通过  g1:错误  g2:通过  g1:通过  g2:通过  g1:通过  g2:通过  g1:错误  g2:通过  g1:错误  g1:通过  g2:通过  g2:通过  g1
:通过  g2:通过  g1:通过  g2:通过  g1:通过  g2:通过  g1:错误  g2:通过  g2:通过  g1:错误  g1:通过  g2:通过  g1:通过  g2:通
过  g1:通过  g1:错误  g2:通过  g1:通过  g1:错误  g2:通过  g2:通过  g1:错误  g2:通过  g1:通过  g2:通过  g2:通过  g1:通过
g2:通过  g2:通过  g1:通过  g1:错误  g1:错误  g1:错误  g2:通过  g1:通过  g2:通过  g2:通过  g1:通过  g2:通过  g1:通过  g2:
通过  g1:通过  g2:通过  g1:通过  g2:通过  g2:通过  g1:错误  g1:错误  g2:通过  g2:通过  g1:通过  g2:通过  g2:通过  g1:错误
  g2:通过  g2:通过  g2:通过  g1:通过  g2:通过  g2:通过  g1:错误  g2:通过  g1:通过  g2:通过  g1:通过  g2:通过  g2:通过  g1
:通过  g2:通过  g1:通过  g2:通过  g1:通过  g2:通过  g2:通过  g2:通过  g1:错误  g2:通过  g2:通过  g2:通过  g2:通过  g2:通
过  g1:错误  g1:通过  g2:通过  g1:通过  g1:错误  g2:通过  g1:通过  g2:通过  g2:通过  g2:通过  g1:通过  g2:通过  g1:错误
g2:通过  g2:通过  g1:错误  g2:通过  g1:通过  g2:通过  g2:通过  g2:通过  g1:通过  g2:通过  g1:错误  g2:通过  g2:通过  g2:
通过  g1:通过  g2:通过  g2:通过  g1:错误  g1:错误  g2:通过  g2:通过  g1:通过  g2:通过  g1:通过  g2:通过  g2:通过  g1:错误
  g2:通过  g1:通过  g2:通过  g1:错误  g2:通过  g1:错误  g1:通过  g2:通过  g2:通过  g2:通过  g1:错误  g2:通过  g2:通过  g2
:通过  g2:通过  g2:通过  g1:通过  g2:通过  g2:通过  g2:通过  g2:通过  g1:错误  g2:通过  g1:错误  g1:通过  g2:通过  g1:错
误  g2:通过  g1:通过  g2:通过  g1:通过  g2:通过  g1:通过  g2:通过  g1:通过  g2:通过  g1:通过  g2:通过  g2:通过  g2:通过
g1:通过  g2:通过  g1:通过  g2:通过  g1:通过  g2:通过  g1:通过  g2:通过  g1:错误  g2:通过  g1:错误  g2:通过  g2:通过  g1:
错误  g2:通过  g2:通过  g1:通过  g2:通过  g2:通过  g2:通过  g1:通过  g2:通过  g2:通过  g2:通过  g2:通过  g2:通过  g2:通过
  g1:通过  g2:通过  g2:通过  g1:通过  g2:通过  g2:通过  g1:通过  g2:通过  g2:通过  g1:错误  g2:通过  g1:通过  g1:通过  g2
:通过  g1:通过  g2:通过  g1:错误  g2:通过  g2:通过  g2:通过  g1:错误  g2:通过  g1:错误  g2:通过  g2:通过  g1:错误  g2:通
过  g2:通过  g1:通过  g1:错误  g1:错误  g2:通过  g1:错误  g1:错误  g2:通过  g1:通过  g2:通过  g2:通过  g1:错误  g2:通过
g1:错误  g2:通过  g2:通过  g1:通过  g1:通过  g2:通过  g1:错误  g2:通过  g2:通过  g1:错误  g1:错误  g2:通过  g2:通过  g2:
通过  g1:通过  g2:通过  g1:错误  g2:通过  g2:通过  g1:通过  g2:通过  g1:通过  g1:通过  g2:通过  g2:通过  g1:通过  g2:通过
  g1:通过  g2:通过  g1:通过  g1:错误  g2:通过  g2:通过  g2:通过  g1:通过  g2:通过  g1:通过  g2:通过  g2:通过  g1:通过  g2
:通过  g1:错误  g2:通过  g1:错误  g1:通过  g2:通过  g1:错误  g2:通过  g2:通过  g1:错误  g2:通过  g2:通过  g2:通过  g1:通
过  g2:通过  g2:通过  g1:通过  g2:通过  g2:通过  g1:通过  g2:通过  g2:通过  g1:通过  g2:通过  g2:通过  g1:通过  g2:通过
g2:通过  g2:通过  g2:通过  g1:通过  g1:错误  g2:通过  g1:错误  g2:通过  g2:通过  g2:通过  g1:通过  g2:通过  g2:通过  g1:
错误  g2:通过  g1:通过  g2:通过  g1:错误  g2:通过  g1:错误  g2:通过  g2:通过  g1:错误  g1:通过  g2:通过  g2:通过  g1:错误
  g2:通过  g1:错误  g2:通过  g2:通过  g1:通过  g1:通过  g2:通过  g1:通过  g1:错误  g2:通过  g2:通过  g1:通过  g2:通过  g1
:通过  g2:通过  g1:通过  g2:通过  g2:通过  g1:通过  g1:错误  g2:通过  g1:通过  g2:通过  g2:通过  g1:通过  g2:通过  g2:通
过  g1:通过  g2:通过  g1:通过  g1:错误  g2:通过  g2:通过  g1:通过  g2:通过  g2:通过  g2:通过  g1:错误  g2:通过  g1:错误
g2:通过  g1:错误  g2:通过  g1:通过  g2:通过  g2:通过  g2:通过  g1:通过  g2:通过  g1:通过  g2:通过  g2:通过  g1:通过  g1:
通过  g2:通过  g1:错误  g1:错误  g2:通过  g2:通过  g1:通过  g2:通过  g2:通过  g1:通过  g1:错误  g2:通过  g1:通过  g2:通过
  g1:通过  g2:通过  g2:通过  g1:通过  g2:通过  g1:错误  g2:通过  g2:通过  g1:错误  g2:通过  g2:通过  g1:错误  g2:通过  g2
:通过  g2:通过  g2:通过  g1:错误  g2:通过  g2:通过  g2:通过  g1:通过  g2:通过  g1:通过  g2:通过  g1:通过  g2:通过  g2:通
过  g1:通过  g2:通过  g2:通过  g2:通过  g1:通过  g2:通过  g2:通过  g1:错误  g2:通过  g1:通过  g1:通过  g2:通过  g1:通过
g2:通过  g2:通过  g1:错误  g1:错误  g2:通过  g1:通过  g2:通过  g2:通过  g1:错误  g2:通过  g2:通过  g2:通过  g1:通过  g1:
错误  g2:通过  g2:通过  g2:通过  g2:通过  g1:错误  g1:通过  g2:通过  g2:通过  g1:错误  g2:通过  g1:错误  g2:通过  g1:通过
  g2:通过  g1:错误  g2:通过  g1:通过  g2:通过  g1:错误  g1:错误  g2:通过  g1:通过  g2:通过  g2:通过  g2:通过  g2:通过  g1
:通过  g2:通过  g1:通过  g1:通过  g2:通过  g1:错误  g2:通过  g2:通过  g2:通过  g1:错误  g2:通过  g1:通过  g1:错误  g2:通
过  g1:错误  g1:错误  g2:通过  g2:通过  g2:通过  g1:错误  g1:错误  g2:通过  g1:通过  g1:通过  g2:通过  g2:通过  g1:错误
g2:通过  g1:通过  g1:通过  g2:通过  g2:通过  g2:通过  g1:错误  g2:通过  g1:通过  g2:通过  g2:通过  g1:通过  g2:通过  g2:
通过  g2:通过  g1:通过  g2:通过  g1:通过  g1:通过  g2:通过  g1:错误  g2:通过  g2:通过  g1:通过  g2:通过  g1:错误  g2:通过
  g2:通过  g1:通过  g2:通过  g2:通过  g1:错误  g2:通过  g2:通过  g1:错误  g1:错误  g2:通过  g1:通过  g2:通过  g2:通过  g1
:错误  g1:错误  g2:通过  g1:错误  g2:通过  g1:通过  g2:通过  g2:通过  g1:通过  g1:错误  g2:通过  g2:通过  g1:错误  g1:错
误  g2:通过  g1:错误  g2:通过  g2:通过  g2:通过  g1:错误  g2:通过  g2:通过  g1:错误  g2:通过  g1:错误  g2:通过  g1:通过
g2:通过  g1:错误  g2:通过  g2:通过  g2:通过  g1:错误  g2:通过  g1:错误  g1:通过  g2:通过  g1:通过  g2:通过  g1:错误  g2:
通过  rule.steategy: ErrorCount, From Closed to Open, snapshot: 50, time: 1644724684417
g1:拒绝  g1:拒绝  g1:拒绝  g1:拒绝  g2:拒绝  g2:拒绝  g1:拒绝  g2:拒绝  g2:拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g1:拒绝  g2:
拒绝  g1:拒绝  g2:拒绝  g2:拒绝  g2:拒绝  g1:拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g1:拒绝
  g2:拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g2:拒绝  g2:拒绝  g1:拒绝  g2:拒绝  g2:拒绝  g1:拒绝  g2
:拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g2:拒绝  g2:拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g2:拒绝  g2:拒绝  g1:拒
绝  g2:拒绝  g1:拒绝  g2:拒绝  g2:拒绝  g1:拒绝  g1:拒绝  g2:拒绝  g2:拒绝  g2:拒绝  g1:拒绝  g2:拒绝  g2:拒绝  g2:拒绝
g1:拒绝  g1:拒绝  g2:拒绝  g2:拒绝  g1:拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g1:拒绝  g2:拒绝  g1:
拒绝  g2:拒绝  g2:拒绝  g2:拒绝  g1:拒绝  g1:拒绝  g2:拒绝  g2:拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g1:拒绝  g1:拒绝  g2:拒绝
  g1:拒绝  g1:拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g2:拒绝  g2:拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g1
:拒绝  g2:拒绝  g2:拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g1:拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g2:拒绝  g1:拒
绝  g2:拒绝  g1:拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g1:拒绝  g2:拒绝  g1:拒绝
g2:拒绝  g2:拒绝  g1:拒绝  g2:拒绝  g2:拒绝  g1:拒绝  g1:拒绝  g1:拒绝  g2:拒绝  g2:拒绝  g1:拒绝  g1:拒绝  g1:拒绝  g2:
拒绝  g2:拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g2:拒绝  g2:拒绝  g1:拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g1:拒绝  g2:拒绝  g1:拒绝
  g1:拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g1:拒绝  g1:拒绝  g1:拒绝  g1:拒绝  g2:拒绝  g2:拒绝  g2:拒绝  g1:拒绝  g1:拒绝  g2
:拒绝  g2:拒绝  g2:拒绝  g1:拒绝  g1:拒绝  g2:拒绝  g2:拒绝  g2:拒绝  g1:拒绝  g1:拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g2:拒
绝  g1:拒绝  g2:拒绝  g2:拒绝  g1:拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g2:拒绝
g1:拒绝  g2:拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g1:拒绝  g2:拒绝  g2:拒绝  g1:拒绝  g1:拒绝  g2:拒绝  g2:拒绝  g2:拒绝  g1:
拒绝  g1:拒绝  g1:拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g1:拒绝  g2:拒绝  g2:拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g1:拒绝  g2:拒绝
  g2:拒绝  g1:拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g1:拒绝  g1:拒绝  g2:拒绝  g2:拒绝  g2
:拒绝  g2:拒绝  g1:拒绝  g1:拒绝  g2:拒绝  g2:拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g2:拒绝  g2:拒绝  g1:拒绝  g1:拒绝  g2:拒
绝  g1:拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g1:拒绝  g2:拒绝  g2:拒绝  g2:拒绝  g2:拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g1:拒绝
g2:拒绝  g1:拒绝  g1:拒绝  g2:拒绝  g2:拒绝  g2:拒绝  g1:拒绝  g1:拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g1:
拒绝  g2:拒绝  g1:拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g2:拒绝  g2:拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g1:拒绝
  g1:拒绝  g2:拒绝  g1:拒绝  g1:拒绝  g1:拒绝  g1:拒绝  g2:拒绝  g2:拒绝  g1:拒绝  g1:拒绝  g1:拒绝  g1:拒绝  g2:拒绝  g2
:拒绝  g1:拒绝  g2:拒绝  g2:拒绝  g2:拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g2:拒绝  g2:拒绝  g1:拒绝  g2:拒绝  g2:拒绝  g1:拒
绝  g2:拒绝  g2:拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g2:拒绝  g2:拒绝
g2:拒绝  g2:拒绝  g1:拒绝  g2:拒绝  g2:拒绝  g1:拒绝  g1:拒绝  g1:拒绝  g2:拒绝  g2:拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g1:
拒绝  g1:拒绝  g2:拒绝  g2:拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g1:拒绝  g1:拒绝  g2:拒绝
  g1:拒绝  g1:拒绝  g2:拒绝  g2:拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g2:拒绝  g2:拒绝  g2:拒绝  g1:拒绝  g1:拒绝  g2:拒绝  g1
:拒绝  g1:拒绝  g2:拒绝  g2:拒绝  g1:拒绝  g1:拒绝  g2:拒绝  g2:拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g2:拒绝  g2:拒绝  g1:拒
绝  g1:拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g1:拒绝  g2:拒绝
g1:拒绝  g2:拒绝  g1:拒绝  g1:拒绝  g1:拒绝  g2:拒绝  g2:拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g1:拒绝  g1:
拒绝  g2:拒绝  g1:拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g2:拒绝  g2:拒绝  g2:拒绝  g2:拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g2:拒绝
  g1:拒绝  g2:拒绝  g2:拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g1:拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g2:拒绝  g2:拒绝  g1:拒绝  g2
:拒绝  g1:拒绝  g1:拒绝  g2:拒绝  g2:拒绝  g2:拒绝  g1:拒绝  g1:拒绝  g1:拒绝  g2:拒绝  g2:拒绝  g2:拒绝  g1:拒绝  g2:拒
绝  g1:拒绝  g2:拒绝  g2:拒绝  g1:拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g2:拒绝  g2:拒绝  g1:拒绝
g1:拒绝  g2:拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g2:拒绝  g2:
拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g1:拒绝  g2:拒绝
  g2:拒绝  g2:拒绝  g1:拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g1:拒绝  g1:拒绝  g2:拒绝  g2:拒绝  g1:拒绝  g1:拒绝  g2:拒绝  g1
:拒绝  g2:拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g2:拒绝  g2:拒绝  g2:拒绝  g1:拒
绝  g2:拒绝  g2:拒绝  g1:拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g2:拒绝  g2:拒绝  g1:拒绝  g2:拒绝  g2:拒绝  g2:拒绝  g1:拒绝
g2:拒绝  g1:拒绝  g2:拒绝  g2:拒绝  g2:拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g1:拒绝  g2:拒绝  g2:拒绝  g1:拒绝  g1:拒绝  g2:
拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g2:拒绝  g2:拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g2:拒绝  g1:拒绝
  g2:拒绝  g1:拒绝  g1:拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g2:拒绝  g2:拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g1:拒绝  g2:拒绝  g1
:拒绝  g2:拒绝  g2:拒绝  g1:拒绝  g1:拒绝  g1:拒绝  g2:拒绝  rule.steategy: ErrorCount, From Open to Half-Open, time: 164
4724687426
g1:通过  g2:拒绝  g2:拒绝  g2:拒绝  g2:拒绝  rule.steategy: ErrorCount, From HalfOpen to Closed, time: 1644724687462
g1:通过  g2:通过  g1:错误  g2:通过  g2:通过  g1:通过  g2:通过  g2:通过  g1:错误  g2:通过  g2:通过  g1:通过  g2:通过  g1:
通过  g2:通过  g2:通过  g1:错误  g2:通过  g1:通过  g2:通过  g2:通过  g1:错误  g2:通过  g1:错误  g2:通过  g1:通过  g2:通过
  g2:通过  g2:通过  g2:通过  g1:错误  g2:通过  g1:错误  g2:通过  g2:通过  g1:错误  g2:通过  g1:通过  g2:通过  g2:通过  g2
:通过  g2:通过  g1:错误  g2:通过  g1:错误  g2:通过  g1:错误  g2:通过  g2:通过  g2:通过  g1:通过  g1:错误  g2:通过  g2:通
过  g1:错误  g2:通过  g1:通过  g2:通过  g2:通过  g1:错误  g2:通过  g2:通过  g1:错误  g2:通过  g1:通过  g1:通过  g2:通过
g2:通过  g2:通过  g1:错误  g1:错误  g2:通过  g1:错误  g2:通过  g1:错误  g2:通过  g2:通过  g1:错误  g1:错误  g2:通过  g1:
错误  g2:通过  g2:通过  g2:通过  g1:通过  g1:通过  g2:通过  g2:通过  g1:错误  g2:通过  g2:通过  g1:通过  g2:通过  g2:通过
  g2:通过  g1:错误  g1:错误  g2:通过  g1:错误  g1:错误  g2:通过  g2:通过  g2:通过  g2:通过  g1:通过  g2:通过  g1:通过  g1
:错误  g2:通过  g2:通过  g1:通过  g1:错误  g2:通过  g2:通过  g1:通过  g2:通过  g1:错误  g2:通过  g1:通过  g2:通过  g1:通
过  g2:通过  g2:通过  g1:错误  g2:通过  g1:通过  g2:通过  g2:通过  g2:通过  g1:错误  g1:通过  g2:通过  g2:通过  g2:通过
g1:错误  g2:通过  g1:通过  g2:通过  g1:错误  g2:通过  g1:错误  g2:通过  g1:通过  g2:通过  g2:通过  g1:通过  g2:通过  g1:
通过  g2:通过  g1:错误  g2:通过  g2:通过  g1:通过  g2:通过  g1:错误  g2:通过  g2:通过  g1:错误  g2:通过  g1:错误  g2:通过
  g1:错误  g2:通过  g2:通过  g2:通过  g1:错误  g2:通过  g1:错误  g2:通过  g1:错误  g2:通过  g2:通过  g1:错误  g2:通过  g1
:通过  g1:错误  g1:通过  g2:通过  g2:通过  g1:错误  g1:错误  g2:通过  g1:错误  g2:通过  g2:通过  g1:错误  g2:通过  g1:错
误  g2:通过  rule.steategy: ErrorCount, From Closed to Open, snapshot: 50, time: 1644724691656
g1:拒绝  g1:拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g2:拒绝  g2:拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g2:拒绝  g2:拒绝  g1:拒绝  g2:
拒绝  g1:拒绝  g1:拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g2:拒绝  g2:拒绝  g2:拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g2:拒绝  g2:拒绝
  g2:拒绝  g2:拒绝  g1:拒绝  g2:拒绝  g2:拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g2
:拒绝  g2:拒绝  g1:拒绝  g1:拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g1:拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g1:拒
绝  g2:拒绝  g1:拒绝  g1:拒绝  g2:拒绝  g2:拒绝  g2:拒绝  g2:拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g2:拒绝  g2:拒绝  g1:拒绝
g1:拒绝  g2:拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g1:拒绝  g1:拒绝  g2:拒绝  g2:拒绝  g2:拒绝  g1:
拒绝  g1:拒绝  g2:拒绝  g2:拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g2:拒绝  g2:拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g2:拒绝  g1:拒绝
  g1:拒绝  g2:拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g1:拒绝  g2:拒绝  g2:拒绝  g2:拒绝  g1:拒绝  g2:拒绝  g2:拒绝  g1:拒绝  g1
:拒绝  g2:拒绝  g2:拒绝  g1:拒绝  g2:拒绝  g2:拒绝  g2:拒绝  g1:拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g1:拒
绝  g2:拒绝  g2:拒绝  g1:拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g2:拒绝  g2:拒绝  g1:拒绝  g2:拒绝  g2:拒绝  g2:拒绝  g1:拒绝
g2:拒绝  g2:拒绝  g1:拒绝  g1:拒绝  g2:拒绝  g2:拒绝  g2:拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g1:拒绝  g2:拒绝  g2:拒绝  g1:
拒绝  g2:拒绝  g1:拒绝  g2:拒绝  g2:拒绝  g1:拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g2:拒绝  g2:拒绝  g1:拒绝
  g2:拒绝  g2:拒绝  g1:拒绝  g2:拒绝  g2:拒绝  g2:拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g1:拒绝  g2
:拒绝  g1:拒绝  g2:拒绝  g2:拒绝  g2:拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g1:拒绝  g2:拒绝  g2:拒绝  g1:拒绝  g1:拒绝  g2:拒
绝  g2:拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g2:拒绝
g1:拒绝  g2:拒绝  g2:拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g2:拒绝  g2:拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g1:拒绝  g1:拒绝  g2:
拒绝  g2:拒绝  g1:拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g2:拒绝  g2:拒绝  g2:拒绝  g1:拒绝  g1:拒绝  g2:拒绝
  g2:拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g1:拒绝  g2:拒绝  g2:拒绝  g1:拒绝  g2:拒绝  g2:拒绝  g2:拒绝  g1:拒绝  g2:拒绝  g1
:拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g2:拒绝  g1:拒绝  g1:拒绝  g2:拒绝  g2:拒
绝  g1:拒绝  g2:拒绝  g2:拒绝  g1:拒绝  g1:拒绝  g2:拒绝  g2:拒绝  g1:拒绝  g2:拒绝  exit status 3221225786

慢查询比例策略

参考 错误数策略

错误比例策略

参考 错误数策略

你可能感兴趣的:(golang,开发语言,后端)