20 KiB
20 KiB
LingAdmin 分布式微服务架构
基于 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 # 发布订阅配置
🚀 快速开始
前置要求
-
.NET 8 SDK
winget install Microsoft.DotNet.SDK.8 -
Dapr CLI
powershell -Command "iwr -useb https://raw.githubusercontent.com/dapr/cli/master/install/install.ps1 | iex" dapr init -
Docker Desktop (用于 Redis)
winget install Docker.DockerDesktop -
SQL Server
winget install Microsoft.SQLServer.2022.Developer
安装步骤
-
克隆项目并还原依赖
cd Backend/Services dotnet restore LingAdmin.Microservices.sln -
配置数据库连接
修改各服务的
appsettings.Development.json:{ "ConnectionStrings": { "DefaultConnection": "Server=localhost;Database=<ServiceDB>;Trusted_Connection=True;TrustServerCertificate=True;" } } -
创建数据库迁移
# Identity Service cd IdentityService/LingAdmin.IdentityService dotnet ef migrations add InitialCreate # Authorization Service cd ../../AuthorizationService/LingAdmin.AuthorizationService dotnet ef migrations add InitialCreate -
启动 Redis
docker run -d --name redis -p 6379:6379 redis:latest -
启动所有服务
cd Backend/Services .\start-all.ps1或者使用 Dapr CLI:
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 (通过网关访问)
用户注册
POST /api/auth/register
Content-Type: application/json
{
"name": "张三",
"email": "zhangsan@example.com",
"password": "Password@123"
}
用户登录
POST /api/auth/login
Content-Type: application/json
{
"email": "zhangsan@example.com",
"password": "Password@123",
"rememberMe": true
}
响应:
{
"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
POST /api/auth/refresh-token
Content-Type: application/json
{
"refreshToken": "your-refresh-token"
}
角色权限 API
获取所有角色
GET /api/roles
Authorization: Bearer <access-token>
分配角色给用户
POST /api/roles/assign
Authorization: Bearer <access-token>
Content-Type: application/json
{
"userId": 1,
"roleIds": [2, 3]
}
获取用户权限
GET /api/authorization/users/{userId}/permissions
🔗 Dapr 集成
服务调用
服务之间通过 Dapr 进行调用:
// 从 Identity Service 调用 Authorization Service
var permissions = await _daprClient.InvokeMethodAsync<UserPermissionsDto>(
HttpMethod.Get,
"authorization-service", // 目标服务的 App ID
$"api/authorization/users/{userId}/permissions");
事件发布
// 发布用户创建事件
await _daprClient.PublishEventAsync(
"pubsub", // PubSub 组件名
"user-created", // 主题名
new UserCreatedEvent { UserId = user.Id, Email = user.Email });
事件订阅
[Topic("pubsub", "user-created")]
[HttpPost("events/user-created")]
public async Task HandleUserCreated(UserCreatedEvent @event)
{
// 处理用户创建事件
await _roleService.AssignRolesToUserAsync(@event.UserId, new[] { 3 }); // 分配默认角色
}
状态存储
// 保存状态
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 刷新机制
- Access Token 过期后,使用 Refresh Token 获取新的 Token 对
- Refresh Token 使用后立即失效(轮换机制)
- 密码修改后所有 Refresh Token 自动失效
🚢 部署指南
Docker Compose 部署
创建 docker-compose.yml:
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:
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
📝 扩展服务
要添加新的微服务,请按照以下步骤:
- 创建新项目,引用
LingAdmin.Shared - 配置 Dapr 组件
- 在
dapr.yaml中添加服务配置 - 在 API Gateway 的路由配置中添加新路由
- 实现服务间通信(使用 Dapr Service Invocation)
🤝 贡献指南
- Fork 本仓库
- 创建功能分支 (
git checkout -b feature/AmazingFeature) - 提交更改 (
git commit -m 'Add some AmazingFeature') - 推送到分支 (
git push origin feature/AmazingFeature) - 提交 Pull Request
📄 许可证
MIT License