微服务负载均衡导致新增的字段时有时无的问题排查与解决/(ㄒoㄒ)/~~

📋 问题描述

现象

  • 问题:8个新添加的字段在页面刷新后时有时无
  • 环境:本地测试正常,服务器部署后出现问题
  • 特点:后端API直接测试正常,通过网关访问时出现间歇性问题

技术栈

  • 后端:Spring Boot + Spring Cloud + Nacos
  • 网关:Spring Cloud Gateway
  • 服务发现:Nacos Discovery
  • ORM:MyBatis-Plus
  • 序列化:Jackson

🔍 排查过程

阶段一:怀疑后端代码问题

1. 检查 MyBatis-Plus 字段映射

尝试

  • 检查 @TableField 注解
  • 检查 MyBatis-Plus 全局字段策略配置
  • 添加 call-setters-on-nulls: true 配置

结果:❌ 不是原因

2. 检查 Jackson 序列化配置

尝试

java 复制代码
// 在实体类上添加注解
@JsonInclude(JsonInclude.Include.ALWAYS)
public class Shops implements Serializable {
    // ...
}
yaml 复制代码
# application.yml
spring:
  jackson:
    default-property-inclusion: always
    serialization:
      write-null-map-values: true
    deserialization:
      fail-on-unknown-properties: false

遇到的问题

  • 初始配置中使用了无效的配置项 write-nulls-as-null: true,导致启动失败
  • 修复后配置正确,但问题仍然存在

结果:❌ 配置正确,但问题仍存在

3. 检查 JAR 包打包问题

发现的问题

xml 复制代码
<!-- pom.xml 缺少 spring-boot-maven-plugin -->
<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>

错误信息

复制代码
no main manifest attribute, in chqm-0.0.1-SNAPSHOT.jar

修复:添加插件后重新打包

结果:✅ JAR包正常,但问题仍存在


阶段二:发现环境差异

4. 直接测试后端 API

测试命令

bash 复制代码
# 在服务器上直接调用API
curl -X GET "http://localhost:9090/shops/xxxx"

结果:✅ API响应包含所有8个字段

结论:后端代码和配置都是正确的,问题不在后端

5. 检查 Nacos 配置

发现

yaml 复制代码
spring:
  config:
    import:
      - nacos:chqm-server.yaml

怀疑:Nacos配置可能覆盖了本地配置

结果:需要进一步检查


阶段三:定位根本原因 🎯

6. 检查 Nacos 服务实例

关键发现

bash 复制代码
# 检查Nacos中的服务实例
curl -s "http://xxxx.xxxx.xxxx.xxxx:8848/nacos/v1/ns/instance/list?serviceName=chqm-server&namespaceId=public"

结果 :发现Nacos中注册了3个 chqm-server 实例:

  • xxxx.xxxx.xxxx.xxxx:9090 ❌ 旧版本
  • xxxx.xxxx.xxxx.xxxx:9090 ❌ 旧版本
  • xxxx.xxxx.xxxx.xxxx:9090 ✅ 最新版本

网关配置

