示例#1
0
func proxy(method string, args interface{}, reply interface{}) error {
	// 随机遍历hbs列表,直到数据发送成功 或者 遍历完
	err := fmt.Errorf("proxy connections not available")
	sendOk := false
	rint := rand.Int()
	for i := 0; i < HbsNum && !sendOk; i++ {
		idx := (i + rint) % HbsNum
		host := HbsHostnames[idx]
		addr := HbsMap[host]

		// 过滤掉建连缓慢的host, 否则会严重影响发送速率
		key := addr + "." + method
		cc := pfc.GetCounterCount(key)
		if cc >= HbsMaxConns {
			continue
		}
		pfc.Counter(key, 1)
		err = ConnPools.Call(addr, method, args, reply)
		pfc.Counter(key, -1)

		if err == nil {
			pfc.Meter(key+".ok", 1)
			sendOk = true
		} else {
			pfc.Meter(key+".error", 1)
		}
	}
	return err
}
func forward2TransferTask(Q *nlist.SafeListLimited, concurrent int32) {
	cfg := g.Config()
	batch := int(cfg.Transfer.Batch)
	maxConns := int64(cfg.Transfer.MaxConns)
	retry := int(cfg.Transfer.Retry)
	if retry < 1 {
		retry = 1
	}

	sema := nsema.NewSemaphore(int(concurrent))
	transNum := len(TransferHostnames)

	for {
		items := Q.PopBackBy(batch)
		count := len(items)
		if count == 0 {
			time.Sleep(time.Millisecond * 50)
			continue
		}

		transItems := make([]*cmodel.MetricValue, count)
		for i := 0; i < count; i++ {
			transItems[i] = convert(items[i].(*cmodel.MetaData))
		}

		sema.Acquire()
		go func(transItems []*cmodel.MetricValue, count int) {
			defer sema.Release()
			var err error

			// 随机遍历transfer列表,直到数据发送成功 或者 遍历完;随机遍历,可以缓解慢transfer
			resp := &g.TransferResp{}
			sendOk := false

			for j := 0; j < retry && !sendOk; j++ {
				rint := rand.Int()
				for i := 0; i < transNum && !sendOk; i++ {
					idx := (i + rint) % transNum
					host := TransferHostnames[idx]
					addr := TransferMap[host]

					// 过滤掉建连缓慢的host, 否则会严重影响发送速率
					cc := pfc.GetCounterCount(host)
					if cc >= maxConns {
						continue
					}

					pfc.Counter(host, 1)
					err = SenderConnPools.Call(addr, "Transfer.Update", transItems, resp)
					pfc.Counter(host, -1)

					if err == nil {
						sendOk = true
						// statistics
						TransferSendCnt[host].IncrBy(int64(count))
					} else {
						// statistics
						TransferSendFailCnt[host].IncrBy(int64(count))
					}
				}
			}

			// statistics
			if !sendOk {
				if cfg.Debug {
					log.Printf("send to transfer fail, connpool:%v", SenderConnPools.Proc())
				}
				pfc.Meter("SendFail", int64(count))
			} else {
				pfc.Meter("Send", int64(count))
			}
		}(transItems, count)
	}
}