脚本之家,脚本语言编程技术及教程分享平台!
分类导航

Python|VBS|Ruby|Lua|perl|VBA|Golang|PowerShell|Erlang|autoit|Dos|bat|

服务器之家 - 脚本之家 - Golang - go实现限流功能示例

go实现限流功能示例

2022-11-09 11:23pdudo Golang

这篇文章主要为大家介绍了go实现限流功能示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

引言

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

需求背景

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

web demo搭建

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

go实现限流功能示例

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

命令:

curl 127.0.0.1:8083/queryAll

go实现限流功能示例

 

限制访问次数编写

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

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

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

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

其定义如下

go实现限流功能示例

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

从未访问过服务器

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

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

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

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

超过最大允许访问数

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

整理为其核心函数如下

go实现限流功能示例

 

功能测试

我们在定义路由地方,将来访者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")
}

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

go实现限流功能示例

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

总结

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

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

原文链接:https://juejin.cn/post/7130830107237122085

延伸 · 阅读

精彩推荐
  • Golanggolang croncli 定时器命令详解

    golang croncli 定时器命令详解

    定时器是执行任务时的常用功能,配置系统的定时任务太麻烦,所以就想用golang简单实现一个定时器命令,包括定时器命令格式、定时执行命令的相关知识...

    千里之行,始于足下11742022-09-07
  • GolangBeego中ORM操作各类数据库连接方式详细示例

    Beego中ORM操作各类数据库连接方式详细示例

    这篇文章主要为大家介绍了Beego中ORM操作各类数据库连接方式详细示例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步早日升职加薪...

    Jeff的技术栈6312022-09-23
  • Golanggolang API开发过程的中的自动重启方式(基于gin框架)

    golang API开发过程的中的自动重启方式(基于gin框架)

    这篇文章主要介绍了golang API开发过程的中的自动重启方式(基于gin框架),本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的...

    千里之行,始于足下12312021-02-25
  • Golang浅谈golang 中time.After释放的问题

    浅谈golang 中time.After释放的问题

    这篇文章主要介绍了浅谈golang 中time.After释放的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...

    win_lin12002021-06-18
  • Golanggolang 如何获取map所有key的方式

    golang 如何获取map所有key的方式

    这篇文章主要介绍了golang 获取map所有key的方式,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...

    YZF_Kevin16772021-05-28
  • GolangGo语言基础go fmt命令使用示例详解

    Go语言基础go fmt命令使用示例详解

    这篇文章主要为大家介绍了Go语言基础go fmt命令的使用示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步...

    枫少文5022021-12-08
  • GolangGolang中Json的序列化和反序列化的使用

    Golang中Json的序列化和反序列化的使用

    本文主要介绍了Golang中Json的序列化和反序列化的使用,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    itzhuzhu.5862022-09-26
  • GolangGo语言Mock使用基本指南详解

    Go语言Mock使用基本指南详解

    这篇文章主要介绍了Go语言Mock使用基本指南详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面...

    Destiny池鱼3862020-07-20