方法一:
1, 首先介绍一下 “sync/atomic” 包下面的SwapInt32 函数
用法:
func SwapInt32(addr *int32, new int32) (old int32)
解释:函数用于将新值自动存储到* addr中,并返回先前的* addr值。原子操作
返回值:它将新的int32值存储到* addr中,并返回先前的* addr值。
2, 举例 如何实现流量控制
func main() {
var precent int32 = 0
loop := 0
// 截取10%的流量
rate := 10
for {
i ++;
if loop > 1000 {
break;
}
var old_val = atomic.SwapInt32(&precent, (precent+1)%100)
if old_val < 10 {
fmt.Println(" capture the traffic", old_val)
}
// Prints new and old value
fmt.Println("Stored new value:", precent, ", Old value:", old_val)
}
}
方法二:
1,首先介绍一下 “sync/atomic” 包下面的AddUint32() 函数
func AddUint32(addr *uint32, delta uint32) (new uint32)
addr表示地址,而delta表示少量大于零的位
方法解释:原子的把将增量自动添加到* addr中并返回改地址上新的值
返回值:它自动添加addr和delta并返回一个新值。
例如:如果我们要原子的将int32类型的变量i32的值减小3话,可以这样操作:atomic.AddInt32(&i32, -3)
2,实现一个流量控制类。
第一步,定义流量控制类
type TrafficCapture struct {
// 存放流量数据
source []int
queryCount uint32
// the capture base num,for example 100
base int
// the captrue rate
ratio int
}
第二部:初始化控制类
func NewTrafficCapture(base int, ratio int) *TrafficCapture {
source := make([]int, base)
for i := 0; i < base; i++ {
source[i] = i
}
// 打乱数据
rand.Shuffle(base, func(i, j int) {
source[i], source[j] = source[j], source[i]
})
return &TrafficControl{
source: source,
base: base,
ratio: ratio,
}
}
第三部分:流量截取
返回true,则截取流量,返回false则放过
func (t *TrafficControl) Allow() bool {
rate := t.source[int(atomic.AddUint32(&t.queryCount, 1))%t.base]
if rate < t.ratio {
return true
} else {
return false
}
}