什么是QPS
QPS 每秒能处理的请求数,超过这个数值,系统的响应时间就会增大,甚至导致系统奔溃宕机。
QPS怎么去计算,才能更好的去设计
首先我们需要知道一个QPS的计算方法,有助于我们对系统的QPS有个大概的估计。
假设我们有1亿个请求:(百分之80的请求发生在百分之20的时间中)
示例
1、qps = 1000000000.8/243600*0.2 = 4629 所以如果只有一台机器,那么qps=4629左右,
如果只有一台机器的话,那qps=4629左右。单机最大qps我们可以通过压测来评估。如果我们定义接口在1s之内能响应属于正常情况,那压测的时候,我们逐渐增大模拟的qps,当接口平均响应时间大于1s,那此时的qps就是系统能接受的最大qps。
2、每天300w PV 的在单台机器上,这台机器需要多少QPS?
( 3000000 * 0.8 ) / (86400 * 0.2 ) = 139 (QPS)。
一般需要达到139QPS,因为是峰值。
问:如果一台机器的QPS是58,需要几台机器来支持?
答:139 / 58 = 3
部分使用方式
var ipMap = map[string]*rate.Limiter -- 根据ip设置不同限流,存入map
var mu = *sync.RWMutex -- 读写锁
func GetLimiter(unique string,r rate.Limit, defaultQPS int) *rate.Limiter{
mu.RLock() //开启读锁
limiter, exist := i.map[unique]
mu.RUnlock() //关闭读锁
if exist {
return limiter
}
//开启限流
l := rate.NewLimiter(r, defaultQPS)
i.mu.Lock() //加锁
//进行ip添加操作
map[unique] = l
mu.Unlock()
return l
}
使用方式
var limit = GetRateLimiter(unique, 50, 50)
unique -- ip、srv等唯一的标识
在单独的方法中限流
func TestXXXX(t *testing.T){
r := limit.Reserve()
// r.Ok 判断是否达到令牌可用数量
// 如果延迟时间达到2s,直接熔断
if rv.Delay() > 2*time.Second {
return errorx.NewFromString("too many request")
}
//
time.Sleep(rv.Delay())
// 原本的逻辑
xxxxxx
}
单元测试
var limitvx = GetLimiter("xxx", 25, 25)
func TestGetLimiter(t *testing.T) {
// 10s
go func(){
time.Sleep(10 * time.Second)
os.Exit(0)
}()
for i := 0; i < 25000; i++ {
rv := limitvx.Reserve()
// 超频后,下一次执行大于2秒,直接熔断
if rv.Delay() > 2*time.Second {
fmt.Println("----------")
return
}
time.Sleep(rv.Delay())
fmt.Println(i)
}
}
在某一个请求上限流
func LimitRate(r *rate.Limiter) gin.HandlerFunc {
return func(c *gin.Context) {
r.Wait(context.Background())
c.Next()
}
}
var l = rate.New(1,50)
r.POST("/xxxxxxx/", LimitRate(l), xxxxx)