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 ...
随机推荐
- [Django框架之路由层匹配、有名 无名分组、反向解析、路由分发、名称空间、伪静态、本地虚拟环境、django版本区别]
[Django框架之路由层匹配.有名 无名分组.反向解析.路由分发.名称空间.伪静态.本地虚拟环境.django版本区别] 路由层 路由即请求地址与视图函数的映射关系,如果把网站比喻成一本书,那路由就 ...
- Linux常见错误解决办法
1. 程序运行的一些基础知识 1. 编译程序时去哪找头文件? 系统目录:就是交叉编译工具链里的某个 include 目录:也可以自己指定:编译时用 " -I dir "选项指定. ...
- Zabbix 监控介绍
Zabbix 监控介绍 1.Zabbix监控架构 2.Zabbix 优点 开源无软件成本投入 Server对设备性能要求低 支持设备多,自带多种监控模板 支持分布式集中管理,有自动发现功能,可以实现自 ...
- 最简单的方法是使用标准的 Linux GUI 程序之一: i-nex 收集硬件信息,并且类似于 Windows 下流行的 CPU-Z 的显示。 HardInfo 显示硬件具体信息,甚至包括一组八个的流行的性能基准程序,你可以用它们评估你的系统性能。 KInfoCenter 和 Lshw 也能够显示硬件的详细信息,并且可以从许多软件仓库中获取。
最简单的方法是使用标准的 Linux GUI 程序之一: i-nex 收集硬件信息,并且类似于 Windows 下流行的 CPU-Z 的显示. HardInfo 显示硬件具体信息,甚至包括一组八个的流 ...
- docker,docker-compose,harbor安装
安装docker-ce 下载docker-ce.repo: wget -O /etc/yum.repos.d/docker-ce.repo https://download.docker.com/li ...
- python基础之面向对象(一)(概念、实例、魔法方法)
一.面向对象概念理解 1.面向对象和面向过程 面向过程:核心过程二字,过程即解决问题的步骤,就是先干什么后干什么 基于该思想写程序就好比在这是一条流水线,是一种机械式的思维方式 优点:复杂的过程流程化 ...
- shell进阶之tree、pstree、lsof命令详解
一.tree命令详解: 主要功能是创建文件列表,将所有文件以树的形式列出来 -a 显示所有文件和目录. -A 使用ASNI绘图字符显示树状图而非以ASCII字符组合. -C 在文件和目录清单加上色彩, ...
- Heap Size 与 Stack Size
Heap Size:如果没有用到标准库的malloc,就是废物,纯属浪费内存,所以直接设置为0即可: Stack Size :最大的可读写变量的大小即可:
- Centos7 搭建vsftpd
1.安装vsftpd 在线安装:yum -y install vsftpd 离线安装:下载vsftp的rpm包,通过rpm -ivh xxx.rpm安装 2.修改/etc/vsftpd/vsftpd. ...
- C语言的指针数组与指针数组
一.指针数组与指针数组 1,指针数组 顾名思义,即一个元素全部是指针的数组,其形式与普通数组相似,形式如 *a[N]. 在理解指针数组的使用方式前,我先来说下我个人对数组的理解. 比如一维整形数组(形 ...