修复:为 user-svc 添加健康检查和启动顺序控制

This commit is contained in:
fish
2026-03-28 21:54:09 +08:00
parent 5ac0a52bb1
commit c5260bcae8
31 changed files with 1995 additions and 167 deletions

View File

@@ -30,7 +30,7 @@ func Load() (*Config, error) {
viper.AddConfigPath("../../config")
viper.SetDefault("server.port", 9000)
viper.SetDefault("database.host", "postgres")
viper.SetDefault("database.host", "backend-postgres")
viper.SetDefault("database.port", 5432)
viper.SetDefault("database.user", "admin")
viper.SetDefault("database.password", "password")

View File

@@ -5,17 +5,18 @@ import (
"fmt"
"net"
"backend/services/user-svc/internal/domain"
"backend/services/user-svc/internal/service"
"backend/shared/pkg/errors"
"backend/shared/pkg/logger"
"user-svc/internal/domain"
"user-svc/internal/service"
"shared/pkg/errors"
"shared/pkg/logger"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
// 导入生成的 proto 代码
userpb "backend/services/user-svc/proto"
userpb "shared/proto/user"
common "shared/proto/common"
)
type UserServer struct {
@@ -41,36 +42,36 @@ func (s *UserServer) Register(ctx context.Context, req *userpb.RegisterRequest)
logger.Error("Register failed: %v", err)
// 转换错误类型
switch {
case errors.IsConflict(err):
return &userpb.RegisterResponse{
Response: &userpb.Response{
Code: 409,
Message: "账号已存在",
},
}, status.Errorf(codes.AlreadyExists, "账号已存在")
case errors.IsInvalidInput(err):
return &userpb.RegisterResponse{
Response: &userpb.Response{
Code: 400,
Message: "无效的输入参数",
},
}, status.Errorf(codes.InvalidArgument, "无效的输入参数")
default:
return &userpb.RegisterResponse{
Response: &userpb.Response{
Code: 500,
Message: "内部服务器错误",
},
}, status.Errorf(codes.Internal, "内部服务器错误")
}
switch {
case errors.IsConflict(err):
return &userpb.RegisterResponse{
Response: &common.Response{
Code: 409,
Message: "账号已存在",
},
}, status.Errorf(codes.AlreadyExists, "账号已存在")
case errors.IsInvalidInput(err):
return &userpb.RegisterResponse{
Response: &common.Response{
Code: 400,
Message: "无效的输入参数",
},
}, status.Errorf(codes.InvalidArgument, "无效的输入参数")
default:
return &userpb.RegisterResponse{
Response: &common.Response{
Code: 500,
Message: "内部服务器错误",
},
}, status.Errorf(codes.Internal, "内部服务器错误")
}
}
// 构造响应
return &userpb.RegisterResponse{
UserId: resp.UserID.String(),
Account: resp.Account,
Response: &userpb.Response{
Response: &common.Response{
Code: 200,
Message: "注册成功",
},
@@ -88,21 +89,21 @@ func (s *UserServer) GetUserByAccount(ctx context.Context, req *userpb.GetUserBy
switch {
case errors.IsNotFound(err):
return &userpb.GetUserByAccountResponse{
Response: &userpb.Response{
Response: &common.Response{
Code: 404,
Message: "用户不存在",
},
}, status.Errorf(codes.NotFound, "用户不存在")
case errors.IsInvalidInput(err):
return &userpb.GetUserByAccountResponse{
Response: &userpb.Response{
Response: &common.Response{
Code: 400,
Message: "无效的输入参数",
},
}, status.Errorf(codes.InvalidArgument, "无效的输入参数")
default:
return &userpb.GetUserByAccountResponse{
Response: &userpb.Response{
Response: &common.Response{
Code: 500,
Message: "内部服务器错误",
},
@@ -114,7 +115,7 @@ func (s *UserServer) GetUserByAccount(ctx context.Context, req *userpb.GetUserBy
return &userpb.GetUserByAccountResponse{
UserId: user.ID.String(),
Account: account.Account,
Response: &userpb.Response{
Response: &common.Response{
Code: 200,
Message: "获取成功",
},

View File

@@ -2,10 +2,9 @@ package repository
import (
"database/sql"
"time"
"backend/services/user-svc/internal/domain"
"backend/shared/pkg/errors"
"user-svc/internal/domain"
"shared/pkg/errors"
"github.com/google/uuid"
"golang.org/x/crypto/bcrypt"
@@ -41,7 +40,11 @@ func (r *UserRepository) Register(req *domain.RegisterRequest) (*domain.Register
}
// 创建用户
userID := uuid.NewV7()
userID, err := uuid.NewV7()
if err != nil {
tx.Rollback()
return nil, errors.WrapError(err, "failed to generate user ID")
}
userQuery := "INSERT INTO user_main (id, deleted) VALUES ($1, $2)"
if _, err := tx.Exec(userQuery, userID, false); err != nil {
@@ -50,7 +53,11 @@ func (r *UserRepository) Register(req *domain.RegisterRequest) (*domain.Register
}
// 创建登录账号
accountID := uuid.NewV7()
accountID, err := uuid.NewV7()
if err != nil {
tx.Rollback()
return nil, errors.WrapError(err, "failed to generate account ID")
}
accountQuery := "INSERT INTO user_login_account (id, user_id, account, deleted) VALUES ($1, $2, $3, $4)"
if _, err := tx.Exec(accountQuery, accountID, userID, req.Account, false); err != nil {
tx.Rollback()
@@ -65,7 +72,11 @@ func (r *UserRepository) Register(req *domain.RegisterRequest) (*domain.Register
}
// 创建密码记录
passwordID := uuid.NewV7()
passwordID, err := uuid.NewV7()
if err != nil {
tx.Rollback()
return nil, errors.WrapError(err, "failed to generate password ID")
}
passwordQuery := "INSERT INTO user_login_password (id, user_id, password, deleted) VALUES ($1, $2, $3, $4)"
if _, err := tx.Exec(passwordQuery, passwordID, userID, string(hashedPassword), false); err != nil {
tx.Rollback()

View File

@@ -1,9 +1,10 @@
package service
import (
"backend/services/user-svc/internal/domain"
"backend/services/user-svc/internal/repository"
"backend/shared/pkg/errors"
"user-svc/internal/domain"
"user-svc/internal/repository"
"shared/pkg/errors"
)
type UserService struct {