mirror of
https://github.com/DullJZ/s3-balance.git
synced 2026-09-08 01:16:37 +08:00
Count operation type A & B
This commit is contained in:
@@ -16,14 +16,27 @@ import (
|
||||
"github.com/aws/aws-sdk-go-v2/service/s3"
|
||||
)
|
||||
|
||||
// OperationCategory 表示后端操作分类
|
||||
type OperationCategory string
|
||||
|
||||
const (
|
||||
// OperationTypeA 表示写入类操作
|
||||
OperationTypeA OperationCategory = "A"
|
||||
// OperationTypeB 表示读取类操作
|
||||
OperationTypeB OperationCategory = "B"
|
||||
)
|
||||
|
||||
// BucketInfo 存储桶信息
|
||||
type BucketInfo struct {
|
||||
Config config.BucketConfig
|
||||
Client *s3.Client
|
||||
UsedSize int64 // 已使用容量(字节)
|
||||
Available bool // 是否可用(由health监控更新)
|
||||
LastChecked time.Time // 最后检查时间(由health监控更新)
|
||||
mu sync.RWMutex
|
||||
Config config.BucketConfig
|
||||
Client *s3.Client
|
||||
UsedSize int64 // 已使用容量(字节)
|
||||
Available bool // 是否可用(由health监控更新)
|
||||
LastChecked time.Time // 最后检查时间(由health监控更新)
|
||||
mu sync.RWMutex
|
||||
operationCountA int64
|
||||
operationCountB int64
|
||||
operationLimitReached bool
|
||||
}
|
||||
|
||||
// Manager 存储桶管理器
|
||||
@@ -267,6 +280,50 @@ func (b *BucketInfo) UpdateUsedSize(delta int64) {
|
||||
b.UsedSize += delta
|
||||
}
|
||||
|
||||
// RecordOperation 记录一次后端操作并根据配置判断是否需要禁用存储桶
|
||||
func (b *BucketInfo) RecordOperation(category OperationCategory) bool {
|
||||
if b == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
b.mu.Lock()
|
||||
defer b.mu.Unlock()
|
||||
|
||||
if b.Config.Virtual {
|
||||
return false
|
||||
}
|
||||
|
||||
var (
|
||||
limit int64
|
||||
count *int64
|
||||
)
|
||||
|
||||
switch category {
|
||||
case OperationTypeA:
|
||||
b.operationCountA++
|
||||
count = &b.operationCountA
|
||||
limit = int64(b.Config.OperationLimits.TypeA)
|
||||
case OperationTypeB:
|
||||
b.operationCountB++
|
||||
count = &b.operationCountB
|
||||
limit = int64(b.Config.OperationLimits.TypeB)
|
||||
default:
|
||||
return false
|
||||
}
|
||||
|
||||
if limit <= 0 || count == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
if !b.operationLimitReached && *count >= limit {
|
||||
b.Available = false
|
||||
b.operationLimitReached = true
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// IsVirtual 检查是否为虚拟存储桶
|
||||
func (b *BucketInfo) IsVirtual() bool {
|
||||
b.mu.RLock()
|
||||
|
||||
+13
-11
@@ -7,9 +7,9 @@ import (
|
||||
|
||||
// MetricsReporter 实现 health.HealthReporter 和 health.StatsReporter 接口
|
||||
type MetricsReporter struct {
|
||||
metrics *metrics.Metrics
|
||||
buckets map[string]*BucketInfo
|
||||
manager *Manager
|
||||
metrics *metrics.Metrics
|
||||
buckets map[string]*BucketInfo
|
||||
manager *Manager
|
||||
}
|
||||
|
||||
// NewMetricsReporter 创建指标报告器
|
||||
@@ -25,18 +25,20 @@ func (r *MetricsReporter) ReportHealth(targetID string, status health.Status) {
|
||||
if r.metrics == nil {
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
// 更新存储桶可用性状态
|
||||
r.manager.mu.RLock()
|
||||
bucket, exists := r.manager.buckets[targetID]
|
||||
r.manager.mu.RUnlock()
|
||||
|
||||
|
||||
if exists {
|
||||
bucket.mu.Lock()
|
||||
bucket.Available = status.Healthy
|
||||
if !bucket.operationLimitReached {
|
||||
bucket.Available = status.Healthy
|
||||
}
|
||||
bucket.LastChecked = status.LastChecked
|
||||
bucket.mu.Unlock()
|
||||
|
||||
|
||||
// 更新 Prometheus 指标
|
||||
r.metrics.SetBucketHealthy(targetID, bucket.Config.Endpoint, status.Healthy)
|
||||
}
|
||||
@@ -47,18 +49,18 @@ func (r *MetricsReporter) ReportStats(stats *health.Stats) {
|
||||
if r.metrics == nil {
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
// 更新存储桶使用统计
|
||||
r.manager.mu.RLock()
|
||||
bucket, exists := r.manager.buckets[stats.TargetID]
|
||||
r.manager.mu.RUnlock()
|
||||
|
||||
|
||||
if exists {
|
||||
bucket.mu.Lock()
|
||||
bucket.UsedSize = stats.UsedSize
|
||||
bucket.mu.Unlock()
|
||||
|
||||
|
||||
// 更新 Prometheus 指标
|
||||
r.metrics.SetBucketUsage(stats.TargetID, stats.UsedSize, bucket.Config.MaxSizeBytes)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user