当前位置:首页 > 科技  > 软件

Go中的流量限制:有效控制流量

来源: 责编: 时间:2023-10-29 21:45:25 395观看
导读一、介绍速率限制是构建可扩展和弹性系统的关键技术。它通过对指定时间范围内允许的请求数量施加限制来帮助控制流量。在Go中实现速率限制可以确保最佳的资源利用,并保护您的应用程序免受过度流量或滥用行为的影响。在

一、介绍

速率限制是构建可扩展和弹性系统的关键技术。它通过对指定时间范围内允许的请求数量施加限制来帮助控制流量。在Go中实现速率限制可以确保最佳的资源利用,并保护您的应用程序免受过度流量或滥用行为的影响。在这篇博文中,我们将探索Go中的速率限制技术,并提供实用的代码示例来帮助您有效地实现它们。9C928资讯网——每日最新资讯28at.com

9C928资讯网——每日最新资讯28at.com

二、理解速率限制

速率限制包括定义一组规则,这些规则决定客户端在给定的时间窗口内可以发出多少请求。确保系统能够处理负载,防止滥用或拒绝服务攻击。限制速率的两种常见方法是:9C928资讯网——每日最新资讯28at.com

固定窗口速率限制:在这种方法中,速率限制在固定的时间窗口内强制执行。例如,如果速率限制设置为每分钟100个请求,系统将在任何给定的60秒窗口中允许最多100个请求。超过此限制的请求将被拒绝或延迟到下一个时间窗口。9C928资讯网——每日最新资讯28at.com

令牌桶速率限制:令牌桶速率限制是基于从一个桶中消耗令牌的概念。桶最初由固定数量的令牌填充,每个令牌代表一个请求。当客户端想要发出请求时,它必须从桶中获取令牌。如果桶为空,客户端必须等待,直到令牌可用。9C928资讯网——每日最新资讯28at.com

三、在GO中实现速率限制

Go提供了一个名为golang.org/x/time/rate的内置包,提供速率限制功能。让我们探讨一下如何同时使用固定窗口和令牌桶方法来实现速率限制。9C928资讯网——每日最新资讯28at.com

1.固定窗口

