首页 > 其他分享 >Go语言实现接口IP限流,黑名单&白名单的实例,都可用!

Go语言实现接口IP限流,黑名单&白名单的实例,都可用!

时间:2023-09-21 09:03:17浏览次数:48  
标签:令牌 IP bucket Go 限流 ip 白名单

Go语言实现接口IP限流,黑名单&白名单的实例,都可用!

原创 学习与分享 Go语言圈 2023-07-18 08:30 发表于广东 收录于合集#学Go语言哪些事儿221个 MySQL大牛 带你全面剖析与系统梳理数据库(mysql等)知识分享,总结数据库技巧和方法,提升你的技术技能。 45篇原创内容 公众号

Goland 激活码&个人账号开通授权,支持版本升级

https://www.mano100.cn/thread-1942-1-1.html

学习与交流:Go语言技术微信群

商务合作加微信:LetsFeng

 

现在就开始你的Go语言学习之旅吧!人生苦短,let’s Go.



在Go语言中,可以使用令牌桶算法(Token Bucket Algorithm)来实现接口IP限流。令牌桶算法基于令牌桶的概念,每个令牌代表一个请求,令牌桶限制了请求的速率。

以下是一个简单的示例代码,演示如何使用令牌桶算法实现接口IP限流

package main

import (
    "fmt"
    "net"
    "sync"
    "time"
)

type RateLimiter struct {
    bucket map[string]*TokenBucket
    mutex  sync.Mutex
}

type TokenBucket struct {
    rate       float64 // 速率,单位:令牌/秒
    capacity   float64 // 令牌桶容量
    tokens     float64 // 当前令牌数量
    lastUpdate time.Time // 上次更新时间
}

func NewRateLimiter() *RateLimiter {
    return &RateLimiter{
        bucket: make(map[string]*TokenBucket),
    }
}

func (rl *RateLimiter) AllowIP(ip string) bool {
    rl.mutex.Lock()
    defer rl.mutex.Unlock()

    bucket, exists := rl.bucket[ip]
    if !exists {
        // 初始化令牌桶
        bucket = &TokenBucket{
            rate:       10, // 每秒生成10个令牌
            capacity:   10, // 令牌桶容量为10个
            tokens:     10, // 初始时令牌桶为满的状态
            lastUpdate: time.Now(),
        }
        rl.bucket[ip] = bucket
    }

    // 计算时间间隔,并根据速率生成令牌
    now := time.Now()
    elapsed := now.Sub(bucket.lastUpdate).Seconds()
    tokensToAdd := elapsed * bucket.rate

    // 更新令牌桶状态
    if tokensToAdd > 0 {
        bucket.tokens = bucket.tokens + tokensToAdd
        if bucket.tokens > bucket.capacity {
            bucket.tokens = bucket.capacity
        }
        bucket.lastUpdate = now
    }

    // 检查令牌数量是否足够
    if bucket.tokens >= 1 {
        bucket.tokens--
        return true
    }

    return false
}

func main() {
    limiter := NewRateLimiter()

    // 模拟并发请求
    for i := 0; i < 20; i++ {
        go func() {
            ip := GetClientIP() // 获取客户端IP
            if limiter.AllowIP(ip) {
                fmt.Printf("Request from IP %s is allowed\n", ip)
            } else {
                fmt.Printf("Request from IP %s is rate limited\n", ip)
            }
        }()
    }

    // 等待所有请求完成
    time.Sleep(2 * time.Second)
}

func GetClientIP() string {
    conn, _ := net.Dial("udp", "8.8.8.8:80")
    defer conn.Close()
    localAddr := conn.LocalAddr().(*net.UDPAddr)
    return localAddr.IP.String()
}

在上述示例中,我们定义了 RateLimiter 结构体和 TokenBucket 结构体,用于表示IP限流的令牌桶和限流器。RateLimiter 使用 sync.Mutex 来保证并发安全。

