Em chào mọi người ạ, em có đoạn code golang Login function sử dụng grpc, em deploy nó trong kubernetes, và cho chạy benchmark 200 request thì kết quả mỗi request Login mất tận tầm 5s, trong khi chạy 1 request riêng thì chỉ mất tầm 200ms. Em đã đặt tracing nhưng không hiểu kết quả tracing luôn, nhờ mọi người xem giúp em ạ.
Một số config:
- Os: ubuntu 22.04
- CPU: 8
- RAM: 16gb
- Consumed CPU: ~40%/CPU
- Comsumed RAM: ~60%
- Grpc connection pool: 150 connections
- Mysql max idle connections: 20
- Mysql max open connection: 150
login rpc
func (x *userGrpc) Login(ctx context.Context, request *service_auth.LoginRequest) (*service_auth.LoginResponse, error) {
ctx, span := otel.Tracer("userGrpc").Start(ctx, "userGrpc.Login")
defer span.End()
propagationCache := util.GetPropgationCacheFromCtx(ctx, x.Config)
userResult := x.UserMysqlRepository.GetUserByEmail(ctx, &user.MysqlRepositoryOption{
RoleAccessibility: &service_auth.RoleAccessibility{AccessType: service_auth.RoleAccessibility_PRIVILEGED_ACCESS},
GetByEmail: &user.MysqlRepositoryGetByEmailOption{Email: request.Email},
})
if userResult.Err != nil {
return nil, x.Interpreter.TranslateError(ctx, &locale.InterpreterOption{Err: userResult.Err, Locale: propagationCache.Locale})
}
err := bcrypt.CompareHashAndPassword([]byte(userResult.GetByEmail.User.Password), []byte(request.Password))
if err != nil {
return nil, x.Interpreter.TranslateError(ctx, &locale.InterpreterOption{Err: util.ErrInvalidPassword, Locale: propagationCache.Locale})
}
mask, err := util.DetectMask(ctx, &util.FieldmaskOption{Descriptor: request.ProtoReflect().Descriptor()})
if err != nil {
return nil, x.Interpreter.TranslateError(ctx, &locale.InterpreterOption{Err: err, Locale: propagationCache.Locale})
}
fmutils.Filter(userResult.GetByEmail.User, mask.Paths)
sessionId := fmt.Sprintf("%s-%s", x.Config.Prefix.SessionIdPrefix, uuid.NewString())
_, err = x.CictGatewayClient.CictAuthClient.SessionManagerClient.MutateSession(ctx, &service_auth.MutateSessionRequest{
Operation: &service_auth.MutateSessionRequest_GracefulCreate{
GracefulCreate: &service_auth.MutateSessionGracefulCreate{UserId: userResult.GetByEmail.User.Id, SessionId: sessionId}},
})
if err != nil {
return nil, x.Interpreter.TranslateError(ctx, &locale.InterpreterOption{Err: err})
}
return &service_auth.LoginResponse{User: userResult.GetByEmail.User, SessionId: sessionId}, nil
}
GetUserByEmail:
func (x *mysqlRepository) GetUserByEmail(ctx context.Context, opt *user.MysqlRepositoryOption) *user.MysqlRepositoryResult {
_, span := otel.Tracer("mysqlRepository").Start(ctx, "mysqlRepository.GetUserByEmail")
defer span.End()
if opt.RoleAccessibility == nil || opt.GetByEmail == nil {
return &user.MysqlRepositoryResult{Err: util.ErrInternalWithInvalidArgument}
}
result := &user.MysqlRepositoryResult{GetByEmail: &user.MysqlRepositoryGetByEmailResult{User: &service_auth.User{}}}
query := gorm_helper.RoleAccessibility(x.GormDB, opt.RoleAccessibility).
Where("email = ?", opt.GetByEmail.Email).First(&result.GetByEmail.User)
result.Err = query.Error
return result
}
MutateSessionClient gọi đến một server gateway khác để push message vào kafka
func (x *sessionManagerClient) MutateSession(ctx context.Context, request *service_auth.MutateSessionRequest) (*service_auth.MutateSessionResponse, error) {
ctx, span := otel.Tracer("").Start(ctx, "sessionManagerClient.MutateSession")
defer span.End()
propagationCache := util.GetPropgationCacheFromCtx(ctx, x.Config)
md := metadata.Pairs(
x.Config.Const.Scope, service_auth.EnumScope_AUTH_SCOPE.Enum().String(),
x.Config.Const.Locale, propagationCache.Locale,
x.Config.Const.SessionId, propagationCache.Session.Id,
x.Config.Const.WorkspaceId, propagationCache.WorkspaceId,
)
newCtx := metadata.NewOutgoingContext(context.Background(), md)
cictGatewayEndpoint := fmt.Sprintf("%s:%d", x.Config.Services.ServiceGatewayEndpoint.Address, x.Config.Services.ServiceGatewayEndpoint.Port)
conn, err := grpc.Dial(cictGatewayEndpoint, grpc.WithTransportCredentials(insecure.NewCredentials()))
if err != nil {
return nil, err
}
defer conn.Close()
client := service_auth.NewSessionManagerServiceClient(conn)
return client.MutateSession(newCtx, request)
}
Đây là kết quả tracing: