ZBLOG

请用golang 实现一个限制每天http请求次数的 方法。并封装

这里提供一个使用 golang 实现限制每天 http 请求次数的方法,并进行封装的示例代码:

  1. package main
  2. import (
  3. "fmt"
  4. "net/http"
  5. "sync"
  6. "time"
  7. )
  8. // 定义 HTTP 请求处理函数
  9. func handler(w http.ResponseWriter, r *http.Request) {
  10. fmt.Fprintln(w, "Hello, world!")
  11. }
  12. // 封装每天最大访问次数控制方法
  13. func LimitDailyRequest(maxCount int, fn http.HandlerFunc) http.HandlerFunc {
  14. // 定义一个读写并发安全的映射对象
  15. var m sync.Map
  16. // 返回一个新的 HTTP 请求处理函数,用于在原有请求处理基础上增加每天最大访问次数限制功能
  17. return func(w http.ResponseWriter, r *http.Request) {
  18. // 获取当前时间和当天日期字符串(例如20220101)
  19. nowTime := time.Now()
  20. todayStr := nowTime.Truncate(24*time.Hour).Format("20060102")
  21. // 构建已处理请求数量、上一次请求时间和访问计数器的 key
  22. countKey := fmt.Sprintf("%s:%s", "requests", todayStr)
  23. timeKey := fmt.Sprintf("%s:%s", "last_request_time", todayStr)
  24. counterKey := fmt.Sprintf("%s:%s", "counter", todayStr)
  25. // 使用读写锁来保证并发安全性
  26. var mu sync.RWMutex
  27. mu.RLock()
  28. defer mu.RUnlock()
  29. // 从映射中获取已处理请求数量、上一次请求时间和访问计数器,并判断是否超出限制
  30. currentCount, found := m.LoadOrStore(countKey, 0) // 如果不存在,则设置为0;否则返回已有值
  31. lastRequestTime, found := m.LoadOrStore(timeKey, nowTime.Add(-time.Second)) // 如果不存在,则设置为当前时间的前一秒;否则返回已有值
  32. counter, found := m.LoadOrStore(counterKey, 0)
  33. // 判断是否超出限制
  34. if currentCount.(int) >= maxCount {
  35. http.Error(w, "Exceeding the maximum number of requests per day", http.StatusTooManyRequests)
  36. return // 超出限制直接返回响应,不再执行原有请求处理函数
  37. } else {
  38. // 增加访问计数器,并更新本次请求时间和已处理请求数量到映射中
  39. mu.Lock()
  40. defer mu.Unlock()
  41. m.Store(countKey, currentCount.(int)+1)
  42. m.Store(timeKey, nowTime)
  43. m.Store(counterKey, counter.(int)+1)
  44. fn(w, r) // 执行原有请求处理函数
  45. // 打印当前已处理请求数量和剩余请求数量(可选)
  46. fmt.Printf("今日已处理 %d 次,请求数量剩余 %d\n", currentCount.(int)+1, maxCount-currentCount.(int)-1)
  47. }
  48. }
  49. }
  50. func main() {
  51. // 创建一个 HTTP 服务器并注册 HTTP 请求处理函数(使用 LimitDailyRequest 封装后的新函数)
  52. http.HandleFunc("/", LimitDailyRequest(20, handler))
  53. // 启动 HTTP 服务器并监听在本地 8080 端口上
  54. http.ListenAndServe(":8080", nil)
  55. }

使用 LimitDailyRequest 封装 HTTP 请求处理函数后,每个客户端每天最多只能访问该接口指定的次数。如果超出限制,则会直接返回响应,并不再执行原有请求处理函数。同时,该封装方法是线程安全的,可以保证在高并发情况下仍能正确地统计和限制请求次数。

本站部分文章来源于网络,版权归原作者所有,如有侵权请联系站长删除。
转载请注明出处:https://golang.0voice.com/?id=3131

分享:
扫描分享到社交APP
上一篇
下一篇
发表列表
游客 游客
此处应有掌声~
评论列表

还没有评论,快来说点什么吧~

联系我们

在线咨询: 点击这里给我发消息

微信号:3007537140

上班时间: 10:30-22:30

关注我们
x

注册

已经有帐号?