291 lines
8.5 KiB
Markdown
291 lines
8.5 KiB
Markdown
# ProfileService - 角色管理服务
|
||
|
||
ProfileService是CarrotSkin皮肤站的角色管理微服务,负责处理Minecraft角色的创建、管理、RSA密钥生成和签名验证等核心功能。
|
||
|
||
## 📋 目录
|
||
|
||
- [功能特性](#功能特性)
|
||
- [技术架构](#技术架构)
|
||
- [数据模型](#数据模型)
|
||
- [API接口](#api接口)
|
||
- [部署指南](#部署指南)
|
||
- [开发指南](#开发指南)
|
||
- [故障排查](#故障排查)
|
||
|
||
## 🚀 功能特性
|
||
|
||
### 核心功能
|
||
- **角色管理**: 创建、查询、更新、删除Minecraft角色
|
||
- **RSA密钥管理**: 自动生成RSA-2048密钥对,支持数据签名和验证
|
||
- **皮肤/披风关联**: 管理角色与皮肤、披风的关联关系
|
||
- **用户角色列表**: 支持查询用户下的所有角色
|
||
- **数据验证**: 完整的参数验证和业务逻辑检查
|
||
|
||
### 安全特性
|
||
- **RSA签名**: 支持使用私钥对数据进行签名
|
||
- **签名验证**: 支持使用公钥验证数据签名
|
||
- **权限控制**: 确保用户只能操作自己的角色
|
||
- **数据完整性**: 完整的事务处理和数据一致性保证
|
||
|
||
## 🏗️ 技术架构
|
||
|
||
### 技术栈
|
||
- **框架**: go-zero微服务框架
|
||
- **数据库**: MySQL 8.0+
|
||
- **缓存**: Redis (通过go-zero集成)
|
||
- **通信协议**: gRPC
|
||
- **密钥算法**: RSA-2048
|
||
|
||
### 服务架构
|
||
```
|
||
ProfileService
|
||
├── internal/
|
||
│ ├── config/ # 配置管理
|
||
│ ├── handler/ # gRPC处理器
|
||
│ ├── logic/ # 业务逻辑层
|
||
│ ├── model/ # 数据模型层
|
||
│ └── svc/ # 服务上下文
|
||
├── pb/ # Protocol Buffers定义
|
||
└── docs/ # 文档和SQL脚本
|
||
```
|
||
|
||
## 📊 数据模型
|
||
|
||
### 数据库表结构
|
||
|
||
```sql
|
||
CREATE TABLE `profiles` (
|
||
`uuid` VARCHAR(36) NOT NULL COMMENT '角色的UUID,通常为Minecraft玩家的UUID',
|
||
`user_id` BIGINT UNSIGNED NOT NULL COMMENT '关联的用户ID',
|
||
`name` VARCHAR(16) NOT NULL COMMENT '角色名 (Minecraft In-Game Name)',
|
||
`skin_id` BIGINT UNSIGNED NULL DEFAULT NULL COMMENT '当前使用的皮肤ID',
|
||
`cape_id` BIGINT UNSIGNED NULL DEFAULT NULL COMMENT '当前使用的披风ID',
|
||
`rsa_private_key` TEXT NOT NULL COMMENT 'RSA-2048私钥 (PEM格式)',
|
||
`created_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||
`updated_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||
PRIMARY KEY (`uuid`),
|
||
INDEX `idx_user_id` (`user_id`)
|
||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
|
||
```
|
||
|
||
### 数据类型映射
|
||
|
||
| 字段 | SQL类型 | Go Model类型 | Proto类型 | 说明 |
|
||
|------|---------|-------------|-----------|------|
|
||
| uuid | VARCHAR(36) | string | string | 角色UUID |
|
||
| user_id | BIGINT UNSIGNED | uint64 | int64 | 用户ID |
|
||
| name | VARCHAR(16) | string | string | 角色名 |
|
||
| skin_id | BIGINT UNSIGNED NULL | sql.NullInt64 | int64 | 皮肤ID (0表示无皮肤) |
|
||
| cape_id | BIGINT UNSIGNED NULL | sql.NullInt64 | int64 | 披风ID (0表示无披风) |
|
||
| rsa_private_key | TEXT | string | string | RSA私钥 |
|
||
| created_at | TIMESTAMP | time.Time | string | 创建时间 |
|
||
| updated_at | TIMESTAMP | time.Time | string | 更新时间 |
|
||
|
||
## 🔌 API接口
|
||
|
||
### 对外接口 (Public APIs)
|
||
|
||
#### 1. CreateProfile - 创建角色
|
||
```protobuf
|
||
rpc CreateProfile(CreateProfileRequest) returns (CreateProfileResponse);
|
||
```
|
||
- **功能**: 创建新的Minecraft角色
|
||
- **验证**: UUID格式、角色名格式、用户权限
|
||
- **特性**: 自动生成RSA密钥对、角色名去重检查
|
||
|
||
#### 2. GetProfile - 获取角色信息
|
||
```protobuf
|
||
rpc GetProfile(GetProfileRequest) returns (GetProfileResponse);
|
||
```
|
||
- **功能**: 根据UUID获取角色基本信息
|
||
- **返回**: 不包含私钥的公开信息
|
||
|
||
#### 3. GetProfilesByUserId - 获取用户角色列表
|
||
```protobuf
|
||
rpc GetProfilesByUserId(GetProfilesByUserIdRequest) returns (GetProfilesByUserIdResponse);
|
||
```
|
||
- **功能**: 获取指定用户的所有角色列表
|
||
- **特性**: 支持空结果返回
|
||
|
||
#### 4. UpdateProfile - 更新角色信息
|
||
```protobuf
|
||
rpc UpdateProfile(UpdateProfileRequest) returns (UpdateProfileResponse);
|
||
```
|
||
- **功能**: 更新角色名、皮肤ID、披风ID
|
||
- **验证**: 角色名重复检查、权限验证
|
||
- **特性**: 支持NULL值处理 (0表示移除)
|
||
|
||
#### 5. DeleteProfile - 删除角色
|
||
```protobuf
|
||
rpc DeleteProfile(DeleteProfileRequest) returns (DeleteProfileResponse);
|
||
```
|
||
- **功能**: 删除指定角色
|
||
- **验证**: 权限检查
|
||
|
||
#### 6. GetProfilePublicKey - 获取角色公钥
|
||
```protobuf
|
||
rpc GetProfilePublicKey(GetProfilePublicKeyRequest) returns (GetProfilePublicKeyResponse);
|
||
```
|
||
- **功能**: 获取角色的RSA公钥
|
||
- **用途**: 用于验证角色签名
|
||
|
||
#### 7. VerifyProfileSignature - 验证角色签名
|
||
```protobuf
|
||
rpc VerifyProfileSignature(VerifyProfileSignatureRequest) returns (VerifyProfileSignatureResponse);
|
||
```
|
||
- **功能**: 验证使用角色私钥生成的签名
|
||
- **算法**: RSA-2048 + SHA-256
|
||
|
||
#### 8. GetProfileWithProperties - 查询角色属性
|
||
```protobuf
|
||
rpc GetProfileWithProperties(GetProfileWithPropertiesRequest) returns (GetProfileWithPropertiesResponse);
|
||
```
|
||
- **功能**: 查询角色完整信息,包含Minecraft协议兼容的属性和签名
|
||
- **用途**: 用于游戏客户端获取皮肤、披风等信息
|
||
- **特性**: 支持生成带签名和不带签名的属性
|
||
|
||
#### 9. GetProfilesByNames - 批量查询角色
|
||
```protobuf
|
||
rpc GetProfilesByNames(GetProfilesByNamesRequest) returns (GetProfilesByNamesResponse);
|
||
```
|
||
- **功能**: 根据角色名称列表批量查询角色信息
|
||
- **返回**: 简化的角色信息列表(UUID和名称)
|
||
|
||
#### 10. GetUserIdByProfileName - 根据角色名获取用户ID
|
||
```protobuf
|
||
rpc GetUserIdByProfileName(GetUserIdByProfileNameRequest) returns (GetUserIdByProfileNameResponse);
|
||
```
|
||
- **功能**: 根据角色名称查找关联的用户ID
|
||
- **用途**: 支持使用角色名进行登录等操作
|
||
|
||
### 对内接口 (Internal APIs)
|
||
|
||
#### 11. GetProfileInternalInfo - 获取角色内部信息
|
||
```protobuf
|
||
rpc GetProfileInternalInfo(GetProfileInternalInfoRequest) returns (ProfileInternalInfo);
|
||
```
|
||
- **功能**: 获取包含私钥的完整角色信息
|
||
- **权限**: 仅供内部微服务调用
|
||
- **安全**: 包含敏感信息,需要严格权限控制
|
||
|
||
#### 12. SignData - 使用私钥签名数据
|
||
```protobuf
|
||
rpc SignData(SignDataRequest) returns (SignDataResponse);
|
||
```
|
||
- **功能**: 使用角色私钥对数据进行签名
|
||
- **算法**: RSA-2048 + SHA-256
|
||
- **返回**: Base64编码的签名结果
|
||
|
||
## 🚀 部署指南
|
||
|
||
### 环境要求
|
||
- Go 1.19+
|
||
- MySQL 8.0+
|
||
- Redis 6.0+
|
||
|
||
### 配置文件示例
|
||
|
||
```yaml
|
||
# etc/profile.yaml
|
||
Name: profile.rpc
|
||
ListenOn: 0.0.0.0:8082
|
||
|
||
#Etcd:
|
||
# Hosts:
|
||
# - 127.0.0.1:2379
|
||
# Key: profile.rpc
|
||
|
||
DataSource: root:password@tcp(localhost:3306)/carrot_skin?charset=utf8mb4&parseTime=true&loc=Asia%2FShanghai
|
||
|
||
CacheConf:
|
||
- Host: 127.0.0.1:6379
|
||
Pass: ""
|
||
Type: node
|
||
```
|
||
|
||
### 部署步骤
|
||
|
||
1. **数据库初始化**
|
||
```bash
|
||
mysql -u root -p carrot_skin < docs/profiles.sql
|
||
```
|
||
|
||
2. **编译服务**
|
||
```bash
|
||
go build -o profile-service .
|
||
```
|
||
|
||
3. **启动服务**
|
||
```bash
|
||
./profile-service -f etc/profile.yaml
|
||
```
|
||
|
||
## 🛠️ 开发指南
|
||
|
||
### 代码生成
|
||
|
||
使用提供的脚本重新生成代码:
|
||
|
||
```bash
|
||
# Windows
|
||
generate.bat
|
||
|
||
# Linux/Mac
|
||
chmod +x generate.sh
|
||
./generate.sh
|
||
```
|
||
|
||
### 业务逻辑扩展
|
||
|
||
所有业务逻辑都在 `internal/logic/` 目录下:
|
||
|
||
- `createProfileLogic.go` - 角色创建逻辑
|
||
- `getProfileLogic.go` - 角色查询逻辑
|
||
- `updateProfileLogic.go` - 角色更新逻辑
|
||
- `deleteProfileLogic.go` - 角色删除逻辑
|
||
- 等等...
|
||
|
||
### 数据模型扩展
|
||
|
||
如需添加新的数据库方法,在 `internal/model/profilesmodel.go` 中扩展:
|
||
|
||
```go
|
||
type ProfilesModel interface {
|
||
profilesModel
|
||
// 添加自定义方法
|
||
FindByUserId(ctx context.Context, userId uint64) ([]*Profiles, error)
|
||
}
|
||
```
|
||
|
||
## 🔧 故障排查
|
||
|
||
### 常见问题
|
||
|
||
#### 1. 数据类型转换错误
|
||
**问题**: `sql.NullInt64` 类型处理错误
|
||
**解决**: 使用 `nullInt64ToValue()` 函数进行正确转换
|
||
|
||
#### 2. RSA密钥生成失败
|
||
**问题**: RSA密钥生成或解析失败
|
||
**解决**: 检查系统随机数生成器,确保有足够的熵
|
||
|
||
#### 3. 角色名重复
|
||
**问题**: 同一用户下角色名重复
|
||
**解决**: 创建和更新时都会进行重复检查
|
||
|
||
#### 4. UUID格式错误
|
||
**问题**: UUID格式不符合标准
|
||
**解决**: 确保UUID为36位标准格式 (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)
|
||
|
||
### 日志级别
|
||
|
||
- **INFO**: 正常业务操作
|
||
- **ERROR**: 业务错误和系统错误
|
||
- **DEBUG**: 详细的调试信息
|
||
|
||
### 性能监控
|
||
|
||
- 数据库连接池状态
|
||
- Redis缓存命中率
|
||
- gRPC请求响应时间
|
||
- RSA密钥操作耗时 |