通过 AllowIP 方法实现IP限流逻辑。该方法首先从 RateLimiter 中获取对应IP的令牌桶,如果令牌桶不存在,则创建一个新的令牌桶。然后根据速率计算时间间隔,并生成相应数量的令牌。最后,检查令牌桶中的令牌数量是否足够,如果足够则返回 true,表示允许访问;否则返回 false,表示限制访问。

在 main 函数中,我们创建了一个 RateLimiter 对象,并模拟并发请求。每个请求获取客户端IP,并通过 AllowIP 方法判断是否允许访问。根据令牌桶的速率和容量,前 10 个请求会被允许,后续的请求会被限流。

注意,以上示例代码仅演示了基本的令牌桶算法实现IP限流的方法。实际应用中,可能需要考虑更复杂的限流策略,如平滑突发限流、动态调整速率等,以满足具体的需求。

黑名单&白名单的实现

在Go语言中,可以使用map数据结构来实现IP黑名单和IP白名单的功能。以下是一个示例代码,演示如何实现IP黑名单和IP白名单:

package main

import (
    "fmt"
    "net"
)

type IPList struct {
    list map[string]bool
}

func NewIPList() *IPList {
    return &IPList{
        list: make(map[string]bool),
    }
}

func (l *IPList) AddIP(ip string) {
    l.list[ip] = true
}

func (l *IPList) RemoveIP(ip string) {
    delete(l.list, ip)
}

func (l *IPList) ContainsIP(ip string) bool {
    _, exists := l.list[ip]
    return exists
}

func main() {
    // 创建IP黑名单
    blacklist := NewIPList()

    // 添加IP到黑名单
    blacklist.AddIP("127.0.0.1")
    blacklist.AddIP("192.168.0.1")

    // 模拟请求,判断IP是否在黑名单中
    ips := []string{"127.0.0.1", "192.168.0.1", "10.0.0.1"}

    for _, ip := range ips {
        if blacklist.ContainsIP(ip) {
            fmt.Printf("IP %s is in the blacklist\n", ip)
        } else {
            fmt.Printf("IP %s is not in the blacklist\n", ip)
        }
    }
}

在上述示例中,我们定义了一个名为 IPList 的结构体,用于表示IP名单列表。该结构体内部使用map来存储IP,并提供了添加IP、移除IP和判断IP是否存在的方法。

在 main 函数中,我们创建了一个 IPList 对象,并添加一些IP到黑名单中。然后,我们模拟请求并判断每个IP是否在黑名单中,根据结果输出相应的消息。

如果需要实现IP白名单,可以类似地创建一个 IPList 结构体,但将逻辑调整为判断IP是否在白名单中。然后使用 AddIP 方法添加白名单IP,使用 ContainsIP 方法判断IP是否在白名单中。

在实际应用中,可以根据需求扩展 IPList 结构体的功能,如支持批量添加IP、从文件中加载名单等。此外,还可以结合网络请求的IP获取方法,获取客户端IP并进行名单判断。

 

文章首发:

 

 

 

 

 

 

更多相关Go语言的技术文章或视频教程,请关注本公众号获取并查看,感谢你的支持与信任!

 

收录于合集 #学Go语言哪些事儿  221个 上一篇TIOBE7月份榜单,要稳坐前十太难了??下一篇Go语言是 如何解决与实现跨域 问题的?   阅读 2030 Go语言圈 ​ 喜欢此内容的人还喜欢   在 Golang 中实现一个简单的Http中间件过程,这样做     Go语言圈 不看的原因   Go语言 的依赖注入如何用?看看吧     Go语言圈 不看的原因   【三万言】今年 Rust 语言出圈了!下一代系统语言 Rust 前沿报告     觉学社 不看的原因   精选留言 写留言
  •   KuMo   上海 回复   golang 的time包下面有个rate 实现了令牌桶    
已无更多数据            

人划线

标签:令牌,IP,bucket,Go,限流,ip,白名单
From: https://www.cnblogs.com/cheyunhua/p/17719030.html

