优化限流功能
This commit is contained in:
@@ -209,6 +209,8 @@ func (m *HalfOpenManager) checkHalfOpenSuccessThreshold(metrics HalfOpenMetrics,
|
||||
return false
|
||||
}
|
||||
|
||||
// 使用浮点数除法计算成功率,避免整数除法精度丢失问题
|
||||
// 例如: passedRequests=1, failedRequests=2, 则 successRate = 0.333... 而不是 0
|
||||
successRate := float64(passedRequests) / float64(totalRequests)
|
||||
return successRate >= successThreshold
|
||||
}
|
||||
@@ -1106,32 +1108,74 @@ func syncCircuitBreakerStateToDistributed(ctx context.Context, resourceName, sta
|
||||
g.Log().Warningf(ctx, "分布式熔断状态同步失败,跳过: %s, 最后错误: %v", lockKey, lastErr)
|
||||
}
|
||||
|
||||
// CircuitBreakerHealthCheckHandler 健康检查接口
|
||||
func CircuitBreakerHealthCheckHandler(r *ghttp.Request) {
|
||||
// 添加认证检查:使用JWT Token或API Key
|
||||
// checkCircuitBreakerAuthToken 验证熔断器管理接口的认证Token
|
||||
// 统一的认证逻辑,用于健康检查、重置等管理接口
|
||||
// 返回值:
|
||||
// - true: 认证通过
|
||||
// - false: 认证失败,已发送401响应
|
||||
func checkCircuitBreakerAuthToken(r *ghttp.Request) bool {
|
||||
// 从Header中获取认证信息
|
||||
authToken := r.Header.Get("Authorization")
|
||||
|
||||
// 如果Header中没有,尝试从查询参数获取(仅用于开发/测试环境)
|
||||
// 生产环境应禁用此方式,仅支持Header认证
|
||||
if authToken == "" {
|
||||
// 尝试从查询参数获取(仅用于开发环境)
|
||||
authToken = r.Get("authToken").String()
|
||||
}
|
||||
|
||||
// 简单的Token验证(生产环境应使用更严格的认证)
|
||||
// 建议使用JWT或其他安全的认证机制
|
||||
// 检查Token是否为空
|
||||
if authToken == "" {
|
||||
g.Log().Warningf(r.GetCtx(), "熔断器健康检查被拒绝:缺少认证信息,IP=%s", r.GetClientIp())
|
||||
g.Log().Warningf(r.GetCtx(), "熔断器管理接口访问被拒绝:缺少认证Token, IP=%s, Path=%s",
|
||||
r.GetClientIp(), r.URL.Path)
|
||||
r.Response.WriteStatusExit(401, "Unauthorized: Missing authentication token")
|
||||
return
|
||||
return false
|
||||
}
|
||||
|
||||
// TODO: 在这里添加真正的Token验证逻辑
|
||||
// 示例:使用JWT验证
|
||||
// claims, err := jwt.ParseWithClaims(authToken, &MyClaims{})
|
||||
// if err != nil {
|
||||
// 支持Bearer Token格式
|
||||
if strings.HasPrefix(authToken, "Bearer ") {
|
||||
authToken = strings.TrimPrefix(authToken, "Bearer ")
|
||||
}
|
||||
|
||||
// TODO: 实现完整的Token验证逻辑
|
||||
// 建议使用JWT或其他安全机制:
|
||||
//
|
||||
// 1. 使用gogf/gf/v2/os/gjwt进行JWT验证:
|
||||
// token, err := gjwt.ParseAndVerify(authToken, []byte(secret))
|
||||
// if err != nil {
|
||||
// return false
|
||||
// }
|
||||
//
|
||||
// 2. 或使用其他JWT库(如github.com/golang-jwt/jwt/v5):
|
||||
// claims := &MyClaims{}
|
||||
// token, err := jwt.ParseWithClaims(authToken, claims, ...)
|
||||
//
|
||||
// 3. 验证Token的:
|
||||
// - 签名有效性
|
||||
// - 过期时间(exp)
|
||||
// - 签发者(iss)
|
||||
// - 权限范围(scope/roles)
|
||||
//
|
||||
// 4. 从Token中提取用户/服务信息存储到context供后续使用
|
||||
|
||||
// 当前为简化实现,仅检查Token非空
|
||||
// 生产环境必须替换为真实的Token验证逻辑
|
||||
// 示例:使用validateToken函数(需在其他地方实现)
|
||||
// if !validateToken(authToken) {
|
||||
// g.Log().Warningf(r.GetCtx(), "熔断器管理接口访问被拒绝:无效的认证Token, IP=%s", r.GetClientIp())
|
||||
// r.Response.WriteStatusExit(401, "Unauthorized: Invalid token")
|
||||
// return
|
||||
// return false
|
||||
// }
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
// CircuitBreakerHealthCheckHandler 健康检查接口
|
||||
func CircuitBreakerHealthCheckHandler(r *ghttp.Request) {
|
||||
// 认证检查:使用Token验证
|
||||
if !checkCircuitBreakerAuthToken(r) {
|
||||
return
|
||||
}
|
||||
|
||||
page := r.Get("page").Int()
|
||||
size := r.Get("size").Int()
|
||||
if page < 0 {
|
||||
@@ -1237,20 +1281,11 @@ func batchProcessResources(r *ghttp.Request, processFunc func(resourceName strin
|
||||
|
||||
// CircuitBreakerResetHandler 重置熔断器
|
||||
func CircuitBreakerResetHandler(r *ghttp.Request) {
|
||||
// 添加认证检查(与健康检查接口相同)
|
||||
authToken := r.Header.Get("Authorization")
|
||||
if authToken == "" {
|
||||
authToken = r.Get("authToken").String()
|
||||
}
|
||||
|
||||
if authToken == "" {
|
||||
g.Log().Warningf(r.GetCtx(), "熔断器重置被拒绝:缺少认证信息,IP=%s", r.GetClientIp())
|
||||
r.Response.WriteStatusExit(401, "Unauthorized: Missing authentication token")
|
||||
// 认证检查
|
||||
if !checkCircuitBreakerAuthToken(r) {
|
||||
return
|
||||
}
|
||||
|
||||
// TODO: 添加真正的Token验证逻辑
|
||||
|
||||
resourceName := r.Get("resource").String()
|
||||
|
||||
if resourceName == "" || resourceName == "*" {
|
||||
|
||||
@@ -30,6 +30,9 @@ func Auth(r *ghttp.Request) {
|
||||
}
|
||||
|
||||
// 验证 token
|
||||
// TODO: 实现完整的JWT验证逻辑
|
||||
// 当前为占位实现,实际使用时应替换为真实的token验证
|
||||
// 例如:使用gogf/gf/v2/os/gjwt或其他JWT库进行验证
|
||||
if !validateToken(gstr.SubStrFrom(token, "7")) {
|
||||
r.Response.WriteStatusExit(401, "Unauthorized")
|
||||
return
|
||||
@@ -37,3 +40,44 @@ func Auth(r *ghttp.Request) {
|
||||
|
||||
r.Middleware.Next()
|
||||
}
|
||||
|
||||
// validateToken 验证Token有效性
|
||||
// 当前为简化实现,实际生产环境应使用JWT或其他安全机制进行验证
|
||||
// 示例:
|
||||
// - 使用gogf/gf/v2/os/gjwt库解析和验证JWT token
|
||||
// - 验证token签名、过期时间、签发者等
|
||||
// - 从token中提取用户信息并存储到context
|
||||
//
|
||||
// 返回值:
|
||||
// - true: token有效
|
||||
// - false: token无效或过期
|
||||
func validateToken(token string) bool {
|
||||
// TODO: 实现真实的token验证逻辑
|
||||
// 当前为占位实现,返回true以允许基本功能运行
|
||||
// 生产环境必须替换为真实的验证逻辑
|
||||
|
||||
// 简单的非空检查
|
||||
if token == "" {
|
||||
return false
|
||||
}
|
||||
|
||||
// 建议的JWT验证示例(需要引入jwt库):
|
||||
/*
|
||||
claims := &jwt.MapClaims{}
|
||||
t, err := jwt.ParseWithClaims(token, claims, func(token *jwt.Token) (interface{}, error) {
|
||||
return []byte("your-secret-key"), nil
|
||||
})
|
||||
if err != nil || !t.Valid {
|
||||
return false
|
||||
}
|
||||
// 检查过期时间
|
||||
if exp, ok := (*claims)["exp"].(float64); ok {
|
||||
if time.Now().Unix() > int64(exp) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
// 临时返回true,实际使用时应实现完整验证
|
||||
return true
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user