NOTE
hystrix
1. circuit A Go implementation of Hystrix for circuit breaking 2. Usage hystrix.go main.go 3. References
This is a historical learning note and may contain outdated or incomplete understanding.
1. circuit
A Go implementation of Hystrix, used for service circuit breaking. Circuit breaking is one form of degradation; other approaches include switch-based degradation.
2. Usage
- hystrix.go
package hystrix
import (
"expvar"
"github.com/cep21/circuit"
"github.com/cep21/circuit/closers/hystrix"
"github.com/cep21/circuit/metriceventstream"
"log"
"net/http"
"time"
)
var GlobalManager *circuit.Manager
func init() {
configuration := hystrix.Factory{
// Hystrix open logic is to open the circuit after an % of errors
ConfigureOpener: hystrix.ConfigureOpener{
// We change the default to wait for 10 requests, not 20, before checking to close
RequestVolumeThreshold: 10,
// The default values match what hystrix does by default
},
// Hystrix close logic is to sleep then check
ConfigureCloser: hystrix.ConfigureCloser{
SleepWindow: time.Second * 1,
// The default values match what hystrix does by default
},
}
//sf := rolling.StatFactory{}
manager := circuit.Manager{
DefaultCircuitProperties: []circuit.CommandPropertiesConstructor{configuration.Configure},
}
GlobalManager = &manager
manager.MustCreateCircuit("hello", circuit.Config{
Execution: circuit.ExecutionConfig{
// Time out the context after a few ms
Timeout: time.Second * 1,
},
})
go startMetrics(&manager)
go startServer()
}
func startMetrics(manager *circuit.Manager) {
expvar.Publish("hystrix", manager.Var())
metricEventStream := metriceventstream.MetricEventStream{
Manager: manager,
}
if err := metricEventStream.Start(); err != nil {
log.Fatal(err)
}
}
func startServer() {
log.Fatal(http.ListenAndServe(":8080", nil))
}
- main.go
package main
import (
"context"
"fmt"
"http_builder/builder"
"http_builder/hystrix"
"net/http"
"time"
)
func main() {
for i := 0; i < 50; i++ {
if i == 9 {
time.Sleep(time.Second * 2)
}
circuit := hystrix.GlobalManager.GetCircuit("hello")
// Execute on the current thread
errResult := circuit.Go(context.Background(), func(ctx context.Context) error {
return requestBaidu(i)
}, func(ctx context.Context, err error) error {
fmt.Printf("execute fallback func for the %dth time\n", i+1)
return err
})
if errResult != nil {
//log.Println("fallback Result of execution:", errResult)
continue
}
}
time.Sleep(time.Hour * 1)
}
func requestBaidu(i int) error {
fmt.Printf("execute run func for the %dth time\n", i+1)
resp, cancel, err := builder.NewHttpBuilder().
Method(http.MethodGet).
Url("https://www.baidu.com/s").
QueryParam("wd", "test").
DoRequest()
if err != nil {
return err
}
cancel()
resp.Body.Close()
return nil
}
Discussion
Sign in with GitHub to comment. Discussions are stored as GitHub Issues.View on GitHub