相关文章

  • JavaScript-RegExp 对象
    概述 正则表达式(regularexpression)是一种表达文本模式(即字符串结构)的方法,有点像字符串的模板,常常用来按照“给定模式”匹配文本。比如,正则表达式给出一个Email地址的模式,然后用它来确定一个字符串是否为Email地址。JavaScript的正则表达式体系是参照Perl5建立的。新建正......
  • 01 概述JavaScript
    弱编程语言,世界上最流行的脚本语言前端三件套前端的框架,大部分听不懂,现在混个眼熟,以后再说JavaScript的历史起源:https://www.jianshu.com/p/9af9ceb4831c......
  • typescript_typescript的下载与手动编译
    下载npminstall-gtypescript编译.ts文件为.js文件tsc./typescript/test1.ts上面这个命令会在test1.ts的所属目录中创建一个同名的test1.js文件......
  • 无涯教程-JavaScript - CHISQ.DIST.RT函数
    描述CHISQ.DIST.RT函数返回卡方分布的右尾概率。X2分布与X2测试相关。使用X2检验比较观察值和期望值。通过将观察到的输出与预期的输出进行比较,您可以决定原始假设是否有效。语法CHISQ.DIST.RT(x,deg_freedom)争论Argument描述Required/OptionalXThevalue......
  • 无涯教程-JavaScript - CHISQ.DIST函数
    描述CHISQ.DIST函数返回卡方分布。卡方分布通常用于研究样本中某物百分比的变化,如人们每天看电视的时间所占的比Example。语法CHISQ.DIST(x,deg_freedom,cumulative)争论Argument描述Required/OptionalXThevalueatwhichyouwanttoevaluatethedistribution.R......
  • 应用层-在IP网络中经常使用的应用层协议和服务包括哪些?主要提供哪些功能?对应的端口号
    1.TELNET远程登录主机,端口号TCP232.FTP文件传输协议。客户端首先连接到FTP服务器的TCP21端口,进行用户的认证,认证成功后,当我们要传输文件时,服务器会开一个端口为TCP20来进行传输数据文件。3.TFTP简单文件传输协议,FTP的简化版,端口号TCP694.NFS文件共享协议,让两种不同的文件......
  • 《同构JavaScript应用开发》电子书PDF+源代码
    本书将向你展示如何构建和维护属于自己的同构JavaScript应用。全书分为三部分,第一部分描绘不同种类的同构JavaScript的轮廓,第二部分介绍关键概念,第三部分提供业界同行的解决方案案例。通过阅读本书,你将了解到这种应用架构日益流行的原因,并将其运用于解决关键的业务问题,如页面加载速......
  • IPv6 Internet Protocol version 6协议解析
    简介1883定义了ipv6的协议,不过作废了,在2460又重新做了定义,区别不大,只是有个别字段做了扩充。2373和2374对ipv6的格式做了规定。ipv6是下一代ip地址协议,比ipv4的地址更长,可以表示更多地址段。不过由于ipv6地址太长,不方便记忆,并且ipv4的基础设施太过根深蒂固,所以目前还没有完全普......
  • 代码混淆工具ipaguard:如何使用ipaguard保护和混淆iOS应用程序代码
    ​转载:怎么保护苹果手机移动应用程序iosipa文件中的代码? 目录转载:怎么保护苹果手机移动应用程序iosipa文件中的代码?代码混淆步骤1.选择要混淆保护的ipa文件2.选择要混淆的类名称3.选择要混淆保护的函数,方法4.配置签名证书5.混淆和测试运行   ​编辑在......
  • DataGrip 2023:多功能的数据库管理软件
    DataGrip2023是由JetBrains开发的一款功能强大的数据库管理工具,它旨在提供一个集成的开发环境,方便开发人员管理和操作各种类型的数据库。DataGrip2023支持多种数据库系统,包括MySQL、PostgreSQL、Oracle、SQLServer等,它具有直观的用户界面,使用户能够轻松地连接到数据库服务器,进......