| 
18 | 18 | // Sentinel circuit breaker module supports three strategies:  | 
19 | 19 | //  | 
20 | 20 | //  1. SlowRequestRatio: the ratio of slow response time entry(entry's response time is great than max slow response time) exceeds the threshold. The following entry to resource will be broken.  | 
21 |  | -//                       In SlowRequestRatio strategy, user must set max response time.  | 
 | 21 | +//     In SlowRequestRatio strategy, user must set max response time.  | 
22 | 22 | //  2. ErrorRatio: the ratio of error entry exceeds the threshold. The following entry to resource will be broken.  | 
23 | 23 | //  3. ErrorCount: the number of error entry exceeds the threshold. The following entry to resource will be broken.  | 
24 | 24 | //  | 
 | 
32 | 32 | //  | 
33 | 33 | // Sentinel circuit breaker provides the listener to observe events of state changes.  | 
34 | 34 | //  | 
35 |  | -//  type StateChangeListener interface {  | 
36 |  | -//  	OnTransformToClosed(prev State, rule Rule)  | 
 | 35 | +//	type StateChangeListener interface {  | 
 | 36 | +//		OnTransformToClosed(prev State, rule Rule)  | 
37 | 37 | //  | 
38 |  | -//  	OnTransformToOpen(prev State, rule Rule, snapshot interface{})  | 
 | 38 | +//		OnTransformToOpen(prev State, rule Rule, snapshot interface{})  | 
39 | 39 | //  | 
40 |  | -//  	OnTransformToHalfOpen(prev State, rule Rule)  | 
41 |  | -//  }  | 
 | 40 | +//		OnTransformToHalfOpen(prev State, rule Rule)  | 
 | 41 | +//	}  | 
