一、为什么需要这样一套系统?(背景与目标)
在 2025 年的现代软件开发环境中,企业应用面临三大核心挑战:
- 单体架构难以扩展与维护 → 需要向微服务演进
- 权限模型复杂多变 → 需要标准化 RBAC(基于角色的访问控制)
- 前后端协作效率低下 → 需要 API 标准化 + 前端工程化 + 自动化部署
本文旨在构建一个具备用户管理、角色权限控制、服务注册发现、统一网关鉴权、容器化部署能力 的完整微服务系统。该系统可作为企业级项目模板,支持快速二次开发、团队协作与生产上线。
二、整体技术架构图(含时间上下文)
截至 2025年11月 ,主流技术栈已全面拥抱 Spring Boot 3.x (基于 Jakarta EE 9+,支持 JDK 17+)和 Vue 3 Composition API。本系统采用如下架构:
┌───────────────────────┐
│ Vue 3 前端 │ ← TypeScript + Pinia + Axios + Element Plus
└──────────┬────────────┘
│ HTTP (80)
▼
┌───────────────────────┐
│ Nginx 反向代理 │ ← 静态资源 + /api 代理到网关
└──────────┬────────────┘
│ HTTP (9000)
▼
┌───────────────────────┐
│ Spring Cloud Gateway │ ← JWT 鉴权 + 路由转发(2025 年推荐方式)
└──────────┬────────────┘
│
┌───────┴───────────────────────────────┐
▼ ▼ ▼
┌─────────┐ ┌─────────┐ ┌────────────┐
│ user-svc│ │ role-svc│ │ product-svc│
└─────────┘ └─────────┘ └────────────┘
▲ ▲
└────── OpenFeign ──┘
▲
│
┌───────────────────────┐
│ Nacos │ ← 服务注册中心 + 配置中心(v2.2+)
└───────────────────────┘
┌─────────────┐ ┌─────────────┐
│ MySQL 8 │ │ Redis 7 │
└─────────────┘ └─────────────┘
✅ 技术选型依据(2025年):
- Spring Boot 3.2:支持虚拟线程(Project Loom)、GraalVM 原生镜像
- Spring Cloud Alibaba 2022.0.0.0:兼容 Spring Boot 3
- Vue 3 + Vite:构建速度比 Webpack 快 10 倍以上
- Docker Compose:本地开发与测试环境标准化
三、数据库设计(RBAC 模型)
3.1 表结构(MySQL 8)
-- 用户表
CREATE TABLE `sys_user` (
`id` BIGINT NOT NULL AUTO_INCREMENT,
`username` VARCHAR(50) UNIQUE NOT NULL COMMENT '登录名',
`password` VARCHAR(100) NOT NULL COMMENT 'BCrypt 加密',
`real_name` VARCHAR(50),
`status` TINYINT DEFAULT 1 COMMENT '1:启用 0:禁用',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- 角色表
CREATE TABLE `sys_role` (
`id` BIGINT NOT NULL AUTO_INCREMENT,
`role_code` VARCHAR(50) UNIQUE NOT NULL,
`role_name` VARCHAR(50) NOT NULL,
PRIMARY KEY (`id`)
);
-- 权限表(接口/菜单)
CREATE TABLE `sys_permission` (
`id` BIGINT NOT NULL AUTO_INCREMENT,
`perm_code` VARCHAR(100) UNIQUE NOT NULL COMMENT '如: user:delete',
`perm_name` VARCHAR(100) NOT NULL,
`url` VARCHAR(200) COMMENT '对应后端接口路径',
PRIMARY KEY (`id`)
);
-- 用户-角色关联
CREATE TABLE `sys_user_role` (
`user_id` BIGINT,
`role_id` BIGINT,
PRIMARY KEY (`user_id`, `role_id`),
FOREIGN KEY (`user_id`) REFERENCES sys_user(`id`),
FOREIGN KEY (`role_id`) REFERENCES sys_role(`id`)
);
-- 角色-权限关联
CREATE TABLE `sys_role_permission` (
`role_id` BIGINT,
`perm_id` BIGINT,
PRIMARY KEY (`role_id`, `perm_id`),
FOREIGN KEY (`role_id`) REFERENCES sys_role(`id`),
FOREIGN KEY (`perm_id`) REFERENCES sys_permission(`id`)
);
3.2 初始化数据(2025年11月5日)
-- 用户
INSERT INTO sys_user (id, username, password, real_name, status)
VALUES (1, 'admin', '123456', '系统管理员', 1);
-- 角色
INSERT INTO sys_role (id, role_code, role_name)
VALUES (1, 'ADMIN', '超级管理员'), (2, 'USER', '普通用户');
-- 权限
INSERT INTO sys_permission (id, perm_code, perm_name, url) VALUES
(1, 'user:list', '查看用户', '/api/user/list'),
(2, 'user:create', '创建用户', '/api/user/create'),
(3, 'user:delete', '删除用户', '/api/user/delete');
-- 关联
INSERT INTO sys_user_role VALUES (1, 1);
INSERT INTO sys_role_permission VALUES (1, 1), (1, 2), (1, 3);
四、后端工程结构(Maven 多模块)
microservice-parent/ # 父工程(2025-11-05 创建)
├── pom.xml
├── common/ # 公共模块
├── user-service/ # 用户服务
├── role-service/ # 角色权限服务
├── gateway-service/ # API 网关
└── docker-compose.yml # 容器编排(含当前时间戳注释)
4.1 父工程 pom.xml(Spring Boot 3.2 + Alibaba 2022)
<properties>
<java.version>17</java.version>
<spring-boot.version>3.2.0</spring-boot.version>
<spring-cloud-alibaba.version>2022.0.0.0</spring-cloud-alibaba.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${spring-cloud-alibaba.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.5</version>
</dependency>
</dependencies>
</dependencyManagement>
4.2 公共模块 common
4.2.1 统一返回体
public class Result<T> {
private Integer code = 200;
private String msg = "success";
private T data;
public static <T> Result<T> ok(T data) {
Result<T> r = new Result<>();
r.setData(data);
return r;
}
public static <T> Result<T> fail(String msg) {
Result<T> r = new Result<>();
r.setCode(500);
r.setMsg(msg);
return r;
}
public static <T> Result<T> unauthorized() {
Result<T> r = new Result<>();
r.setCode(401);
r.setMsg("Unauthorized");
return r;
}
}
4.2.2 全局异常处理
@RestControllerAdvice
public class GlobalExceptionHandler {
private static final Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class);
@ExceptionHandler(BizException.class)
public Result<?> handleBiz(BizException e) {
return Result.fail(e.getMessage());
}
@ExceptionHandler(Exception.class)
public Result<?> handleSys(Exception e) {
log.error("系统异常 @ {}", LocalDateTime.now(), e);
return Result.fail("系统繁忙,请稍后再试");
}
}
五、用户服务(user-service)核心实现
5.1 依赖(关键:LoadBalancer 必须显式引入)
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
5.2 JWT 工具类(支持黑名单)
@Component
public class JwtUtil {
private static final String SECRET = "MicroServiceSecretKey2025!";
private static final long EXPIRATION = 24 * 60 * 60 * 1000; // 24小时
public String generateToken(Long userId, String username) {
return Jwts.builder()
.setSubject(username)
.claim("userId", userId)
.setIssuedAt(new Date())
.setExpiration(new Date(System.currentTimeMillis() + EXPIRATION))
.signWith(SignatureAlgorithm.HS512, SECRET)
.compact();
}
public void logout(String token, RedisTemplate<String, String> redis) {
redis.opsForValue().set("jwt:blacklist:" + token, "1", EXPIRATION, TimeUnit.MILLISECONDS);
}
}
5.3 登录接口
@PostMapping("/login")
public Result<String> login(@RequestBody LoginDTO dto) {
SysUser user = userMapper.selectByUsername(dto.getUsername());
if (user == null || !dto.getPassword().equals(user.getPassword())) {
throw new BizException("用户名或密码错误");
}
String token = jwtUtil.generateToken(user.getId(), user.getUsername());
return Result.ok(token);
}
六、API 网关统一鉴权
6.1 路由配置
spring:
cloud:
gateway:
routes:
- id: user-api
uri: lb://user-service
predicates:
- Path=/api/user/**
6.2 全局过滤器(2025 年推荐:权限与 Token 分离)
最佳实践:网关只验证 Token 有效性,具体权限由下游服务判断(服务自治)
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
String path = exchange.getRequest().getPath().value();
if (isWhiteList(path)) return chain.filter(exchange);
String token = extractToken(exchange);
if (token == null) return unauthorized(exchange);
try {
jwtUtil.parseToken(token); // 仅验证签名与黑名单
} catch (Exception e) {
return unauthorized(exchange);
}
// 将 userId 透传给下游
Claims claims = jwtUtil.parseToken(token);
ServerHttpRequest newRequest = exchange.getRequest().mutate()
.header("X-User-Id", claims.get("userId").toString())
.build();
return chain.filter(exchange.mutate().request(newRequest).build());
}
七、前端 Vue 3 实现(2025 年标准)
7.1 权限指令(按钮级控制)
// src/directives/permission.ts
export default {
mounted(el: HTMLElement, binding: any) {
const { value: requiredPerm } = binding
const userStore = useUserStore()
if (!userStore.permissions.includes(requiredPerm)) {
el.parentNode?.removeChild(el)
}
}
}
// 使用
<el-button v-permission="'user:delete'">删除</el-button>
7.2 自动登录与 Token 管理
// stores/user.ts
const useUserStore = defineStore('user', () => {
const token = ref(localStorage.getItem('token') || '')
const permissions = ref<string[]>([])
const login = async (username: string, password: string) => {
const res = await request.post('/user/login', { username, password })
token.value = res.data
localStorage.setItem('token', token.value)
await loadUserInfo()
}
const loadUserInfo = async () => {
const res = await request.get('/role/permissions')
permissions.value = res.data
}
return { token, permissions, login, loadUserInfo }
})
八、Docker 容器化部署(含时间戳)
8.1 docker-compose.yml(2025-11-05 版本)
version: '3.8'
services:
nacos:
image: nacos/nacos-server:v2.2.3
environment:
MODE: standalone
ports: ["8848:8848"]
mysql:
image: mysql:8
environment:
MYSQL_ROOT_PASSWORD: 123456
MYSQL_DATABASE: micro_db
volumes: ["./init.sql:/docker-entrypoint-initdb.d/init.sql"]
redis:
image: redis:7
gateway:
build: ./gateway-service
ports: ["9000:9000"]
depends_on: [nacos]
user-service:
build: ./user-service
depends_on: [nacos, mysql, redis]
nginx:
image: nginx:alpine
ports: ["80:80"]
volumes:
- ./frontend/dist:/usr/share/nginx/html
- ./nginx.conf:/etc/nginx/nginx.conf
8.2 构建与启动
# 后端打包
mvn clean package -DskipTests
# 前端构建
cd frontend && npm run build
# 启动全部服务(2025年11月5日 10:16 执行)
docker-compose up -d
九、总结与演进路线(2025 年视角)
| 能力 | 当前实现 | 未来演进 |
|---|---|---|
| 服务治理 | Nacos 注册中心 | Nacos 配置中心 + 动态刷新 |
| 安全 | JWT + Redis 黑名单 | OAuth2 + OpenID Connect |
| 监控 | 无 | Prometheus + Grafana + SkyWalking |
| 部署 | Docker Compose | Kubernetes + Helm |
| 构建 | Maven + Vite | CI/CD(GitHub Actions / GitLab CI) |
十、结语
本文整合了从需求分析、架构设计、代码实现、安全控制、前后端联调到容器化部署 的完整链路。它不仅是一篇技术教程,更是一套可落地、可扩展、符合现代工程规范的企业级微服务解决方案。
真正的架构,不是堆砌技术,而是在正确的时间,用正确的工具,解决正确的问题。
附:项目结构模板(GitHub-ready)
microservice-rbac/
├── docs/
│ └── architecture.md
├── common/
├── user-service/
├── role-service/
├── gateway-service/
├── frontend/ # Vue 3 + Vite
├── docker-compose.yml # 2025-11-05 最终版
├── nginx.conf
└── README.md