go实现限流功能示例

 更新时间:2022年08月16日 14:11:14   作者:pdudo  
这篇文章主要为大家介绍了go实现限流功能示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

引言

在我们日常维护中,经常有爬虫进行爬取网页,少则1秒钟请求数十次,多则达百次,严重消耗了服务器带宽,且影响正常使用者,好在nginx可以配合lua可以完成类似的需求,本次我们将使用go来完成本需求。

需求背景

在我们日常维护中,可能需要这样一种工具,来对某些路由,对特定IP或者用户ID,在特定时间内,限制最大访问次数,这样有效的避免服务器带宽资源的浪费的同时也能接入更多用户请求,本次使用go来做一个类似的。

web demo搭建

我们先来使用SampleHttp编写一个最简单的web服务器,定义路由queryAll,收到后,假设将返回客户端1w字节的数据信息。

在启动web服务器后,我们使用curl进行测试

命令:

curl 127.0.0.1:8083/queryAll

限制访问次数编写

在上述整体需求的情况下,我们需要编写在规定时间限制访问次数的需求,这里我们为了方便,使用ip来作为限制条件,其核心功能分类大致分为:

  • 从未访问过web服务器
  • 访问过web服务器,在规定时间内没有超出限制
  • 访问过web服务器,在在规定时间内超出了限制
  • 访问过web服务器,时间间隔超过了规定时间

如上分类,除了第三种需要限流外,其他则视为正常访问即可。

核心存储,我们可以选择go map,其中keyipvalue为结构体,该结构体包含访问次数创建间戳。

其定义如下

我们来根据如上定义的核心功能来编写程序

从未访问过服务器

我们根据map中是否存在这个key来判断,如

_, ok := visitHashMap[ip]; if !ok {
    // 如果没有该ip的访问次数,则新增记录
}

访问过服务器,在规定时间超过了限制

if time.Now().Unix()-visit.createUnixTime >= interval*60 {
    // 在规定时间超过了限制,需要重新计算阈值
}

超过最大允许访问数

if visitHashMap[ip].number >= maxNum {
    // 超过允许最大访问次数
}

整理为其核心函数如下

功能测试

我们在定义路由地方,将来访者IP传入,就可以根据其返回的bool值来判断是否需要限制访问了。

main函数定义如下:

func main() {
	SampleHttp.Route("get","/queryAll", func(info *SampleHttp.HttpInfo) {
		ip := strings.Split(info.RemoteIP,":")[0]
		if ! limits(ip) {
			info.Write([]byte(fmt.Sprintf("%s 已经被限制访问,在%d分钟内,访问达到%d次",time.Now(),interval,visitHashMap[ip].number)))
			return
		}
		info.Write([]byte(fmt.Sprintf("%s 收到queryAll请求,开始查询,返回1W字节数据信息...,统计信息: 在%d分钟内,访问达到%d次",time.Now(),interval,visitHashMap[ip].number)))
	})
	visitHashMap = make(map[string]visitInfo,0)
	SampleHttp.StartServer("0.0.0.0:8083")
}

我们将开启服务器来测试一下

通过上述执行结果图,可以看到,当1分钟内访问次数超过10次后,就被限制访问了,而从第一次访问时间到目前访问时间间隔达到1分钟以上后,限制就被解除了,可见功能已经完成了。

总结

如上只是实现了这种方法而已,在实际项目中,还需要详细的打磨才行,不然执行效率肯定堪忧,怎么样,限制这个看着好玩吧,快来试试吧,相关代码已经放置到了gitee上。

以上就是go实现限流功能示例的详细内容,更多关于go限流功能的资料请关注脚本之家其它相关文章!

相关文章

  • 执行go vendor第三方包版本冲突问题解决

    执行go vendor第三方包版本冲突问题解决

    这篇文章主要为大家介绍了执行go vendor时,第三方包go版本冲突问题的解决方法,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-07-07
  • 使用Golang获取音视频时长信息的示例代码

    使用Golang获取音视频时长信息的示例代码

    这篇文章主要介绍了如何使用Golang获取音视频时长信息,文中通过代码示例讲解的非常详细,对大家的学习或工作有一定的帮助,需要的朋友可以参考下
    2024-03-03
  • Go语言实现定时器的方法

    Go语言实现定时器的方法

    这篇文章主要介绍了Go语言实现定时器的方法,涉及Go语言时间操作技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-02-02
  • go实现for range迭代时修改值的操作

    go实现for range迭代时修改值的操作

    这篇文章主要介绍了go实现for range迭代时修改值的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-04-04
  • golang利用unsafe操作未导出变量-Pointer使用详解

    golang利用unsafe操作未导出变量-Pointer使用详解

    这篇文章主要给大家介绍了关于golang利用unsafe操作未导出变量-Pointer使用的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考借鉴,下面随着小编来一起学习学习吧
    2018-08-08
  • Go单元测试工具gomonkey的使用

    Go单元测试工具gomonkey的使用

    本文主要介绍了Go单元测试工具gomonkey的使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-06-06
  • golang gorm多条件筛选查询操作

    golang gorm多条件筛选查询操作

    这篇文章主要介绍了golang gorm多条件筛选查询操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-12-12
  • go语言中五种字符串的拼接方式(小结)

    go语言中五种字符串的拼接方式(小结)

    字符串拼接在 golang 里面其实有很多种实现,本文就详细的介绍一下go语言中五种字符串的拼接方式以及性能,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-12-12
  • Go 实现一次性打包各个平台的可执行程序

    Go 实现一次性打包各个平台的可执行程序

    这篇文章主要介绍了Go 实现一次性打包各个平台的可执行程序,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-12-12
  • golang channel管道使用示例解析

    golang channel管道使用示例解析

    这篇文章主要介绍了golang channel管道使用示例解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步早日升职加薪
    2022-04-04

最新评论