Golang限制函数调用次数
Golang限制函数调用次数
项目环境
- ubuntu+go1.14
需求描述
- 限制某个函数5秒内只能调用一次,5秒内的其他调用抛弃
工具包使用
这里用到了官方限流器/time/rate
该限流器是基于Token Bucket(令牌桶)实现的。
简单来说,令牌桶就是一个固定大小的桶,系统会以恒定速率向桶中放Token,桶满则暂时不放。
而用户则从桶中取Token,如果有剩余Token就可以一直取。如果没有剩余Token,则需要等到系统中被放置了Token才行。
方法简介:
NewLimiter
func NewLimiter(r Limit, b int) *Limiter
这里有两个参数:
第一个参数是r Limit。代表每秒可以向Token桶中产生多少token。Limit实际上是float64的别名。
第二个参数是b int。b代表Token桶的容量大小。
除了直接指定每秒产生的Token个数外,还可以用Every方法来指定向Token桶中放置Token的间隔
例如我的需求是5秒只能访问一次,那我就5秒放一个Token,桶中最多保存1个:
var r = rate.Every( 5 * time.Second)
var limiter = NewLimiter(limit, 1);
Wait/WaitN
func (lim *Limiter) Wait(ctx context.Context) (err error)
func (lim *Limiter) WaitN(ctx context.Context, n int) (err error)
Wait是WaitN(ctx,1)的简写。
当使用Wait方法消费Token时,如果此时桶内Token数组不足(小于N),那么Wait方法将会阻塞一段时间,直至Token满足条件。如果充足则直接返回。
Wait方法有一个context参数,我们可以设置context的Deadline或者Timeout,来决定此次Wait的最长时间。
Allow/AllowN
func (lim *Limiter) Allow() bool
func (lim *Limiter) AllowN(now time.Time, n int) bool
Allow是AllowN(time.Now(),1)的简写。
AllowN方法表示,截止到某一时刻,目前桶中数目是否至少为n个,满足则返回true,同时从桶中消费n个token。
反之返回不消费Token,false。
如果你需要在事件超出频率的时候丢弃或跳过事件,就使用AllowN,否则使用Reserve或Wait.
结合我的需求,没有Token就抛弃,我用这个Allow
if !limit.Allow() {
fmt.Println(" has no token")
return
}else{
fmt.Println(" has token")
}
Reserve/ReserveN
func (lim *Limiter) Reserve() *Reservation
func (lim *Limiter) ReserveN(now time.Time, n int) *Reservation
Reserve是ReserveN(time.Now(), 1)的简写。
ReserveN 返回对象Reservation
该对象的Delay()方法返回了需要等待的时间,必须等到等待时间之后,才能进行接下来的工作。
如果不想等待,可以调用Cancel()方法,该方法会将Token归还。
使用示例
r := lim.ReserveN(time.Now(), 1)
if !r.OK() {
// 如果ReserveN 传入的n大于令牌池的容量b,那么返回false.
return
}
time.Sleep(r.Delay())
Act() //处理逻辑
实现Demo
package main
import (
"fmt"
"golang.org/x/time/rate"
"time"
)
func main() {
// 模拟每500毫秒调用一次t函数
for{
t()
time.Sleep(time.Millisecond* 500)
}
}
var r = rate.Every( 5 * time.Second)
var limit = rate.NewLimiter(r, 1)
func t() {
if !limit.Allow() {
fmt.Println(" has no token")
return
}else{
fmt.Println(" has token")
}
}
打印
root@ubuntu14:/home/kingram/sourceCode/test# go build t4.go
root@ubuntu14:/home/kingram/sourceCode/test# ./t4
has token
has no token
has no token
has no token
has no token
has no token
has no token
has no token
has no token
has no token
has token
has no token
has no token
has no token
has no token
has no token
has no token
has no token
has no token
has no token
has token
Golang限制函数调用次数的更多相关文章
- Java 中的 int 与 Integer 用于 List<Integer> 时,以及通过打印变量检測程序执行和函数调用次数计数
总结一下近期做的东西中遇到的问题 1. Java 中的 int 与 Integer 用于 List<Integer> 时 两者之间的关系都是非常清楚的.int 是基本数据类型,存储的是值 ...
- golang mcall
// func mcall(fn func(*g)) // Switch to m->g0's stack, call fn(g). // Fn must never return. It sh ...
- 一个能让你了解所有函数调用顺序的Android库
http://mobile.51cto.com/android-536059.htm 原理 本库其实并没有什么黑科技,本库也没有java代码,核心就是2个build.gradle中的task.首先,原 ...
- How Javascript works (Javascript工作原理) (一) 引擎,运行时,函数调用栈
个人总结:该系列文章对JS底层的工作原理进行了介绍. 这篇文章讲了 运行时:js其实是和AJAX.DOM.Settimeout等WebAPI独立分离开的 调用栈:JavaScript的堆内存管理 和 ...
- Prometheus Metrics 设计的最佳实践和应用实例,看这篇够了!
Prometheus 是一个开源的监控解决方案,部署简单易使用,难点在于如何设计符合特定需求的 Metrics 去全面高效地反映系统实时状态,以助力故障问题的发现与定位.本文即基于最佳实践的 Metr ...
- 怎么调试lua性能
怎么调试lua性能 我们的游戏使用的是Cocos2dx-lua 3.9的项目,最近发现我们的游戏.运行比较缓慢.想做一次性能优化了.其实主要分为GPU.CPU的分别优化.GPU部分的优化.网上有很多优 ...
- JS学习:第二周——NO.1回调函数
[回调函数] 定义:把一个函数的定义阶段,作为参数,传给另一个函数: 回调函数调用次数,取决于条件: 回调函数可以传参: 回调函数可以给变this指向,默认是window: 回调函数没有返回值,for ...
- 跟vczh看实例学编译原理——一:Tinymoe的设计哲学
自从<序>胡扯了快一个月之后,终于迎来了正片.之所以系列文章叫<看实例学编译原理>,是因为整个系列会通过带大家一步一步实现Tinymoe的过程,来介绍编译原理的一些知识点. 但 ...
- SQL SERVER中用户定义标量函数(scalar user defined function)的性能问题
用户定义函数(UDF)分类 SQL SERVER中的用户定义函数(User Defined Functions 简称UDF)分为标量函数(Scalar-Valued Function)和表值函数(T ...
随机推荐
- Zabbix 5.0 优化建议
Blog:博客园 个人 在使用Zabbix过程中,正确的调整Zabbix系统,使之保持高性能是非常重要的,能够充分利用硬件资源,监控更多主机和性能指标. 硬件 关于zabbix server端硬件的建 ...
- Beta——事后分析
事后总结 NameNotFound 团队 项目 内容 北航-2020-软件工程(春季学期) 班级博客 要求 Beta事后分析 课程目标 通过团队合作完成一个软件项目的开发 会议截图 一.设想和目标 软 ...
- jQ的显式迭代和隐式迭代
jQ的显示迭代 隐式迭代 let lis = document.querySelector('li') lis.forEach(function (value, index) { value.styl ...
- Rust trait
Rust trait Rust中的trait类似于Java中的接口,定义了一组可以被类型选择实现的"契约"或共享行为,. 特征定义: trait Playable{ fn play ...
- IDEA 安装 zookeeper 可视化管理插件
1. 安装 zookeeper 插件 打开 IDEA->Settings->Plugins,然后在 Marketplace 输入 "zookeeper" 如下: 插件安 ...
- 思考一个问题STM32的
如果一个定时中断刚刚进入中断服务函数 但是服务函数执行时间太长 又一次触发了中断 会怎样
- java IO教程《三》
缓冲区流讲解(Buffered) 什么是缓冲区? 缓冲流,也叫高效流,是对4个基本的File流的增强,所以也是4个流,按照数据类型分类: 字节缓冲流:BufferedInputStream,Buffe ...
- 『动善时』JMeter基础 — 32、JMeter察看结果树组件详解
目录 1.察看结果树介绍 2.察看结果树界面详解 3.察看结果树的其他功能 (1)将数据写入文件中 (2)Search功能 (3)Scroll automatically选项 4.总结 1.察看结果树 ...
- 2. Servlet3.0注解方式 @WebServlet
web.xml配置还是比较麻烦,这次使用注解方式 编写servlet import javax.servlet.ServletException; import javax.servlet.annot ...
- Python+Selenium学习笔记17 - HTML测试报告
运行少量case时 1 # coding = utf-8 2 3 from selenium import webdriver 4 import unittest 5 import time 6 fr ...