//返回值:sourceipport,desipport,slots,是否有效 //[email protected]:6666|10232-11123->10.13.128.221:6667 func checkCommandValid(c string) (sipport string, des string, slots []string, flag bool) { cdetail := strings.Split(c, "@") sd := strings.Split(cdetail[1], "->") if len(sd) != 2 { email.MSendMail("[sys/redis.go:checkCommandValid] reveive command string is not valid", []byte(c)) return "", "", nil, false } source := sd[0] des = sd[1] if strings.Count(source, "|") < 1 { email.MSendMail("[sys/redis.go:checkCommandValid] reveive command string is not valid", []byte(c)) } temp := strings.Split(source, "|") sipport = temp[0] slots = temp[1:] for _, v := range slots { ss := strings.Split(v, "-") if len(ss) > 2 { return "", "", nil, false } else if len(ss) == 2 { i, e := strconv.Atoi(ss[0]) if e != nil { return "", "", nil, false } ii, e := strconv.Atoi(ss[1]) if e != nil { return "", "", nil, false } if i >= ii { return "", "", nil, false } } } return sipport, des, slots, true }
//ExecRedisCmd 执行redis command func (r *Redises) ExecRedisCmd(ipport, cmd string, arg ...interface{}) []string { defer func() { if err := recover(); err != nil { log.Println("[sys/redis.go:ExecRedisCmd] error", err) es := fmt.Sprint(err) email.MSendMail("[sys/redis.go:ExecRedisCmd] error", []byte(es)) } }() rc := r.getPooledRedisClient(ipport) defer rc.Close() reply, err := rc.Do(cmd, arg...) if err != nil { es := fmt.Sprint(cmd, arg, " run error!:>>>", err) return []string{es} } var result []string switch t := reply.(type) { default: log.Printf("%s 命令 %s, redis 返回输出类型是:%T", cmd, arg, t) result = []string{} case []byte: result = []string{string(reply.([]byte))} case string: result = []string{reply.(string)} case []interface{}: is := reply.([]interface{}) for _, v := range is { result = append(result, string(v.([]byte))) } } return result }
//DealTransSlot 迁移指令处理函数 func (r *Redises) DealTransSlot(sipport string, dip string, slots []string) { defer func() { if err := recover(); err != nil { log.Println("[sys/redis.go:transSlot] error", err) es := fmt.Sprint(err) email.MSendMail("[sys/redis.go:transSlot] error", []byte(es)) } }() r.emailContent = time.Now().String() + "\n" rs := r.ExecRedisCmd(sipport, "cluster", "nodes") wm := wrapRedisNode(rs[0]) //v : [email protected]:6666|10232-11123->10.13.128.221:6667 r.emailContent = fmt.Sprint(r.emailContent, sipport, " to destination ip:", dip, " slots:", slots, " \nGet cluster nodes info:\n", rs, "\n\n>>>>>>>>>>>>>>>>>>begin process>>>>>>>>>>>>>>>\n\n") r.processNodesInfo(sipport, dip, wm, slots...) r.emailContent = fmt.Sprint(r.emailContent, " \n\n done!!!!!!!!!!!!!!!!!!!!!!!!!!") email.MSendMail("[sys/redis.go:DealTransSlot] transinfo", []byte(r.emailContent)) //fmt.Printf("%s\n", r.emailContent) }
//DealCommandChan 处理socket 获取的 转移slot指令 func (r *Redises) DealCommandChan() { go func() { for v := range CommandChan { fmt.Printf("receive command chan string --->%s\n", v) switch v[0] { //v : [email protected]:6666|10232-11123->10.13.128.221:6667 case 'T': sipport, desipport, slots, flag := checkCommandValid(v) if flag { r.DealTransSlot(sipport, desipport, slots) } else { email.MSendMail("[sys/redis.go:checkCommandValid] reveive command string is not valid", []byte(v)) } } } }() }
//RedisAliveCheck redis 实例存货监控 func (r *Redises) RedisAliveCheck(conf *config.Config, errChan chan string) { defer func() { if err := recover(); err != nil { log.Println("[sys/redis.go:RedisAliveCheck] recover error::", err) } }() var result string for _, v := range conf.Redises { ipport := v.Ip + ":" + strconv.Itoa(v.Port) rs := r.ExecRedisCmd(ipport, "PING") if len(rs) != 1 || rs[0] != "PONG" || rs[0] == "" { result = result + "," + ipport } } if result != "" { email.MSendMail("redis 不存活报警", []byte(result)) errChan <- string(result) } }