首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >Spring Boot 3.x 封装 AIOps 平台:API 设计 + RBAC 权限 + WebSocket 实时推送,附完整代码

Spring Boot 3.x 封装 AIOps 平台:API 设计 + RBAC 权限 + WebSocket 实时推送,附完整代码

作者头像
行者全栈架构师
发布2026-07-21 12:21:04
发布2026-07-21 12:21:04
320
举报

凌晨 2 点,线上告警暴增,传统运维平台只能看到密密麻麻的日志和告警,根因定位全靠人工翻日志。花了 45 分钟才定位到是一台 Redis 节点内存溢出导致级联故障。那次事故后,我下定决心要搭建一个 AI 辅助的运维平台——让告警自动聚类、根因自动推理、修复建议一键执行。

01 AIOps 平台后端架构

我负责的运维平台需要对接 40+ 台服务器的监控数据、告警规则和自动化任务,后端架构必须兼顾性能和扩展性。

核心服务职责

服务

职责

关键接口

AlertService

告警接收、分级、分发

POST /api/alerts, GET /api/alerts/{id}

TaskService

运维任务创建、调度、追踪

POST /api/tasks, PUT /api/tasks/{id}/status

MetricService

指标采集、存储、查询

GET /api/metrics/query, WS /ws/metrics

AuthService

用户认证、角色鉴权

POST /api/auth/login, GET /api/auth/permissions

图:Spring Boot 项目目录结构,清晰的模块分层

02 RESTful API 设计

告警 API 设计

为什么告警 API 要单独设计而不是复用通用 CRUD?告警有状态机(待处理→处理中→已解决)、分级策略、聚合逻辑,通用 CRUD 无法满足业务需求。

代码语言:javascript
复制
/**
 * 告警控制器
 * 支持告警创建、查询、状态流转
 */
@RestController
@RequestMapping("/api/alerts")
@Tag(name = "告警管理", description = "AIOps 告警相关接口")
publicclass AlertController {

    @Autowired
    private AlertService alertService;

    @PostMapping
    @Operation(summary = "创建告警")
    @PreAuthorize("hasRole('OPERATOR') or hasRole('ADMIN')")
    public Result<AlertVO> createAlert(
            @RequestBody @Valid AlertCreateDTO dto) {
        return Result.success(alertService.createAlert(dto));
    }

    @GetMapping("/{id}")
    @Operation(summary = "查询告警详情")
    public Result<AlertVO> getAlert(@PathVariable Long id) {
        return Result.success(alertService.getAlert(id));
    }

    @PutMapping("/{id}/status")
    @Operation(summary = "更新告警状态")
    @PreAuthorize("hasRole('OPERATOR') or hasRole('ADMIN')")
    public Result<AlertVO> updateStatus(
            @PathVariable Long id,
            @RequestBody @Valid AlertStatusUpdateDTO dto) {
        return Result.success(alertService.updateStatus(id, dto));
    }

    @GetMapping
    @Operation(summary = "分页查询告警列表")
    public Result<PageResult<AlertVO>> listAlerts(
            @Valid AlertQueryDTO query) {
        return Result.success(alertService.listAlerts(query));
    }
}

任务 API 设计

为什么任务 API 要支持回调?Hermes Agent 执行任务后需要回调更新状态,否则前端无法实时追踪任务进度。

代码语言:javascript
复制
/**
 * 任务控制器
 * 支持任务创建、调度、回调通知
 */
@RestController
@RequestMapping("/api/tasks")
publicclass TaskController {

    @Autowired
    private TaskService taskService;

    @PostMapping
    @PreAuthorize("hasRole('OPERATOR') or hasRole('ADMIN')")
    public Result<TaskVO> createTask(
            @RequestBody @Valid TaskCreateDTO dto) {
        return Result.success(taskService.createTask(dto));
    }

    @PostMapping("/callback")
    @Operation(summary = "Agent 任务回调接口")
    public Result<Void> taskCallback(
            @RequestBody TaskCallbackDTO dto,
            @RequestHeader("X-Agent-Token") String token) {
        taskService.handleCallback(dto, token);
        return Result.success();
    }
}

API 设计规范对照

规范项

要求

示例

URL 命名

小写 + 短横线

/api/alerts, /api/task-templates

HTTP 方法

CRUD 对应

GET 查询, POST 创建, PUT 更新

版本管理

URI 前缀

