import (
//"fmt"
"math/rand"
"net"
"stathat.com/c/consistent"
"time"
)
// BackendSvr Type
type BackendSvr struct {
svrStr string
isUp bool // is Up or Down
failTimes int
}
var (
pConsisthash *consistent.Consistent
pBackendSvrs map[string]*BackendSvr
)
func initBackendSvrs(svrs []string) { //遍历后端服务 并且添加到一致性哈希表中 另初始化pBackendSvrs key为后端服务地址 value是BackendSvr结构体
pConsisthash = consistent.New()
pBackendSvrs = make(map[string]*BackendSvr)
for _, svr := range svrs {
pConsisthash.Add(svr)
pBackendSvrs[svr] = &BackendSvr{
svrStr: svr,
isUp: true,
failTimes: 0,
}
}
go checkBackendSvrs()
}
//通过连接 获取后端服务地址 ,通过服务地址到哈希表中找对应的BackendSvr
func getBackendSvr(conn net.Conn) (*BackendSvr, bool) {
remoteAddr := conn.RemoteAddr().String()
svr, _ := pConsisthash.Get(remoteAddr)
bksvr, ok := pBackendSvrs[svr]
return bksvr, ok
}
func checkBackendSvrs() { //判断后端服务器健康状态以及是否可以使用 是否达到设置失败次数
// scheduler every 10 seconds
rand.Seed(time.Now().UnixNano())
t := time.Tick(time.Duration(10)*time.Second + time.Duration(rand.Intn(100))*time.Millisecond*100) //10s +随机毫秒数 后 执行下面代码
for _ = range t {
for _, v := range pBackendSvrs {
if v.failTimes >= pConfig.FailOver && v.isUp == true {
v.isUp = false
pConsisthash.Remove(v.svrStr)
}
}
}
}