3 Star 12 Fork 3

os-lee/easy-paas

加入 Gitee
与超过 1400万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
req_counter.go 2.82 KB
一键复制 编辑 原始数据 按行查看 历史
lee 提交于 2024-07-09 19:23 +08:00 . 使用gobreaker支持服务熔断功能
package flow
import (
"context"
"fmt"
"gitee.com/os-lee/easy-paas/common"
"strconv"
"sync"
"time"
"github.com/go-redis/redis/v8"
)
// ReqCounterHandler 请求计算器
var (
ReqCounterHandler *ReqCounter
)
func init() {
ReqCounterHandler = newReqCounter()
}
type ReqCounter struct {
// key:ServiceName val: *flow.ReqCounterItem
ReqCounterMap sync.Map
}
func newReqCounter() *ReqCounter {
return &ReqCounter{
ReqCounterMap: sync.Map{},
}
}
func (handler *ReqCounter) GetReqCounterItem(serviceName string, redisCli *redis.Client) *ReqCounterItem {
if value, ok := handler.ReqCounterMap.Load(serviceName); ok {
return value.(*ReqCounterItem)
}
reqCounterItem := newReqCounterItem(serviceName, redisCli)
handler.ReqCounterMap.Store(serviceName, reqCounterItem)
return reqCounterItem
}
// ReqCounterItem 结构体用于统计服务的请求
type ReqCounterItem struct {
Client *redis.Client
ServiceName string // 服务名称
}
// newReqCounterItem 初始化ReqCounterItem实例
func newReqCounterItem(serviceName string, redisCli *redis.Client) *ReqCounterItem {
return &ReqCounterItem{
Client: redisCli,
ServiceName: serviceName,
}
}
// RecordRequest 增加当前小时的请求计数
func (src *ReqCounterItem) RecordRequest(ctx context.Context) error {
// TODO 每次请求都写入redis 优化
now := time.Now()
// dateKey = flow_ReqCounter_serviceName_2006-01-02
dateKey := fmt.Sprintf("%s_%s_%s", common.ReqCounterByService, src.ServiceName, now.Format(common.DateFormat))
hour := now.Hour()
_, err := src.Client.HIncrBy(ctx, dateKey, strconv.Itoa(hour), 1).Result()
return err
}
// GetHourlyCountsForDate 获取指定日期每小时的请求计数
func (src *ReqCounterItem) GetHourlyCountsForDate(ctx context.Context, date string) ([]int64, error) {
fullKey := fmt.Sprintf("%s_%s_%s", common.ReqCounterByService, src.ServiceName, date)
hashEntries, err := src.Client.HGetAll(ctx, fullKey).Result()
if err != nil {
return nil, err
}
counts := make([]int64, 24)
for hourStr, countStr := range hashEntries {
hour, err := strconv.Atoi(hourStr)
if err != nil {
continue
}
if hour >= 0 && hour < 24 {
count, err := strconv.ParseInt(countStr, 10, 64)
if err == nil {
counts[hour] = count
}
}
}
return counts, nil
}
// CleanupOldData 清理指定服务的过期统计数据
func (src *ReqCounterItem) CleanupOldData(ctx context.Context, retentionDays int) (int64, error) {
cutoff := time.Now().AddDate(0, 0, -retentionDays).Format(common.DateFormat)
pattern := fmt.Sprintf("%s_%s_%s", common.ReqCounterByService, src.ServiceName, cutoff)
keys, err := src.Client.Keys(ctx, pattern).Result()
if err != nil {
return 0, err
}
if len(keys) > 0 {
deletedCount, err := src.Client.Del(ctx, keys...).Result()
if err != nil {
return 0, err
}
return deletedCount, nil
}
return 0, nil
}
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
Go
1
https://gitee.com/os-lee/easy-paas.git
git@gitee.com:os-lee/easy-paas.git
os-lee
easy-paas
easy-paas
6cf1638f64c0

搜索帮助