/api/v1/alerts, /api/v2/alerts

分页参数

统一格式

page=1&size=20&sort=createdAt,desc

错误响应

标准结构

{code, message, details}

03 RBAC 权限模型

角色设计

我设计的权限模型包含 4 个角色,覆盖运维团队常见的职责分工:

Spring Security 配置

为什么用方法级鉴权而不是 URL 级?运维平台接口多、权限细,URL 级鉴权配置冗长且难以维护,方法级鉴权更灵活。

代码语言:javascript
复制
/**
 * Spring Security 配置
 * JWT + RBAC 权限控制
 */
@Configuration
@EnableWebSecurity
@EnableMethodSecurity
publicclass SecurityConfig {

    @Autowired
    private JwtAuthenticationFilter jwtFilter;

    @Bean
    public SecurityFilterChain filterChain(
            HttpSecurity http) throws Exception {
        http
            .csrf(csrf -> csrf.disable())
            .sessionManagement(s ->
                s.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
            .authorizeHttpRequests(auth -> auth
                .requestMatchers("/api/auth/**").permitAll()
                .requestMatchers("/ws/**").permitAll()
                .requestMatchers("/api/**").authenticated()
                .anyRequest().denyAll()
            )
            .addFilterBefore(jwtFilter,
                UsernamePasswordAuthenticationFilter.class);

        return http.build();
    }

    @Bean
    public PasswordEncoder passwordEncoder() {
        return PasswordEncoderFactories
            .createDelegatingPasswordEncoder();
    }
}

权限校验 Service

代码语言:javascript
复制
/**
 * 权限校验服务
 * 支持角色检查和数据范围过滤
 */
@Service
publicclass AuthService {

    @Autowired
    private UserRoleMapper userRoleMapper;

    public boolean hasPermission(Long userId,
            String resource, String action) {
        List<String> roles = userRoleMapper
            .findRolesByUserId(userId);

        // 超级管理员直接放行
        if (roles.contains("ADMIN")) {
            returntrue;
        }

        // 查询角色-权限映射
        return userRoleMapper.existsPermission(
            roles, resource, action);
    }

    /**
     * 数据范围过滤
     * 运维工程师只能看到自己负责的服务
     */
    public List<Long> filterDataScope(Long userId) {
        return userRoleMapper.findAccessibleServiceIds(userId);
    }
}

04 WebSocket 实时推送

WebSocket 配置

为什么用 WebSocket 而不是 SSE?AIOps 场景需要双向通信——前端不仅接收实时告警,还要发送确认、执行等操作,WebSocket 更合适。

代码语言:javascript
复制
/**
 * WebSocket 配置
 * 支持告警推送和指标实时流
 */
@Configuration
@EnableWebSocketMessageBroker
publicclass WebSocketConfig implements
        WebSocketMessageBrokerConfigurer {

    @Override
    public void configureMessageBroker(
            MessageBrokerRegistry registry) {
        // 服务端推送前缀
        registry.enableSimpleBroker("/topic", "/queue");
        // 客户端发送前缀
        registry.setApplicationDestinationPrefixes("/app");
        // 用户点对点推送前缀
        registry.setUserDestinationPrefix("/user");
    }

    @Override
    public void registerStompEndpoints(
            StompEndpointRegistry registry) {
        registry.addEndpoint("/ws")
            .setAllowedOriginPatterns("*")
            .withSockJS();
    }
}

告警推送 Service

代码语言:javascript
复制
/**
 * 告警推送服务
 * 告警创建后自动推送至在线用户
 */
@Service
@Slf4j
publicclass AlertPushService {

    @Autowired
    private SimpMessagingTemplate messagingTemplate;

    /**
     * 推送告警给指定角色用户
     */
    public void pushAlert(AlertVO alert) {
        // 推送到告警主题,所有订阅者收到
        messagingTemplate.convertAndSend(
            "/topic/alerts", alert);

        // P0 级告警额外推送到运维主管
        if ("P0".equals(alert.getSeverity())) {
            messagingTemplate.convertAndSend(
                "/topic/alerts/p0", alert);
            log.warn("P0 告警推送: {}", alert.getTitle());
        }
    }

    /**
     * 推送指标数据流
     */
    public void pushMetrics(MetricVO metric) {
        messagingTemplate.convertAndSend(
            "/topic/metrics/" + metric.getServiceName(),
            metric);
    }
}

05 Hermes Agent SDK 集成

SDK 对接架构

为什么封装 SDK 而不是直接 HTTP 调用?Agent 连接需要心跳保活、断线重连、Token 刷新,SDK 封装这些底层逻辑后,业务层只需关注任务编排。

代码语言:javascript
复制
/**
 * Hermes Agent SDK 客户端
 * 封装 Agent 连接、任务下发、回调处理
 */
@Component
@Slf4j
publicclass HermesAgentClient {

    privatefinal RestTemplate restTemplate;
    privatefinal String agentBaseUrl;

    @Value("${hermes.agent.base-url}")
    private String baseUrl;

    @Value("${hermes.agent.token}")
    private String agentToken;

    public HermesAgentClient(RestTemplateBuilder builder) {
        this.restTemplate = builder
            .rootUri(baseUrl)
            .defaultHeader("X-Agent-Token", agentToken)
            .build();
    }

    /**
     * 下发任务到 Agent
     */
    public TaskResult dispatchTask(TaskDispatchDTO dto) {
        try {
            ResponseEntity<TaskResult> resp = restTemplate
                .postForEntity("/api/v1/tasks/dispatch",
                    dto, TaskResult.class);
            return resp.getBody();
        } catch (RestClientException e) {
            log.error("任务下发失败: {}", e.getMessage());
            thrownew ServiceException("任务下发失败");
        }
    }

    /**
     * 查询 Agent 健康状态
     */
    public AgentHealthVO healthCheck() {
        return restTemplate.getForObject(
            "/api/v1/health", AgentHealthVO.class);
    }
}

06 踩坑指南

坑 1:WebSocket 连接频繁断开

现象:前端 Dashboard 每隔 2-3 分钟断开一次 WebSocket,重新连接后丢失中间的告警数据。

原因:阿里云 SLB 默认 TCP 空闲超时 90 秒,长时间无消息时 SLB 主动断开连接。

解决:在服务端增加心跳机制,每 30 秒发送一次 ping:

代码语言:javascript
复制
@Scheduled(fixedRate = 30000)
public void sendHeartbeat() {
    messagingTemplate.convertAndSend(
        "/topic/heartbeat",
        Map.of("ts", System.currentTimeMillis()));
}

提醒:同时调整 SLB 的 TCP 空闲超时为 300 秒,给心跳更多容错空间。

坑 2:RBAC 权限缓存失效导致 403

现象:运维主管修改了角色权限后,相应用户仍然报 403,需要重启服务才生效。

原因:权限数据缓存在 Redis 中,修改权限后没有主动刷新缓存。

解决:权限变更时发布缓存失效事件:

代码语言:javascript
复制
@Autowired
private ApplicationEventPublisher eventPublisher;

public void refreshRolePermissions(Long roleId) {
    // 清除缓存
    redisTemplate.delete("perm:role:" + roleId);
    // 发布事件,通知所有实例刷新
    eventPublisher.publishEvent(
        new PermissionRefreshEvent(roleId));
}

提醒:多实例部署时,确保事件通过 Redis Pub/Sub 同步到所有节点。

坑 3:Agent 回调接口被重复调用

现象:日志中发现大量重复的回调请求,部分已关闭的任务被重新打开。

原因:Agent 回调接口仅校验 Token,没有幂等防重机制,网络抖动时 Agent 会重试回调。

解决:增加幂等性校验,基于 taskId + status 生成排重键:

代码语言:javascript
复制
public void handleCallback(TaskCallbackDTO dto, String token) {
    String idempotentKey = "callback:"
        + dto.getTaskId() + ":" + dto.getStatus();

    // 幂等校验:5 分钟内相同回调只处理一次
    Boolean first = redisTemplate.opsForValue()
        .setIfAbsent(idempotentKey, "1",
            Duration.ofMinutes(5));

    if (Boolean.FALSE.equals(first)) {
        log.info("忽略重复回调: {}", idempotentKey);
        return;
    }

    // 正常处理回调逻辑
    taskService.updateTaskStatus(dto);
}

提醒:Agent SDK 也需要在客户端设置合理的重试间隔(建议 5 秒起步,指数退避)。

图:Swagger OpenAPI 文档,平台所有接口统一管理

07 API 性能基准测试

接口

并发数

平均 RT

P99 RT

QPS

POST /api/alerts

50

35ms

120ms

1,200

GET /api/alerts

100

22ms

85ms

3,800

POST /api/tasks

50

48ms

150ms

850

GET /api/metrics/query

200

65ms

280ms

2,500

WS /ws/metrics

50 连接

-

-

稳定推送

测试环境:阿里云 ECS 2C4G * 2 实例 | MySQL RDS 4C8G | Redis 4G 主从版

传统运维平台 vs AIOps 平台对比

为什么需要量化对比?光看 API 性能不够直观,与传统运维平台的对比才能真正体现 AIOps 的价值。以下数据来自同一团队的实测对比。

运维场景

传统运维平台

AIOps 平台

提升幅度

告警根因定位

45min(人工翻日志)

3min(AI 自动推理)

降低 93%

重复告警处理

人工逐条确认

自动聚类合并,压缩率 75%

效率提升 4 倍

故障修复 MTTR

60min

12min(建议一键执行)

降低 80%

巡检报告生成

2h/次(手工统计)

30s 自动生成

降低 99.6%

夜间值班人力

2 人轮班

1 人 + AI 辅助

人力降低 50%

平台监控与部署配置

平台上线后需要监控服务和 API 可用性:

监控项

采集方式

更新间隔

告警阈值

严重级别

平台 API 可用性

Prometheus up

15s

== 0 持续 30s

P0

API P99 延迟

Micrometer metrics

60s

> 1s

P1

WebSocket 连接数

Spring Actuator

60s

峰值 > 200

P2

JVM 堆内存使用率

Actuator /metrics

60s

> 85%

P1

接口错误率

日志聚合

60s

> 1%

P1

数据库连接池使用率

HikariCP metrics

60s

> 80%

P2

代码语言:javascript
复制
# Systemd Service 配置 - AIOps 平台生产部署
cat > /etc/systemd/system/aiops-platform.service << 'EOF'
[Unit]
Description=AIOps Platform Backend Service
After=network.target mysql.service redis.service

[Service]
Type=simple
User=aiops
Group=aiops
WorkingDirectory=/opt/aiops-platform
ExecStart=/usr/bin/java -jar \
    -Xms4g -Xmx4g \
    -XX:+UseG1GC \
    -XX:+HeapDumpOnOutOfMemoryError \
    -Dspring.profiles.active=production \
    /opt/aiops-platform/aiops-backend.jar
ExecStop=/bin/kill -15 $MAINPID
Restart=always
RestartSec=10s
SuccessExitStatus=143

[Install]
WantedBy=multi-user.target
EOF

# Crontab 配置 - 平台维护任务
0 3 * * * /opt/scripts/platform_log_rotate.sh     # 每天凌晨日志轮转
0 4 * * 0 /opt/scripts/platform_db_backup.sh       # 每周日数据库备份
*/5 * * * * /opt/scripts/platform_health_check.sh  # 每5分钟健康检查

08 总结

本文覆盖了 AIOps 平台后端开发的四个核心环节:

  • ✅ RESTful API 设计(告警、任务、指标)
  • ✅ RBAC 权限模型与 Spring Security 集成
  • ✅ WebSocket 实时推送机制
  • ✅ Hermes Agent SDK 封装与对接

适用场景:需要从零搭建 AIOps 平台后端的中小团队

不适用场景:已有成熟运维平台仅需轻度定制的团队

💬 你在搭建运维平台后端时遇到过哪些棘手问题?欢迎评论区交流~ 💡 下期预告:Vue3 打造 AIOps Dashboard——实时监控面板的开发实战,从数据可视化到交互设计全流程拆解。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2026-07-20,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 行者架构谈 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 01 AIOps 平台后端架构
    • 核心服务职责
  • 02 RESTful API 设计
    • 告警 API 设计
    • 任务 API 设计
    • API 设计规范对照
  • 03 RBAC 权限模型
    • 角色设计
    • Spring Security 配置
    • 权限校验 Service
  • 04 WebSocket 实时推送
    • WebSocket 配置
    • 告警推送 Service
  • 05 Hermes Agent SDK 集成
    • SDK 对接架构
  • 06 踩坑指南
    • 坑 1:WebSocket 连接频繁断开
    • 坑 2:RBAC 权限缓存失效导致 403
    • 坑 3:Agent 回调接口被重复调用
  • 07 API 性能基准测试
    • 传统运维平台 vs AIOps 平台对比
    • 平台监控与部署配置
  • 08 总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档