# xp-robotaxi-automatic-pilot-boot 代码问题分析 本文档记录了对该模块代码实现中发现的问题。 ## 严重问题(影响稳定性和性能) ### 1. Kafka 消费线程被阻塞 20 秒 (`KafkaConsumerService:1115-1118) ```java // 乘客上车确认,硬编码 sleep 20 秒 try { Thread.sleep(waittime); // waittime 默认值 20000ms = 20 秒!!! } catch (InterruptedException e) { throw new RuntimeException(e); } ``` **问题**: - 在 Kafka 消费线程中**同步阻塞 20 秒**,严重影响消费吞吐量 - 如果有多个消息连续到达,会导致消费队列严重积压 - 这是设计错误,应该用异步延迟处理,不应该阻塞消费线程 --- ### 2. 线程泄露 (两处) (`KafkaConsumerService:1395-1411`) ```java if(stringR.getCode() != Constants.SUCCESS){ // 每次推送失败都创建一个新的线程池!!! ThreadPoolExecutor executor = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>()); executor.execute(() -> { ... }); } ``` **问题**: - 每次推送失败都会创建一个新的线程池,线程创建后永远不会关闭 - 随着推送失败次数增多,会产生大量空闲线程,造成**内存泄漏** - 应该使用**共享的线程池**而不是每次创建新的 另一处在 `updateOrderStatus` 方法中也存在同样问题(在 xp-robotaxi-order-boot 中同样存在这个问题。 --- ### 3. 未捕获异常导致消费失败无限重试 多处代码直接抛出 `RuntimeException` 而不捕获: - `navigationDeviationEvent:617` - 获取地图线路失败直接抛出 - `navigationDeviationEvent:666` - 获取地图线路失败直接抛出 - `navigationDeviationEvent:721` - 获取地图线路失败直接抛出 - `buildNaviRequest:822` - 车辆位置不存在直接抛出 - `buildNaviRequest:933` - 获取地图线路失败直接抛出 - `cloudPushNavigationInfo:756` - 获取导航数据失败直接抛出 **问题**: - 如果一次失败,这个 Kafka 消息会**一直消费失败**,被无限重试,占据消费带宽 - 应该捕获异常,记日志后返回,让消费成功跳过这条坏消息 --- ## 中问题(数据一致性、潜在崩溃、安全问题) ### 1. NPE(空指针)风险 `systemStatusXpuAndReassign:484-494`: ```java // 如果 Feign 调用失败,getData() 返回 null,调用 xpOrder.getVehicleId() 会 NPE XpOrder xpOrder = xpOrderClient.queryOrderById(Long.parseLong(orderId)).getData(); vehicle = xpVehicleClient.queryById(xpOrder.getVehicleId()).getData(); ``` 同样的问题存在于多处: - `navigationDeviationEvent:602` - 获取巡游订单未判空 - `navigationDeviationEvent:625` - 获取测试订单未判空 - `navigationDeviationEvent:701` - 获取普通订单未判空 --- ### 2. 缺少幂等性处理 Kafka 保证消息至少投递一次 (`at-least-once`),但代码中: - 没有对消息去重 - 重复修改订单状态没有幂等保护 - 重复创建巡游订单可能导致**多个巡游订单被创建** - 重复推送消息给用户造成骚扰 --- ### 3. 车辆验证码校验安全问题 (`VehicleRtInfoServiceImpl:161-175) ```java // 整个车辆校验逻辑被注释掉,任何车辆都能获取验证码 // XpVehicle vehicle = xpVehicleClient.findByVehicleVin(vin).getData(); // if (vehicle == null) { // return XpCommonResponse.fail(RobotaxiErrorEnum.MOBILE_VIN_MISMATCH); // } // ... 状态校验被注释 return null; // 直接通过校验 ``` **问题**: - 不管车辆状态是否正常,都能获取验证码 - 非运营车辆也能被召车,存在安全隐患 --- ### 4. 白名单验证码绕过漏洞 (`VehicleRtInfoServiceImpl:118-133`) ```java boolean isWhitelisted = whitelistMobiles != null && whitelistMobiles.contains(request.getMobile()); // ... if (!isWhitelisted) { // 校验验证码 } else { // 白名单直接删除 key 跳过校验通过!!! redisService.deleteObject(key); } return XpCommonResponse.ok(Collections.emptyMap()); ``` **问题**: - 白名单号码**不需要输入正确验证码**就能直接通过验证 - 如果白名单手机号泄露,任何人都可以绕过验证码保护 --- ### 5. orderId 解析方式脆弱 多处使用硬编码前缀截取: ```java if (order_id.contains("XU")) { orderId = Long.parseLong(order_id.substring(2)); } else if(order_id.contains("TEST")) { orderId = Long.parseLong(order_id.substring(4)); }else{ orderId = Long.parseLong(order_id); } ``` **问题**: - 如果前缀格式变化(比如变成 "XU_" 或其他格式),会抛出 `NumberFormatException` - 如果 orderId 本身包含 "XU" 或 "TEST" 子串,会解析错误 --- ## 一般问题(代码质量、冗余) ### 1. 重复 Feign 查询,冗余网络调用 比如 `orderStateUpdateEvent:1164-1167`: ```java XpOrder xpOrder = xpOrderClient.queryOrderById(Long.valueOf(orderId)).getData(); if (Objects.nonNull(xpOrder)){ // 查询车辆 XpVehicle xpVehicle = xpVehicleClient.queryById(xpOrder.getVehicleId()).getData(); ... } ``` 在外层已经查询过一次订单,这里又查询一次,浪费一次网络IO。 --- ### 2. 缺少事务管理 整个消费流程涉及: - 修改订单状态(通过 Feign 调用 order-service) - 修改车辆状态(通过 Feign 调用 vehicle-convoy) - 发送消息推送 - 更新埋点 **问题**:如果处理到一半失败,不会回滚已经完成的操作,会导致**数据不一致**。 --- ### 3. 注释过期 (`VehicleRtInfoServiceImpl:89-90`) ```java // TODO: Call SMS interface to send code when available // sendSms(request.getMobile(), code); Map param = Collections.singletonMap("code", code); ... smsClient.pushSms(smsVo); // 实际上这里已经在发送了 ``` TODO 注释已经过期,代码实际已经实现了发送。 --- ## 问题总结 | 问题类型 | 严重程度 | 修复优先级 |---------|----------|------------| | 阻塞消费线程 (20秒) | 🔴 高 | P0 (最高) | 线程泄露 | 🔴 高 | P0 | 未捕获异常导致无限重试 | 🔴 高 | P1 | NPE 风险 | 🟠 中高 | P1 | 缺少幂等处理 | 🟠 中高 | P1 | 安全漏洞(跳过车辆校验)| 🟠 中高 | P2 | 安全漏洞(白名单绕过验证码)| 🟠 中高 | P2 | 重复冗余查询 | 🟡 中 | P2 | 缺少事务 | 🟡 中 | P2 | 脆弱的 orderId 解析 | 🟡 中 | P3 最需要优先修复的是 **"Kafka 消费线程 sleep 20秒** 和 **线程泄露** 这两个问题,它们直接影响服务稳定性。