从零到上线:Spring Boot 3 + Spring Cloud Alibaba + Vue 3 构建高可用 RBAC 微服务系统(超详细实战)

一、为什么需要这样一套系统?(背景与目标)

2025 年的现代软件开发环境中,企业应用面临三大核心挑战:

  1. 单体架构难以扩展与维护 → 需要向微服务演进
  2. 权限模型复杂多变 → 需要标准化 RBAC(基于角色的访问控制)
  3. 前后端协作效率低下 → 需要 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
相关推荐
cherry52302 小时前
Java大厂面试真题:Spring Boot + 微服务 + 缓存架构三轮技术拷问实录
jvm·spring boot·mysql·微服务·java面试·分布式架构·redis缓存
code_std2 小时前
SpringBoot 登录验证码
java·spring boot·后端
摇滚侠2 小时前
Spring Boot3零基础教程,响应式编程,前景提要,笔记108
java·spring boot·笔记
三口吃掉你3 小时前
微服务之网关(Spring Cloud Gateway)
java·网关·微服务·gateway
xiaohe06013 小时前
🥳 Uni ECharts 2.1 发布:正式支持鸿蒙,零成本迁移、全平台兼容、跨端开发零负担!
vue.js·uni-app·echarts
RAY_CHEN.3 小时前
vue递归组件-笔记
前端·javascript·vue.js
0小豆03 小时前
【系列开篇】从零构建智能字幕校准系统:一个AI+微服务的完整实战之旅
spring boot·python·nlp·微服务架构·实战项目·spacy·ai算法
三口吃掉你3 小时前
微服务之OpenFeign、hystrix熔断降级、loadbalancer负载均衡
hystrix·微服务·负载均衡·openfeign
ZHE|张恒3 小时前
Spring Boot 3 + Flyway 全流程教程
java·spring boot·后端