- 前景
- 开发环境
- Go 基础
- 流程控制
- 函数
- 方法
- 面向对象
- 网络编程
- 并发编程
- 数据操作
- 常用标准库
- beego 框架
- gin 框架
- 微服务
- 插件库
- 项目
- 开源仓库
- go 学习线路图
- 音频和音乐
- 身份验证和 OAuth
- 机器人相关
- 标准 CLI
- 构建用户界面库
- 配置
- 持续集成
- CSS 预处理器
- 数据结构
- 数据库
- 数据库驱动
- 日期和时间
- 分布式系统
- 电子邮件
- 嵌入式脚本语言
- 错误处理
- 文件
- 金融
- Forms
- 功能性
- 游戏开发
- 生成与泛型
- 地理位置
- 编译器
- Goroutines
- 图形界面
- 图片
- 物联网
- 工作计划
- JSON格式
- Logging
- 机器学习
- 实现消息传递
- 微软办公软件
- 依赖注入
- 项目布局
- Strings
- 其他
- 自然语言处理
- 网络
- HTTP 客户端
- OpenGL
- ORM
- 包管理
- 性能
- 查询语言
- 资源嵌入
- 科学与数据分析
- 安全
- 序列化
- 服务器应用
- 流处理
- 模板引擎
- 测试
- 文字处理
- 第三方 API
- 实用工具
- UUID
- 验证方式
- 版本控制
- 视频
- Web 框架
- 中间件
- 路由器
- 视窗
- XML 格式
- 代码分析
- 编辑器插件
- 硬件
- go 生成工具
- go 工具
- DevOps 工具
- 其他
文章来源于网络收集而来,版权归原创者所有,如有侵权请及时联系!
流量控
利用go
channel
实现限流量控制,原理:设置一个缓冲通道,设置访问中间键,当用户请求连接时判断channel里面长度是不是大于设定的缓冲值,如果没有就存入一个值进入channel,如果大于缓冲值,channel自动阻塞。当用户请求结束的时候,取出channel里面的值。
如果想限制用户HTTP请求进行速率限制可以参考 https://github.com/didip/tollbooth 这个中间键
目录:
-videos
--ce.html
-limiter.go
-main.go
main.go文件代码:
package main
import (
"log"
"net/http"
"text/template"
"time"
"github.com/julienschmidt/httprouter"
)
type middleWareHandler struct {
r *httprouter.Router
l *ConnLimiter
}
//NewMiddleWareHandler ...
func NewMiddleWareHandler(r *httprouter.Router, cc int) http.Handler {
m := middleWareHandler{}
m.r = r
m.l = NewConnLimiter(cc)
return m
}
func (m middleWareHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
if !m.l.GetConn() {
defer func() { recover() }()
log.Panicln("Too many requests")
return
}
m.r.ServeHTTP(w, r)
defer m.l.ReleaseConn()
}
//RegisterHandlers ...
func RegisterHandlers() *httprouter.Router {
router := httprouter.New()
router.GET("/ce", ce)
return router
}
func ce(w http.ResponseWriter, r *http.Request, p httprouter.Params) {
//为了演示效果这块设置了等待
time.Sleep(time.Second * 100)
t, _ := template.ParseFiles("./videos/ce.html")
t.Execute(w, nil)
}
func main() {
r := RegisterHandlers()
//里面的参数2为设置的最大流量
mh := NewMiddleWareHandler(r, 2)
http.ListenAndServe(":9000", mh)
}
limiter.go文件代码
package main
import (
"log"
)
//ConnLimiter 定义一个结构体
type ConnLimiter struct {
concurrentConn int
bucket chan int
}
//NewConnLimiter ...
func NewConnLimiter(cc int) *ConnLimiter {
return &ConnLimiter{
concurrentConn: cc,
bucket: make(chan int, cc),
}
}
//GetConn 获取通道里面的值
func (cl *ConnLimiter) GetConn() bool {
if len(cl.bucket) >= cl.concurrentConn {
log.Printf("Reached the rate limitation.")
return false
}
cl.bucket <- 1
return true
}
//ReleaseConn 释放通道里面的值
func (cl *ConnLimiter) ReleaseConn() {
c := <-cl.bucket
log.Printf("New connction coming: %d", c)
}
videos/ce.html文件代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
www.topgoer.com是个不错的go语言中文文档
</body>
</html>
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论