yaml 复制代码
spring:
  cloud:
    gateway:
      routes:
        - id: chqm_route
          uri: lb://xxxx-server  # 负载均衡
          predicates:
            - Path=/xxxx/**

问题根源

  • 网关使用 lb://xxxx-server 进行负载均衡
  • 请求被随机分发到3个实例
  • 部分实例是旧版本,不包含新字段
  • 导致刷新时可能路由到不同实例,字段时有时无

✅ 解决方案

步骤1:停止其他服务器上的服务

bash 复制代码
# 在服务器A上
pkill -9 -f xxxx-0.0.1-SNAPSHOT.jar

# 在服务器B上
pkill -9 -f xxxx-0.0.1-SNAPSHOT.jar

步骤2:从 Nacos 注销多余实例

bash 复制代码
# 等待ephemeral实例自动注销(心跳超时15-30秒)
# 或手动注销
curl -X DELETE "http://xxxx.xxxx.xxxx.xxxx:8848/nacos/v1/ns/instance?serviceName=xxxx-server&ip=xxxx.xxxx.xxxx.xxxx&port=9090&namespaceId=public&ephemeral=true" -u xxxx:xxxx

curl -X DELETE "http://xxxx.xxxx.xxxx.xxxx:8848/nacos/v1/ns/instance?serviceName=xxxx-server&ip=xxxx.xxxx.xxxx.xxxx&port=9090&namespaceId=public&ephemeral=true" -u xxxx:xxxx

步骤3:验证结果

bash 复制代码
# 检查实例列表(应该只剩下最新版本的实例)
curl -s "http://xxxx.xxxx.xxxx.xxxx:8848/nacos/v1/ns/instance/list?serviceName=xxxx-server&namespaceId=public" | grep -o '"ip":"[^"]*"' | sort | uniq

最终结果

  • ✅ Nacos中只剩下最新版本的实例
  • ✅ 所有请求都路由到最新版本的服务
  • ✅ 前端刷新后,8个字段稳定出现

💡 技术要点总结

1. 微服务负载均衡机制

yaml 复制代码
# Spring Cloud Gateway 使用 lb:// 进行负载均衡
uri: lb://xxxx-server
  • lb:// 表示使用负载均衡
  • 请求会被分发到所有注册的实例
  • 如果实例版本不一致,会导致行为不一致

2. Nacos 服务注册机制

  • Ephemeral 实例:服务停止后会自动注销(心跳超时)
  • 健康检查:不健康的实例会被标记,但可能仍会被路由
  • 实例管理:可以通过API手动注销或禁用实例

3. 版本一致性的重要性

  • 多实例部署时,必须确保所有实例版本一致
  • 新版本部署时,应该先停止旧版本,再启动新版本
  • 或者使用灰度发布策略,逐步替换实例

🛡️ 预防措施

1. 部署前检查清单

  • 检查所有服务器上的服务版本是否一致
  • 检查Nacos中的服务实例数量
  • 确认所有实例都是最新版本

2. 监控和告警

  • 定期检查Nacos中的服务实例数量
  • 监控服务版本信息
  • 设置告警,当实例数量异常时通知

3. 部署策略

  • 蓝绿部署:先部署新版本,验证后切换流量
  • 灰度发布:逐步替换实例,降低风险
  • 版本标签:使用版本标签区分不同版本

4. 健康检查

  • 确保负载均衡只路由到健康的实例
  • 配置合理的健康检查间隔
  • 及时下线不健康的实例

🔗 相关资源


📝 后记

这个问题从发现到解决,经历了从代码排查到环境排查的完整过程。最终发现是微服务架构中常见的版本一致性问题。这个案例提醒我们:

  1. 不要忽视环境差异:本地正常不代表生产环境正常
  2. 系统化排查很重要:按照逻辑顺序排查,避免盲目尝试
  3. 微服务架构需要更细致的运维:版本管理、实例监控都很重要

希望这个案例能帮助遇到类似问题的开发者快速定位和解决问题!

注意 :本文档中的IP地址、服务器信息等敏感信息已用 xxxx 替代,实际使用时请替换为真实信息。

相关推荐
刘一说1 小时前
Nacos 配置加载优先级详解:Spring Cloud Alibaba 微服务配置管理的核心机制
微服务·云原生·架构
曾经的三心草1 小时前
微服务的编程测评系统-linux部署指令
linux·微服务·架构
v***44671 小时前
【语义分割】12个主流算法架构介绍、数据集推荐、总结、挑战和未来发展
算法·架构
逻极1 小时前
从单体到微服务:我们如何将Python Web应用性能提升3倍
python·微服务·web
y***n6141 小时前
SpringCloud系列教程:微服务的未来(十四)网关登录校验、自定义过滤器GlobalFilter、GatawayFilter
java·spring cloud·微服务
z***3351 小时前
SpringCloud 系列教程:微服务的未来(二)Mybatis-Plus的条件构造器、自定义SQL、Service接口基本用法
spring cloud·微服务·mybatis
豆奶特浓61 小时前
谢飞机迎战金融风控面试:从Spring WebFlux、Elasticsearch到AI模型,他能扛住吗?
java·elasticsearch·微服务·ai·面试·spring webflux·金融风控
l***91471 小时前
电池管理系统(BMS)架构详细解析:原理与器件选型指南
架构
ChrisitineTX1 小时前
万字硬核拆解:Gemini 3.0 架构革新,多模态原生模型的天花板被捅破了?(1)
人工智能·架构