42 | 42 | //  | 
43 | 43 | // Here is the example code to use circuit breaker:  | 
44 | 44 | //  | 
45 |  | -//  type stateChangeTestListener struct {}  | 
46 |  | -//  | 
47 |  | -//  func (s *stateChangeTestListener) OnTransformToClosed(prev circuitbreaker.State, rule circuitbreaker.Rule) {  | 
48 |  | -//  	fmt.Printf("rule.steategy: %+v, From %s to Closed, time: %d\n", rule.Strategy, prev.String(), util.CurrentTimeMillis())  | 
49 |  | -//  }  | 
50 |  | -//  | 
51 |  | -//  func (s *stateChangeTestListener) OnTransformToOpen(prev circuitbreaker.State, rule circuitbreaker.Rule, snapshot interface{}) {  | 
52 |  | -//  	fmt.Printf("rule.steategy: %+v, From %s to Open, snapshot: %.2f, time: %d\n", rule.Strategy, prev.String(), snapshot, util.CurrentTimeMillis())  | 
53 |  | -//  }  | 
54 |  | -//  | 
55 |  | -//  func (s *stateChangeTestListener) OnTransformToHalfOpen(prev circuitbreaker.State, rule circuitbreaker.Rule) {  | 
56 |  | -//  	fmt.Printf("rule.steategy: %+v, From %s to Half-Open, time: %d\n", rule.Strategy, prev.String(), util.CurrentTimeMillis())  | 
57 |  | -//  }  | 
58 |  | -//  | 
59 |  | -//  func main() {  | 
60 |  | -//  	err := sentinel.InitDefault()  | 
61 |  | -//  	if err != nil {  | 
62 |  | -//  		log.Fatal(err)  | 
63 |  | -//  	}  | 
64 |  | -//  	ch := make(chan struct{})  | 
65 |  | -//  	// Register a state change listener so that we could observer the state change of the internal circuit breaker.  | 
66 |  | -//  	circuitbreaker.RegisterStateChangeListeners(&stateChangeTestListener{})  | 
67 |  | -//  | 
68 |  | -//  	_, err = circuitbreaker.LoadRules([]*circuitbreaker.Rule{  | 
69 |  | -//  	// Statistic time span=10s, recoveryTimeout=3s, slowRtUpperBound=50ms, maxSlowRequestRatio=50%  | 
70 |  | -//  		{  | 
71 |  | -//  			Resource:         "abc",  | 
72 |  | -//  			Strategy:         circuitbreaker.SlowRequestRatio,  | 
73 |  | -//  			RetryTimeoutMs:   3000,  | 
74 |  | -//  			MinRequestAmount: 10,  | 
75 |  | -//  			StatIntervalMs:   10000,  | 
76 |  | -//  			MaxAllowedRtMs:   50,  | 
77 |  | -//  			Threshold:        0.5,  | 
78 |  | -//  		},  | 
79 |  | -//  		// Statistic time span=10s, recoveryTimeout=3s, maxErrorRatio=50%  | 
80 |  | -//  		{  | 
81 |  | -//  			Resource:         "abc",  | 
82 |  | -//  			Strategy:         circuitbreaker.ErrorRatio,  | 
83 |  | -//  			RetryTimeoutMs:   3000,  | 
84 |  | -//  			MinRequestAmount: 10,  | 
85 |  | -//  			StatIntervalMs:   10000,  | 
86 |  | -//  			Threshold:        0.5,  | 
87 |  | -//  		},  | 
88 |  | -//  	})  | 
89 |  | -//  	if err != nil {  | 
90 |  | -//  		log.Fatal(err)  | 
91 |  | -//  	}  | 
92 |  | -//  | 
93 |  | -//  	fmt.Println("Sentinel Go circuit breaking demo is running. You may see the pass/block metric in the metric log.")  | 
94 |  | -//  	go func() {  | 
95 |  | -//  		for {  | 
96 |  | -//  			e, b := sentinel.Entry("abc")  | 
97 |  | -//  			if b != nil {  | 
98 |  | -//  				//fmt.Println("g1blocked")  | 
99 |  | -//  				time.Sleep(time.Duration(rand.Uint64()%20) * time.Millisecond)  | 
100 |  | -//  			} else {  | 
101 |  | -//  				if rand.Uint64()%20 > 9 {  | 
102 |  | -//  					// Record current invocation as error.  | 
103 |  | -//  					sentinel.TraceError(e, errors.New("biz error"))  | 
104 |  | -//  				}  | 
105 |  | -//  				//fmt.Println("g1passed")  | 
106 |  | -//  				time.Sleep(time.Duration(rand.Uint64()%80+10) * time.Millisecond)  | 
107 |  | -//  				e.Exit()  | 
108 |  | -//  			}  | 
109 |  | -//  		}  | 
110 |  | -//		}()  | 
111 |  | -//  | 
112 |  | -//  	go func() {  | 
113 |  | -//  		for {  | 
114 |  | -//  			e, b := sentinel.Entry("abc")  | 
115 |  | -//  			if b != nil {  | 
116 |  | -//  				//fmt.Println("g2blocked")  | 
117 |  | -//  				time.Sleep(time.Duration(rand.Uint64()%20) * time.Millisecond)  | 
118 |  | -//  			} else {  | 
119 |  | -//  				//fmt.Println("g2passed")  | 
120 |  | -//  				time.Sleep(time.Duration(rand.Uint64()%80) * time.Millisecond)  | 
121 |  | -//  				e.Exit()  | 
122 |  | -//  			}  | 
123 |  | -//  		}  | 
124 |  | -//  	}()  | 
125 |  | -//  	<-ch  | 
126 |  | -//  }  | 
127 |  | -//  | 
 | 45 | +//	 type stateChangeTestListener struct {}  | 
 | 46 | +//  | 
 | 47 | +//	 func (s *stateChangeTestListener) OnTransformToClosed(prev circuitbreaker.State, rule circuitbreaker.Rule) {  | 
 | 48 | +//	 	fmt.Printf("rule.steategy: %+v, From %s to Closed, time: %d\n", rule.Strategy, prev.String(), util.CurrentTimeMillis())  | 
 | 49 | +//	 }  | 
 | 50 | +//  | 
 | 51 | +//	 func (s *stateChangeTestListener) OnTransformToOpen(prev circuitbreaker.State, rule circuitbreaker.Rule, snapshot interface{}) {  | 
 | 52 | +//	 	fmt.Printf("rule.steategy: %+v, From %s to Open, snapshot: %.2f, time: %d\n", rule.Strategy, prev.String(), snapshot, util.CurrentTimeMillis())  | 
 | 53 | +//	 }  | 
 | 54 | +//  | 
 | 55 | +//	 func (s *stateChangeTestListener) OnTransformToHalfOpen(prev circuitbreaker.State, rule circuitbreaker.Rule) {  | 
 | 56 | +//	 	fmt.Printf("rule.steategy: %+v, From %s to Half-Open, time: %d\n", rule.Strategy, prev.String(), util.CurrentTimeMillis())  | 
 | 57 | +//	 }  | 
 | 58 | +//  | 
 | 59 | +//	 func main() {  | 
 | 60 | +//	 	err := sentinel.InitDefault()  | 
 | 61 | +//	 	if err != nil {  | 
 | 62 | +//	 		log.Fatal(err)  | 
 | 63 | +//	 	}  | 
 | 64 | +//	 	ch := make(chan struct{})  | 
 | 65 | +//	 	// Register a state change listener so that we could observer the state change of the internal circuit breaker.  | 
 | 66 | +//	 	circuitbreaker.RegisterStateChangeListeners(&stateChangeTestListener{})  | 
 | 67 | +//  | 
 | 68 | +//	 	_, err = circuitbreaker.LoadRules([]*circuitbreaker.Rule{  | 
 | 69 | +//	 	// Statistic time span=10s, recoveryTimeout=3s, slowRtUpperBound=50ms, maxSlowRequestRatio=50%  | 
 | 70 | +//	 		{  | 
 | 71 | +//	 			Resource:         "abc",  | 
 | 72 | +//	 			Strategy:         circuitbreaker.SlowRequestRatio,  | 
 | 73 | +//	 			RetryTimeoutMs:   3000,  | 
 | 74 | +//	 			MinRequestAmount: 10,  | 
 | 75 | +//	 			StatIntervalMs:   10000,  | 
 | 76 | +//	 			MaxAllowedRtMs:   50,  | 
 | 77 | +//	 			Threshold:        0.5,  | 
 | 78 | +//	 		},  | 
 | 79 | +//	 		// Statistic time span=10s, recoveryTimeout=3s, maxErrorRatio=50%  | 
 | 80 | +//	 		{  | 
 | 81 | +//	 			Resource:         "abc",  | 
 | 82 | +//	 			Strategy:         circuitbreaker.ErrorRatio,  | 
 | 83 | +//	 			RetryTimeoutMs:   3000,  | 
 | 84 | +//	 			MinRequestAmount: 10,  | 
 | 85 | +//	 			StatIntervalMs:   10000,  | 
 | 86 | +//	 			Threshold:        0.5,  | 
 | 87 | +//	 		},  | 
 | 88 | +//	 	})  | 
 | 89 | +//	 	if err != nil {  | 
 | 90 | +//	 		log.Fatal(err)  | 
 | 91 | +//	 	}  | 
 | 92 | +//  | 
 | 93 | +//	 	fmt.Println("Sentinel Go circuit breaking demo is running. You may see the pass/block metric in the metric log.")  | 
 | 94 | +//	 	go func() {  | 
 | 95 | +//	 		for {  | 
 | 96 | +//	 			e, b := sentinel.Entry("abc")  | 
 | 97 | +//	 			if b != nil {  | 
 | 98 | +//	 				//fmt.Println("g1blocked")  | 
 | 99 | +//	 				time.Sleep(time.Duration(rand.Uint64()%20) * time.Millisecond)  | 
 | 100 | +//	 			} else {  | 
 | 101 | +//	 				if rand.Uint64()%20 > 9 {  | 
 | 102 | +//	 					// Record current invocation as error.  | 
 | 103 | +//	 					sentinel.TraceError(e, errors.New("biz error"))  | 
 | 104 | +//	 				}  | 
 | 105 | +//	 				//fmt.Println("g1passed")  | 
 | 106 | +//	 				time.Sleep(time.Duration(rand.Uint64()%80+10) * time.Millisecond)  | 
 | 107 | +//	 				e.Exit()  | 
 | 108 | +//	 			}  | 
 | 109 | +//	 		}  | 
 | 110 | +//			}()  | 
 | 111 | +//  | 
 | 112 | +//	 	go func() {  | 
 | 113 | +//	 		for {  | 
 | 114 | +//	 			e, b := sentinel.Entry("abc")  | 
 | 115 | +//	 			if b != nil {  | 
 | 116 | +//	 				//fmt.Println("g2blocked")  | 
 | 117 | +//	 				time.Sleep(time.Duration(rand.Uint64()%20) * time.Millisecond)  | 
 | 118 | +//	 			} else {  | 
 | 119 | +//	 				//fmt.Println("g2passed")  | 
 | 120 | +//	 				time.Sleep(time.Duration(rand.Uint64()%80) * time.Millisecond)  | 
 | 121 | +//	 				e.Exit()  | 
 | 122 | +//	 			}  | 
 | 123 | +//	 		}  | 
 | 124 | +//	 	}()  | 
 | 125 | +//	 	<-ch  | 
 | 126 | +//	 }  | 
128 | 127 | package circuitbreaker  | 
0 commit comments