func fixedWindowRateLimiting() { limiter := rate.NewLimiter(rate.Limit(100), 1) // 允许每秒100次 for i := 0; i < 200; i++ {  if !limiter.Allow() {   fmt.Println("Rate limit exceeded. Request rejected.")   continue  }  go process() }}// 处理请求func process() { fmt.Println("Request processed successfully.") time.Sleep(time.Millisecond) // 模拟请求处理时间}

在上面的代码片段中,我们创建了一个限制使用率。速率限制为每秒100个请求的NewLimiter。对每个请求调用limiter.Allow()方法,如果允许请求,则返回true;如果超过速率限制,则返回false。如果超过速率限制,请求将被拒绝。9C928资讯网——每日最新资讯28at.com

对应的输出为,清楚的看到部分请求已经被拒绝了:9C928资讯网——每日最新资讯28at.com

Request processed successfully.Rate limit exceeded. Request rejected.Rate limit exceeded. Request rejected.Rate limit exceeded. Request rejected.Rate limit exceeded. Request rejected.Rate limit exceeded. Request rejected.Rate limit exceeded. Request rejected.Rate limit exceeded. Request rejected....

2.令牌桶

func tokenBucketRateLimiting() { limiter := rate.NewLimiter(rate.Limit(10), 5) ctx, _ := context.WithTimeout(context.TODO(), time.Millisecond) for i := 0; i < 200; i++ {  if err := limiter.Wait(ctx); err != nil {   fmt.Println("Rate limit exceeded. Request rejected.")   continue  }  go process() }}// 处理请求func process() { fmt.Println("Request processed successfully.") time.Sleep(time.Millisecond) // 模拟请求处理时间}

在上述代码中,我们使用 rate.NewLimiter 创建了一个限制器,其速率限制为每秒 10 个请求,突发 5 个请求。每个请求都会调用 limiter.Wait() 方法,该方法会阻塞直到有令牌可用。如果水桶是空的,没有可用的令牌,请求就会被拒绝。9C928资讯网——每日最新资讯28at.com

对应的输出为,清楚的看到部分请求已经被拒绝了:9C928资讯网——每日最新资讯28at.com

Request processed successfully.Rate limit exceeded. Request rejected.Rate limit exceeded. Request rejected.Request processed successfully.Rate limit exceeded. Request rejected.

四、动态速率限制

动态速率限制是指根据客户端行为、系统负载或业务规则等动态因素调整速率限制。这种技术允许您实时调整速率限制,以优化资源利用率并提供更好的用户体验。让我们看看 Go 中动态速率限制的示例:9C928资讯网——每日最新资讯28at.com

func dynamicRateLimiting() { limiter := rate.NewLimiter(rate.Limit(10), 1) // 允许每秒100次 // Dynamic rate adjustment go func() {  time.Sleep(time.Second * 10) // 每10秒调整 limiter  fmt.Println("---adjust limiter---")  limiter.SetLimit(rate.Limit(200)) // 将 limiter 提升到每秒 200 }() for i := 0; i < 3000; i++ {  if !limiter.Allow() {   fmt.Println("Rate limit exceeded. Request rejected.")   time.Sleep(time.Millisecond * 100)   continue  }  process() }}// 处理请求func process() { fmt.Println("Request processed successfully.") time.Sleep(time.Millisecond * 10) // 模拟请求处理时间}

在上面的代码片段中,我们创建了一个限制器,初始速率限制为每秒 10 个请求。然后,我们启动一个 goroutine,在 10秒钟后将速率限制调整为每秒 200 个请求。这样,我们就能根据不断变化的情况动态调整速率限制。9C928资讯网——每日最新资讯28at.com

对应的输出为,这里我们可以看到中途的时候,某些请求已经被拒绝掉了,后来我们通过动态调整,后续的请求都可以正常通过了:9C928资讯网——每日最新资讯28at.com

...Request processed successfully.Rate limit exceeded. Request rejected.Request processed successfully.---adjust limiter---Rate limit exceeded. Request rejected.Request processed successfully.Request processed successfully.Request processed successfully.Request processed successfully.Request processed successfully....

五、自适应速率限制

自适应速率限制可根据之前请求的响应时间或错误率动态调整速率限制。它允许系统自动适应不同的流量条件,确保最佳性能和资源利用率。让我们看看 Go 中自适应速率限制的示例:9C928资讯网——每日最新资讯28at.com

func adaptiveRateLimiting() { limiter := rate.NewLimiter(rate.Limit(10), 1) // 允许每秒10次 // 自适应调整 go func() {  for {   time.Sleep(time.Second * 10)   responseTime := measureResponseTime() // 测量之前请求的响应时间   if responseTime > 500*time.Millisecond {    fmt.Println("---adjust limiter 50---")    limiter.SetLimit(rate.Limit(50))   } else {    fmt.Println("---adjust limiter 100---")    limiter.SetLimit(rate.Limit(100))   }  } }() for i := 0; i < 3000; i++ {  if !limiter.Allow() {   fmt.Println("Rate limit exceeded. Request rejected.")   time.Sleep(time.Millisecond * 100)   continue  }  process() }}// 测量以前请求的响应时间// 执行自己的逻辑来测量响应时间func measureResponseTime() time.Duration { return time.Millisecond * 100}// 处理请求func process() { fmt.Println("Request processed successfully.") time.Sleep(time.Millisecond * 10) // 模拟请求处理时间}

在上述代码片段中,我们使用 measureResponseTime 函数模拟测量之前请求的响应时间。根据测量到的响应时间,我们通过使用 limiter.SetLimit 设置不同的值来动态调整速率限制。这样,系统就能根据观察到的响应时间调整其速率限制策略。9C928资讯网——每日最新资讯28at.com

对应的输出为:9C928资讯网——每日最新资讯28at.com

Request processed successfully.Rate limit exceeded. Request rejected.Request processed successfully.Rate limit exceeded. Request rejected.---adjust limiter 100---Request processed successfully.Request processed successfully.Request processed successfully.Request processed successfully.Request processed successfully.

总结

速率限制是维护 Go 应用程序稳定性和安全性的基本技术。通过有效控制传入请求的流量,您可以防止资源耗尽并确保资源的公平分配。在这篇博文中,我们探讨了固定窗口和令牌桶速率限制的概念,并提供了代码片段,演示如何使用 golang.org/x/time/rate 包在 Go 中实现它们。将速率限制纳入您的应用程序,以构建能够高效处理不同流量水平的弹性系统。9C928资讯网——每日最新资讯28at.com

当然可以使用第三方库来实现,比如说:go.uber.org/ratelimit。9C928资讯网——每日最新资讯28at.com

本文链接:http://www.28at.com/showinfo-26-15601-0.htmlGo中的流量限制:有效控制流量

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com

上一篇: Go 中的类型断言与静态转换

下一篇: 负载均衡器的八大使用场景介绍

标签:
  • 热门焦点
  • Find N3入网:最高支持16+1TB

    OPPO将于近期登场的Find N3折叠屏目前已经正式入网,型号为PHN110。本次Find N3在外观方面相比前两代有很大的变化,不再是小号的横向折叠屏,而是跟别的厂商一样采用了较为常见的
  • 鸿蒙OS 4.0公测机型公布:甚至连nova6都支持

    华为全新的HarmonyOS 4.0操作系统将于今天下午正式登场,官方在发布会之前也已经正式给出了可升级的机型产品,这意味着这些机型会率先支持升级享用。这次的HarmonyOS 4.0支持
  • 红魔电竞平板评测:大屏幕硬实力

    前言:三年的疫情因为要上网课的原因激活了平板市场,如今网课的时代已经过去,大家的生活都恢复到了正轨,这也就意味着,真正考验平板电脑生存的环境来了。也就是面对着这种残酷的
  • 《英雄联盟》夏季赛总决赛今日开打!JDG对阵LNG首发名单来了 Knight:准备三连冠

    8月5日消息,今日17:00,《英雄联盟》2023LPL夏季赛总决赛将正式开打,由JDG对阵LNG。对两支队伍来说,这场比赛不仅要争夺夏季赛冠军,更要决定谁才是LPL赛区一
  • 把LangChain跑起来的三个方法

    使用LangChain开发LLM应用时,需要机器进行GLM部署,好多同学第一步就被劝退了,那么如何绕过这个步骤先学习LLM模型的应用,对Langchain进行快速上手?本片讲解3个把LangChain跑起来
  • 一年经验在二线城市面试后端的经验分享

    忠告这篇文章只适合2年内工作经验、甚至没有工作经验的朋友阅读。如果你是2年以上工作经验,请果断划走,对你没啥帮助~主人公这篇文章内容来自 「升职加薪」星球星友 的投稿,坐
  • JVM优化:实战OutOfMemoryError异常

    一、Java堆溢出堆内存中主要存放对象、数组等,只要不断地创建这些对象,并且保证 GC Roots 到对象之间有可达路径来避免垃 圾收集回收机制清除这些对象,当这些对象所占空间超过
  • 破圈是B站头上的紧箍咒

    来源 | 光子星球撰文 | 吴坤谚编辑 | 吴先之每年的暑期档都少不了瞄准追剧女孩们的古偶剧集,2021年有优酷的《山河令》,2022年有爱奇艺的《苍兰诀》,今年却轮到小破站抓住了追
  • 华为Mate60系列模具曝光:采用硕大圆形后置相机模组+拼接配色方案

    据此前多方爆料,今年华为将开始恢复一年双旗舰战略,除上半年推出的P60系列外,往年下半年的Mate系列也将迎来更新,有望在9-10月份带来全新的华为Mate60
Top