616 lines
20 KiB
Markdown
616 lines
20 KiB
Markdown
# LingAdmin 分布式微服务架构
|
||
|
||
基于 Dapr 的后台管理系统分布式服务框架。
|
||
|
||
## 📋 目录
|
||
|
||
- [架构概述](#架构概述)
|
||
- [服务划分](#服务划分)
|
||
- [技术栈](#技术栈)
|
||
- [项目结构](#项目结构)
|
||
- [快速开始](#快速开始)
|
||
- [API 文档](#api-文档)
|
||
- [Dapr 集成](#dapr-集成)
|
||
- [安全机制](#安全机制)
|
||
- [部署指南](#部署指南)
|
||
|
||
---
|
||
|
||
## 🏗️ 架构概述
|
||
|
||
本系统采用微服务架构,使用 Dapr 作为分布式应用运行时,实现服务发现、状态管理、发布订阅等核心功能。
|
||
|
||
### 架构图
|
||
|
||
```
|
||
┌─────────────────────────────────────────────────────────┐
|
||
│ Client │
|
||
│ (Web App / Mobile App) │
|
||
└─────────────────────────┬───────────────────────────────┘
|
||
│
|
||
▼
|
||
┌─────────────────────────────────────────────────────────┐
|
||
│ API Gateway │
|
||
│ (Port: 5000) │
|
||
│ ┌─────────────────────────────────────────────────┐ │
|
||
│ │ • 请求路由 (YARP) │ │
|
||
│ │ • JWT 认证 │ │
|
||
│ │ • 限流保护 │ │
|
||
│ │ • 请求日志 │ │
|
||
│ └─────────────────────────────────────────────────┘ │
|
||
└─────────────────────────┬───────────────────────────────┘
|
||
│
|
||
┌───────────────────────────────────┼───────────────────────────────────┐
|
||
│ │ │
|
||
▼ ▼ ▼
|
||
┌─────────────────────────────┐ ┌─────────────────────────────┐ ┌─────────────────────────────┐
|
||
│ Identity Service │ │ Authorization Service │ │ Business Services │
|
||
│ (Port: 5001) │ │ (Port: 5002) │ │ (可扩展...) │
|
||
│ ┌───────────────────────┐ │ │ ┌───────────────────────┐ │ │ ┌───────────────────────┐ │
|
||
│ │ • 用户注册 │ │ │ │ • 角色管理 │ │ │ │ • 业务逻辑 │ │
|
||
│ │ • 用户登录 │ │ │ │ • 权限管理 │ │ │ │ • ... │ │
|
||
│ │ • Token 管理 │ │ │ │ • 用户角色分配 │ │ │ └───────────────────────┘ │
|
||
│ │ • 密码管理 │ │ │ │ • 权限验证 │ │ └─────────────────────────────┘
|
||
│ └───────────────────────┘ │ │ └───────────────────────┘ │
|
||
└──────────────┬──────────────┘ └──────────────┬──────────────┘
|
||
│ │
|
||
│ ┌─────────────────────────┤
|
||
│ │ │
|
||
▼ ▼ ▼
|
||
┌─────────────────────────────────────────────────────────────────────────────────────────┐
|
||
│ Dapr Sidecar │
|
||
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
|
||
│ │ 服务调用 │ │ 状态存储 │ │ 发布订阅 │ │ 配置管理 │ │
|
||
│ └──────────────┘ └──────────────┘ └──────────────┘ └──────────────┘ │
|
||
└─────────────────────────────────────────┬───────────────────────────────────────────────┘
|
||
│
|
||
┌───────────────────────┼───────────────────────┐
|
||
│ │ │
|
||
▼ ▼ ▼
|
||
┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐
|
||
│ Redis │ │ SQL Server │ │ 其他存储 │
|
||
│ (State/PubSub) │ │ (Database) │ │ │
|
||
└──────────────────┘ └──────────────────┘ └──────────────────┘
|
||
```
|
||
|
||
---
|
||
|
||
## 🎯 服务划分
|
||
|
||
### 1. API Gateway (API 网关)
|
||
|
||
| 属性 | 说明 |
|
||
|------|------|
|
||
| **端口** | 5000 |
|
||
| **Dapr App ID** | api-gateway |
|
||
| **职责** | 请求路由、认证、限流、日志 |
|
||
|
||
**核心功能:**
|
||
- 使用 YARP 进行请求路由
|
||
- JWT Token 验证
|
||
- 请求限流 (100 次/分钟)
|
||
- 请求追踪和日志记录
|
||
- 健康检查端点
|
||
|
||
### 2. Identity Service (身份认证服务)
|
||
|
||
| 属性 | 说明 |
|
||
|------|------|
|
||
| **端口** | 5001 |
|
||
| **Dapr App ID** | identity-service |
|
||
| **数据库** | LingAdmin_Identity |
|
||
| **职责** | 用户身份管理 |
|
||
|
||
**核心功能:**
|
||
- 用户注册 (`POST /api/auth/register`)
|
||
- 用户登录 (`POST /api/auth/login`)
|
||
- Token 刷新 (`POST /api/auth/refresh-token`)
|
||
- 用户登出 (`POST /api/auth/logout`)
|
||
- 修改密码 (`POST /api/auth/change-password`)
|
||
- 用户信息管理
|
||
|
||
**数据模型:**
|
||
```
|
||
User
|
||
├── Id (int)
|
||
├── Name (string)
|
||
├── Email (string, unique)
|
||
├── PasswordHash (string)
|
||
├── Status (string: Active/Inactive/Suspended)
|
||
├── CreatedAt (datetime)
|
||
├── LastLoginAt (datetime?)
|
||
└── UpdatedAt (datetime?)
|
||
|
||
RefreshToken
|
||
├── Id (int)
|
||
├── UserId (int, FK)
|
||
├── Token (string)
|
||
├── ExpiresAt (datetime)
|
||
├── CreatedAt (datetime)
|
||
├── CreatedByIp (string?)
|
||
├── RevokedAt (datetime?)
|
||
├── RevokedByIp (string?)
|
||
└── ReplacedByToken (string?)
|
||
```
|
||
|
||
### 3. Authorization Service (授权服务)
|
||
|
||
| 属性 | 说明 |
|
||
|------|------|
|
||
| **端口** | 5002 |
|
||
| **Dapr App ID** | authorization-service |
|
||
| **数据库** | LingAdmin_Authorization |
|
||
| **职责** | 角色和权限管理 |
|
||
|
||
**核心功能:**
|
||
- 角色 CRUD 操作
|
||
- 权限管理
|
||
- 用户角色分配
|
||
- 权限验证 (供其他服务调用)
|
||
|
||
**数据模型:**
|
||
```
|
||
Role Permission
|
||
├── Id (int) ├── Id (int)
|
||
├── Name (string) ├── Name (string)
|
||
├── Code (string, unique) ├── Code (string, unique)
|
||
├── Description (string?) ├── Description (string?)
|
||
├── IsSystem (bool) ├── Resource (string)
|
||
├── CreatedAt (datetime) ├── Action (string)
|
||
└── UpdatedAt (datetime?) └── CreatedAt (datetime)
|
||
|
||
UserRole RolePermission
|
||
├── UserId (int, PK) ├── RoleId (int, PK)
|
||
├── RoleId (int, PK, FK) ├── PermissionId (int, PK, FK)
|
||
├── AssignedAt (datetime) └── AssignedAt (datetime)
|
||
└── AssignedBy (int?)
|
||
```
|
||
|
||
**预置权限:**
|
||
| 权限代码 | 描述 | 资源 | 操作 |
|
||
|----------|------|------|------|
|
||
| users:read | 查看用户 | users | read |
|
||
| users:create | 创建用户 | users | create |
|
||
| users:update | 编辑用户 | users | update |
|
||
| users:delete | 删除用户 | users | delete |
|
||
| roles:read | 查看角色 | roles | read |
|
||
| roles:create | 创建角色 | roles | create |
|
||
| roles:update | 编辑角色 | roles | update |
|
||
| roles:delete | 删除角色 | roles | delete |
|
||
| permissions:read | 查看权限 | permissions | read |
|
||
| permissions:assign | 分配权限 | permissions | assign |
|
||
|
||
**预置角色:**
|
||
| 角色代码 | 描述 | 权限 |
|
||
|----------|------|------|
|
||
| SuperAdmin | 超级管理员 | 所有权限 |
|
||
| Admin | 管理员 | 大部分权限(不含删除) |
|
||
| User | 普通用户 | 基本读取权限 |
|
||
| Editor | 编辑 | 内容编辑相关权限 |
|
||
| Auditor | 审核员 | 审核相关权限 |
|
||
|
||
---
|
||
|
||
## 🛠️ 技术栈
|
||
|
||
| 组件 | 技术 | 版本 |
|
||
|------|------|------|
|
||
| 框架 | .NET | 8.0 |
|
||
| 分布式运行时 | Dapr | 1.12.0 |
|
||
| API 网关 | YARP | 2.1.0 |
|
||
| ORM | Entity Framework Core | 8.0 |
|
||
| 数据库 | SQL Server | 2019+ |
|
||
| 缓存/消息 | Redis | 7.0+ |
|
||
| 认证 | JWT | - |
|
||
| 密码加密 | BCrypt | 4.0.3 |
|
||
| API 文档 | Swagger/OpenAPI | - |
|
||
|
||
---
|
||
|
||
## 📁 项目结构
|
||
|
||
```
|
||
Backend/
|
||
└── Services/
|
||
├── LingAdmin.Microservices.sln # 解决方案文件
|
||
├── start-all.ps1 # 启动所有服务脚本
|
||
├── stop-all.ps1 # 停止所有服务脚本
|
||
│
|
||
├── Shared/
|
||
│ └── LingAdmin.Shared/ # 共享库
|
||
│ ├── Models/ # 共享数据模型
|
||
│ ├── DTOs/ # 共享 DTO
|
||
│ └── Events/ # Dapr 事件定义
|
||
│
|
||
├── ApiGateway/
|
||
│ └── LingAdmin.ApiGateway/ # API 网关服务
|
||
│ ├── Controllers/ # 控制器 (健康检查等)
|
||
│ ├── Middleware/ # 中间件
|
||
│ └── Properties/ # 启动配置
|
||
│
|
||
├── IdentityService/
|
||
│ └── LingAdmin.IdentityService/ # 身份认证服务
|
||
│ ├── Controllers/ # 认证相关 API
|
||
│ ├── Data/ # 数据库上下文
|
||
│ └── Services/ # 业务服务
|
||
│
|
||
├── AuthorizationService/
|
||
│ └── LingAdmin.AuthorizationService/ # 授权服务
|
||
│ ├── Controllers/ # 角色权限 API
|
||
│ ├── Data/ # 数据库上下文
|
||
│ └── Services/ # 业务服务
|
||
│
|
||
└── dapr/
|
||
├── dapr.yaml # Dapr 多应用配置
|
||
└── components/
|
||
├── statestore.yaml # 状态存储配置
|
||
└── pubsub.yaml # 发布订阅配置
|
||
```
|
||
|
||
---
|
||
|
||
## 🚀 快速开始
|
||
|
||
### 前置要求
|
||
|
||
1. **.NET 8 SDK**
|
||
```powershell
|
||
winget install Microsoft.DotNet.SDK.8
|
||
```
|
||
|
||
2. **Dapr CLI**
|
||
```powershell
|
||
powershell -Command "iwr -useb https://raw.githubusercontent.com/dapr/cli/master/install/install.ps1 | iex"
|
||
dapr init
|
||
```
|
||
|
||
3. **Docker Desktop** (用于 Redis)
|
||
```powershell
|
||
winget install Docker.DockerDesktop
|
||
```
|
||
|
||
4. **SQL Server**
|
||
```powershell
|
||
winget install Microsoft.SQLServer.2022.Developer
|
||
```
|
||
|
||
### 安装步骤
|
||
|
||
1. **克隆项目并还原依赖**
|
||
```powershell
|
||
cd Backend/Services
|
||
dotnet restore LingAdmin.Microservices.sln
|
||
```
|
||
|
||
2. **配置数据库连接**
|
||
|
||
修改各服务的 `appsettings.Development.json`:
|
||
```json
|
||
{
|
||
"ConnectionStrings": {
|
||
"DefaultConnection": "Server=localhost;Database=<ServiceDB>;Trusted_Connection=True;TrustServerCertificate=True;"
|
||
}
|
||
}
|
||
```
|
||
|
||
3. **创建数据库迁移**
|
||
```powershell
|
||
# Identity Service
|
||
cd IdentityService/LingAdmin.IdentityService
|
||
dotnet ef migrations add InitialCreate
|
||
|
||
# Authorization Service
|
||
cd ../../AuthorizationService/LingAdmin.AuthorizationService
|
||
dotnet ef migrations add InitialCreate
|
||
```
|
||
|
||
4. **启动 Redis**
|
||
```powershell
|
||
docker run -d --name redis -p 6379:6379 redis:latest
|
||
```
|
||
|
||
5. **启动所有服务**
|
||
```powershell
|
||
cd Backend/Services
|
||
.\start-all.ps1
|
||
```
|
||
|
||
或者使用 Dapr CLI:
|
||
```powershell
|
||
cd Backend/Services/dapr
|
||
dapr run -f dapr.yaml
|
||
```
|
||
|
||
### 验证安装
|
||
|
||
访问以下 Swagger UI 页面:
|
||
- API Gateway: http://localhost:5000/swagger
|
||
- Identity Service: http://localhost:5001/swagger
|
||
- Authorization Service: http://localhost:5002/swagger
|
||
|
||
---
|
||
|
||
## 📖 API 文档
|
||
|
||
### 认证 API (通过网关访问)
|
||
|
||
#### 用户注册
|
||
```http
|
||
POST /api/auth/register
|
||
Content-Type: application/json
|
||
|
||
{
|
||
"name": "张三",
|
||
"email": "zhangsan@example.com",
|
||
"password": "Password@123"
|
||
}
|
||
```
|
||
|
||
#### 用户登录
|
||
```http
|
||
POST /api/auth/login
|
||
Content-Type: application/json
|
||
|
||
{
|
||
"email": "zhangsan@example.com",
|
||
"password": "Password@123",
|
||
"rememberMe": true
|
||
}
|
||
```
|
||
|
||
**响应:**
|
||
```json
|
||
{
|
||
"success": true,
|
||
"data": {
|
||
"accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
|
||
"refreshToken": "dGhpcyBpcyBhIHJlZnJlc2ggdG9rZW4...",
|
||
"expiresAt": "2026-02-03T13:00:00Z",
|
||
"user": {
|
||
"id": 1,
|
||
"name": "张三",
|
||
"email": "zhangsan@example.com",
|
||
"status": "Active",
|
||
"roles": ["User"],
|
||
"permissions": ["users:read", "roles:read"]
|
||
}
|
||
},
|
||
"message": "Login successful",
|
||
"code": 200
|
||
}
|
||
```
|
||
|
||
#### 刷新 Token
|
||
```http
|
||
POST /api/auth/refresh-token
|
||
Content-Type: application/json
|
||
|
||
{
|
||
"refreshToken": "your-refresh-token"
|
||
}
|
||
```
|
||
|
||
### 角色权限 API
|
||
|
||
#### 获取所有角色
|
||
```http
|
||
GET /api/roles
|
||
Authorization: Bearer <access-token>
|
||
```
|
||
|
||
#### 分配角色给用户
|
||
```http
|
||
POST /api/roles/assign
|
||
Authorization: Bearer <access-token>
|
||
Content-Type: application/json
|
||
|
||
{
|
||
"userId": 1,
|
||
"roleIds": [2, 3]
|
||
}
|
||
```
|
||
|
||
#### 获取用户权限
|
||
```http
|
||
GET /api/authorization/users/{userId}/permissions
|
||
```
|
||
|
||
---
|
||
|
||
## 🔗 Dapr 集成
|
||
|
||
### 服务调用
|
||
|
||
服务之间通过 Dapr 进行调用:
|
||
|
||
```csharp
|
||
// 从 Identity Service 调用 Authorization Service
|
||
var permissions = await _daprClient.InvokeMethodAsync<UserPermissionsDto>(
|
||
HttpMethod.Get,
|
||
"authorization-service", // 目标服务的 App ID
|
||
$"api/authorization/users/{userId}/permissions");
|
||
```
|
||
|
||
### 事件发布
|
||
|
||
```csharp
|
||
// 发布用户创建事件
|
||
await _daprClient.PublishEventAsync(
|
||
"pubsub", // PubSub 组件名
|
||
"user-created", // 主题名
|
||
new UserCreatedEvent { UserId = user.Id, Email = user.Email });
|
||
```
|
||
|
||
### 事件订阅
|
||
|
||
```csharp
|
||
[Topic("pubsub", "user-created")]
|
||
[HttpPost("events/user-created")]
|
||
public async Task HandleUserCreated(UserCreatedEvent @event)
|
||
{
|
||
// 处理用户创建事件
|
||
await _roleService.AssignRolesToUserAsync(@event.UserId, new[] { 3 }); // 分配默认角色
|
||
}
|
||
```
|
||
|
||
### 状态存储
|
||
|
||
```csharp
|
||
// 保存状态
|
||
await _daprClient.SaveStateAsync("statestore", $"user-session-{userId}", sessionData);
|
||
|
||
// 读取状态
|
||
var session = await _daprClient.GetStateAsync<SessionData>("statestore", $"user-session-{userId}");
|
||
```
|
||
|
||
---
|
||
|
||
## 🔒 安全机制
|
||
|
||
### JWT 认证
|
||
|
||
- **算法**: HMAC SHA256
|
||
- **Access Token 有效期**: 60 分钟 (可配置)
|
||
- **Refresh Token 有效期**: 7 天 (可配置)
|
||
|
||
### 密码策略
|
||
|
||
- 最少 8 个字符
|
||
- 至少一个大写字母
|
||
- 至少一个小写字母
|
||
- 至少一个数字
|
||
- 至少一个特殊字符
|
||
|
||
### Token 刷新机制
|
||
|
||
1. Access Token 过期后,使用 Refresh Token 获取新的 Token 对
|
||
2. Refresh Token 使用后立即失效(轮换机制)
|
||
3. 密码修改后所有 Refresh Token 自动失效
|
||
|
||
---
|
||
|
||
## 🚢 部署指南
|
||
|
||
### Docker Compose 部署
|
||
|
||
创建 `docker-compose.yml`:
|
||
|
||
```yaml
|
||
version: '3.8'
|
||
|
||
services:
|
||
redis:
|
||
image: redis:7-alpine
|
||
ports:
|
||
- "6379:6379"
|
||
networks:
|
||
- lingadmin
|
||
|
||
sqlserver:
|
||
image: mcr.microsoft.com/mssql/server:2022-latest
|
||
environment:
|
||
- ACCEPT_EULA=Y
|
||
- SA_PASSWORD=YourStrong!Password
|
||
ports:
|
||
- "1433:1433"
|
||
networks:
|
||
- lingadmin
|
||
|
||
api-gateway:
|
||
build:
|
||
context: .
|
||
dockerfile: ApiGateway/LingAdmin.ApiGateway/Dockerfile
|
||
ports:
|
||
- "5000:5000"
|
||
depends_on:
|
||
- redis
|
||
networks:
|
||
- lingadmin
|
||
|
||
identity-service:
|
||
build:
|
||
context: .
|
||
dockerfile: IdentityService/LingAdmin.IdentityService/Dockerfile
|
||
ports:
|
||
- "5001:5001"
|
||
depends_on:
|
||
- sqlserver
|
||
- redis
|
||
networks:
|
||
- lingadmin
|
||
|
||
authorization-service:
|
||
build:
|
||
context: .
|
||
dockerfile: AuthorizationService/LingAdmin.AuthorizationService/Dockerfile
|
||
ports:
|
||
- "5002:5002"
|
||
depends_on:
|
||
- sqlserver
|
||
- redis
|
||
networks:
|
||
- lingadmin
|
||
|
||
networks:
|
||
lingadmin:
|
||
driver: bridge
|
||
```
|
||
|
||
### Kubernetes 部署
|
||
|
||
使用 Dapr 注解部署到 Kubernetes:
|
||
|
||
```yaml
|
||
apiVersion: apps/v1
|
||
kind: Deployment
|
||
metadata:
|
||
name: identity-service
|
||
spec:
|
||
replicas: 3
|
||
selector:
|
||
matchLabels:
|
||
app: identity-service
|
||
template:
|
||
metadata:
|
||
labels:
|
||
app: identity-service
|
||
annotations:
|
||
dapr.io/enabled: "true"
|
||
dapr.io/app-id: "identity-service"
|
||
dapr.io/app-port: "5001"
|
||
spec:
|
||
containers:
|
||
- name: identity-service
|
||
image: lingadmin/identity-service:latest
|
||
ports:
|
||
- containerPort: 5001
|
||
```
|
||
|
||
---
|
||
|
||
## 📝 扩展服务
|
||
|
||
要添加新的微服务,请按照以下步骤:
|
||
|
||
1. 创建新项目,引用 `LingAdmin.Shared`
|
||
2. 配置 Dapr 组件
|
||
3. 在 `dapr.yaml` 中添加服务配置
|
||
4. 在 API Gateway 的路由配置中添加新路由
|
||
5. 实现服务间通信(使用 Dapr Service Invocation)
|
||
|
||
---
|
||
|
||
## 🤝 贡献指南
|
||
|
||
1. Fork 本仓库
|
||
2. 创建功能分支 (`git checkout -b feature/AmazingFeature`)
|
||
3. 提交更改 (`git commit -m 'Add some AmazingFeature'`)
|
||
4. 推送到分支 (`git push origin feature/AmazingFeature`)
|
||
5. 提交 Pull Request
|
||
|
||
---
|
||
|
||
## 📄 许可证
|
||
|
||
MIT License
|