Skip to content

Commit

Permalink
Merge pull request #184 from Maple-pro/dev_rate_limit
Browse files Browse the repository at this point in the history
feat(message & publish): add rate limiter
  • Loading branch information
liaosunny123 authored Aug 26, 2023
2 parents 59335cb + 3edc7d6 commit f0d2c9b
Show file tree
Hide file tree
Showing 6 changed files with 206 additions and 72 deletions.
46 changes: 25 additions & 21 deletions src/constant/strings/err.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ const (
UnableToDeleteCommentErrorCode = 50008
UnableToDeleteCommentError = "无法删除视频评论"
UnableToAddMessageErrorCode = 50009
UnableToAddMessageRrror = "发送消息出错"
UnableToAddMessageError = "发送消息出错"
UnableToQueryMessageErrorCode = 50010
UnableToQueryMessageError = "查消息出错"
PublishServiceInnerErrorCode = 50011
Expand All @@ -48,30 +48,34 @@ const (
StringToIntError = "字符串转数字失败"
RelationServiceIntErrorCode = 50019
RelationServiceIntError = "关系服务出现内部错误"
FavorivateServiceErrorCode = 50020
FavorivateServiceError = "点赞服务内部出错"
FavoriteServiceErrorCode = 50020
FavoriteServiceError = "点赞服务内部出错"
UserServiceInnerErrorCode = 50021
UserServiceInnerError = "登录服务出现内部错误,请稍后重试!"
)

// Expected Error
const (
AuthUserExistedCode = 10001
AuthUserExisted = "用户已存在,请更换用户名或尝试登录!"
UserNotExistedCode = 10002
UserNotExisted = "用户不存在,请先注册或检查你的用户名是否正确!"
AuthUserLoginFailedCode = 10003
AuthUserLoginFailed = "用户信息错误,请检查账号密码是否正确"
AuthUserNeededCode = 10004
AuthUserNeeded = "用户无权限操作,请登陆后重试!"
ActionCommentTypeInvalidCode = 10005
ActionCommentTypeInvalid = "不合法的评论类型"
ActionCommentLimitedCode = 10006
ActionCommentLimited = "评论频繁,请稍后再试!"
InvalidContentTypeCode = 10007
InvalidContentType = "不合法的内容类型"
FavorivateServiceDuplicateCode = 10008
FavorivateServiceDuplicateError = "不能重复点赞"
FavorivateServiceCancelCode = 10009
FavorivateServiceCancelError = "没有点赞,不能取消点赞"
AuthUserExistedCode = 10001
AuthUserExisted = "用户已存在,请更换用户名或尝试登录!"
UserNotExistedCode = 10002
UserNotExisted = "用户不存在,请先注册或检查你的用户名是否正确!"
AuthUserLoginFailedCode = 10003
AuthUserLoginFailed = "用户信息错误,请检查账号密码是否正确"
AuthUserNeededCode = 10004
AuthUserNeeded = "用户无权限操作,请登陆后重试!"
ActionCommentTypeInvalidCode = 10005
ActionCommentTypeInvalid = "不合法的评论类型"
ActionCommentLimitedCode = 10006
ActionCommentLimited = "评论频繁,请稍后再试!"
InvalidContentTypeCode = 10007
InvalidContentType = "不合法的内容类型"
FavoriteServiceDuplicateCode = 10008
FavoriteServiceDuplicateError = "不能重复点赞"
FavoriteServiceCancelCode = 10009
FavoriteServiceCancelError = "没有点赞,不能取消点赞"
PublishVideoLimitedCode = 10010
PublishVideoLimited = "视频发布频繁,请稍后再试!"
ChatActionLimitedCode = 10011
ChatActionLimitedError = "发送消息频繁,请稍后再试!"
)
60 changes: 30 additions & 30 deletions src/services/favorite/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,8 @@ func (c FavoriteServiceServerImpl) FavoriteAction(ctx context.Context, req *favo
logging.SetSpanError(span, err)

return &favorite.FavoriteResponse{
StatusCode: strings.FavorivateServiceErrorCode,
StatusMsg: strings.FavorivateServiceError,
StatusCode: strings.FavoriteServiceErrorCode,
StatusMsg: strings.FavoriteServiceError,
}, err
}

Expand Down Expand Up @@ -88,8 +88,8 @@ func (c FavoriteServiceServerImpl) FavoriteAction(ctx context.Context, req *favo
//重复点赞
if value > 0 {
resp = &favorite.FavoriteResponse{
StatusCode: strings.FavorivateServiceDuplicateCode,
StatusMsg: strings.FavorivateServiceDuplicateError,
StatusCode: strings.FavoriteServiceDuplicateCode,
StatusMsg: strings.FavoriteServiceDuplicateError,
}
logger.WithFields(logrus.Fields{
"ActorId": req.ActorId,
Expand All @@ -114,8 +114,8 @@ func (c FavoriteServiceServerImpl) FavoriteAction(ctx context.Context, req *favo
//没有的点过赞
if value == 0 {
resp = &favorite.FavoriteResponse{
StatusCode: strings.FavorivateServiceCancelCode,
StatusMsg: strings.FavorivateServiceCancelError,
StatusCode: strings.FavoriteServiceCancelCode,
StatusMsg: strings.FavoriteServiceCancelError,
}

logger.WithFields(logrus.Fields{
Expand Down Expand Up @@ -150,8 +150,8 @@ func (c FavoriteServiceServerImpl) FavoriteAction(ctx context.Context, req *favo
logging.SetSpanError(span, err)

return &favorite.FavoriteResponse{
StatusCode: strings.FavorivateServiceErrorCode,
StatusMsg: strings.FavorivateServiceError,
StatusCode: strings.FavoriteServiceErrorCode,
StatusMsg: strings.FavoriteServiceError,
}, err
}
resp = &favorite.FavoriteResponse{
Expand Down Expand Up @@ -190,8 +190,8 @@ func (c FavoriteServiceServerImpl) FavoriteList(ctx context.Context, req *favori
logging.SetSpanError(span, err)

return &favorite.FavoriteListResponse{
StatusCode: strings.FavorivateServiceErrorCode,
StatusMsg: strings.FavorivateServiceError,
StatusCode: strings.FavoriteServiceErrorCode,
StatusMsg: strings.FavoriteServiceError,
}, err
}

Expand All @@ -205,8 +205,8 @@ func (c FavoriteServiceServerImpl) FavoriteList(ctx context.Context, req *favori
logging.SetSpanError(span, err)

return &favorite.FavoriteListResponse{
StatusCode: strings.FavorivateServiceErrorCode,
StatusMsg: strings.FavorivateServiceError,
StatusCode: strings.FavoriteServiceErrorCode,
StatusMsg: strings.FavoriteServiceError,
}, err
}
if len(arr) == 0 {
Expand Down Expand Up @@ -237,8 +237,8 @@ func (c FavoriteServiceServerImpl) FavoriteList(ctx context.Context, req *favori
}).Errorf("feed Service error")
logging.SetSpanError(span, err)
return &favorite.FavoriteListResponse{
StatusCode: strings.FavorivateServiceErrorCode,
StatusMsg: strings.FavorivateServiceError,
StatusCode: strings.FavoriteServiceErrorCode,
StatusMsg: strings.FavoriteServiceError,
}, err
}

Expand Down Expand Up @@ -273,8 +273,8 @@ func (c FavoriteServiceServerImpl) IsFavorite(ctx context.Context, req *favorite
}).Errorf("feed Service error")
logging.SetSpanError(span, err)
return &favorite.IsFavoriteResponse{
StatusCode: strings.FavorivateServiceErrorCode,
StatusMsg: strings.FavorivateServiceError,
StatusCode: strings.FavoriteServiceErrorCode,
StatusMsg: strings.FavoriteServiceError,
}, err
}

Expand All @@ -294,8 +294,8 @@ func (c FavoriteServiceServerImpl) IsFavorite(ctx context.Context, req *favorite
logging.SetSpanError(span, err)

return &favorite.IsFavoriteResponse{
StatusCode: strings.FavorivateServiceErrorCode,
StatusMsg: strings.FavorivateServiceError,
StatusCode: strings.FavoriteServiceErrorCode,
StatusMsg: strings.FavoriteServiceError,
}, err
}

Expand Down Expand Up @@ -340,8 +340,8 @@ func (c FavoriteServiceServerImpl) CountFavorite(ctx context.Context, req *favor
}).Errorf("feed Service error")
logging.SetSpanError(span, err)
return &favorite.CountFavoriteResponse{
StatusCode: strings.FavorivateServiceErrorCode,
StatusMsg: strings.FavorivateServiceError,
StatusCode: strings.FavoriteServiceErrorCode,
StatusMsg: strings.FavoriteServiceError,
}, err
}
videoId := fmt.Sprintf("%svideo_like_%d", config.EnvCfg.RedisPrefix, req.VideoId)
Expand All @@ -357,8 +357,8 @@ func (c FavoriteServiceServerImpl) CountFavorite(ctx context.Context, req *favor
logging.SetSpanError(span, err)

return &favorite.CountFavoriteResponse{
StatusCode: strings.FavorivateServiceErrorCode,
StatusMsg: strings.FavorivateServiceError,
StatusCode: strings.FavoriteServiceErrorCode,
StatusMsg: strings.FavoriteServiceError,
}, err
} else {
num, _ = strconv.Atoi(value)
Expand Down Expand Up @@ -398,8 +398,8 @@ func (c FavoriteServiceServerImpl) CountUserFavorite(ctx context.Context, req *f
logging.SetSpanError(span, err)

return &favorite.CountUserFavoriteResponse{
StatusCode: strings.FavorivateServiceErrorCode,
StatusMsg: strings.FavorivateServiceError,
StatusCode: strings.FavoriteServiceErrorCode,
StatusMsg: strings.FavoriteServiceError,
}, err
}
user_like_id := fmt.Sprintf("%suser_like_%d", config.EnvCfg.RedisPrefix, req.UserId)
Expand All @@ -416,8 +416,8 @@ func (c FavoriteServiceServerImpl) CountUserFavorite(ctx context.Context, req *f
logging.SetSpanError(span, err)

return &favorite.CountUserFavoriteResponse{
StatusCode: strings.FavorivateServiceErrorCode,
StatusMsg: strings.FavorivateServiceError,
StatusCode: strings.FavoriteServiceErrorCode,
StatusMsg: strings.FavoriteServiceError,
}, err
} else {
num = value
Expand Down Expand Up @@ -459,8 +459,8 @@ func (c FavoriteServiceServerImpl) CountUserTotalFavorited(ctx context.Context,
logging.SetSpanError(span, err)

return &favorite.CountUserTotalFavoritedResponse{
StatusCode: strings.FavorivateServiceErrorCode,
StatusMsg: strings.FavorivateServiceError,
StatusCode: strings.FavoriteServiceErrorCode,
StatusMsg: strings.FavoriteServiceError,
}, err
}
user_liked_id := fmt.Sprintf("%suser_liked_%d", config.EnvCfg.RedisPrefix, req.UserId)
Expand All @@ -479,8 +479,8 @@ func (c FavoriteServiceServerImpl) CountUserTotalFavorited(ctx context.Context,
logging.SetSpanError(span, err)

return &favorite.CountUserTotalFavoritedResponse{
StatusCode: strings.FavorivateServiceErrorCode,
StatusMsg: strings.FavorivateServiceError,
StatusCode: strings.FavoriteServiceErrorCode,
StatusMsg: strings.FavoriteServiceError,
}, err
} else {
num, _ = strconv.Atoi(value)
Expand Down
47 changes: 45 additions & 2 deletions src/services/message/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,12 @@ import (
"GuGoTik/src/rpc/chat"
"GuGoTik/src/rpc/user"
"GuGoTik/src/storage/database"
"GuGoTik/src/storage/redis"
grpc2 "GuGoTik/src/utils/grpc"
"GuGoTik/src/utils/logging"
"context"
"fmt"
"github.com/go-redis/redis_rate/v10"

"github.com/sirupsen/logrus"
)
Expand All @@ -27,6 +29,14 @@ func (c MessageServiceImpl) New() {
UserClient = user.NewUserServiceClient(userRpcConn)
}

var chatActionLimitKeyPrefix = config.EnvCfg.RedisPrefix + "chat_freq_limit"

const chatActionMaxQPS = 3

func chatActionLimitKey(userId uint32) string {
return fmt.Sprintf("%s-%d", chatActionLimitKeyPrefix, userId)
}

func (c MessageServiceImpl) ChatAction(ctx context.Context, request *chat.ActionRequest) (res *chat.ActionResponse, err error) {
ctx, span := tracing.Tracer.Start(ctx, "ChatActionService")
defer span.End()
Expand All @@ -39,6 +49,39 @@ func (c MessageServiceImpl) ChatAction(ctx context.Context, request *chat.Action
"content_text": request.Content,
}).Debugf("Process start")

// Rate limiting
limiter := redis_rate.NewLimiter(redis.Client)
limiterKey := chatActionLimitKey(request.ActorId)
limiterRes, err := limiter.Allow(ctx, limiterKey, redis_rate.PerSecond(chatActionMaxQPS))
if err != nil {
logger.WithFields(logrus.Fields{
"ActorId": request.ActorId,
"user_id": request.UserId,
"action_type": request.ActionType,
"content_text": request.Content,
}).Errorf("ChatAction limiter error")

res = &chat.ActionResponse{
StatusCode: strings.UnableToAddMessageErrorCode,
StatusMsg: strings.UnableToAddMessageError,
}
return
}
if limiterRes.Allowed == 0 {
logger.WithFields(logrus.Fields{
"ActorId": request.ActorId,
"user_id": request.UserId,
"action_type": request.ActionType,
"content_text": request.Content,
}).Errorf("Chat action query too frequently by user %d", request.ActorId)

res = &chat.ActionResponse{
StatusCode: strings.ChatActionLimitedCode,
StatusMsg: strings.ChatActionLimitedError,
}
return
}

userResponse, err := UserClient.GetUserExistInformation(ctx, &user.UserExistRequest{
UserId: request.UserId,
})
Expand All @@ -55,7 +98,7 @@ func (c MessageServiceImpl) ChatAction(ctx context.Context, request *chat.Action

return &chat.ActionResponse{
StatusCode: strings.UnableToAddMessageErrorCode,
StatusMsg: strings.UnableToAddMessageRrror,
StatusMsg: strings.UnableToAddMessageError,
}, err
}

Expand Down Expand Up @@ -185,7 +228,7 @@ func addMessage(ctx context.Context, fromUserId uint32, toUserId uint32, Context

resp = &chat.ActionResponse{
StatusCode: strings.UnableToAddMessageErrorCode,
StatusMsg: strings.UnableToAddMessageRrror,
StatusMsg: strings.UnableToAddMessageError,
}
return
}
Expand Down
Loading

0 comments on commit f0d2c9b

Please sign in to comment.