springcloud openfeign 偶现 Caused by: java.net.UnknownHostException

背景

最近查看日志发现某服务偶现Caused by: java.net.UnknownHostException 同时查看eureka的access.log 出现如下异常

10.xxx.xxx.xxx - - 27/May/2025:23:57:29 +0800 "PUT /eureka/apps/{appName}/{host}:xxx-job:8082?status=UP&lastDirtyTimestamp=1748351637173 HTTP/1.1" 404 -

问题关联分析

1. 问题链条

scss 复制代码
Eureka心跳续约失败(404) → 服务从注册中心下线 → 服务发现失败 → DNS解析失败 → UnknownHostException

2. 具体流程

  1. xxx-job 服务向Eureka发送心跳续约请求
  2. Eureka Server返回404,表示该服务实例不存在
  3. 经过几次失败后,Eureka Server将该服务实例从注册表中移除
  4. 其他服务调用 xxx-job 时,从Eureka获取不到该服务的实例信息
  5. Spring Cloud LoadBalancer无法解析 xxx-job 服务名
  6. 最终抛出 UnknownHostException: xxx-job

为什么会出现404错误

1. 服务注册不完整

yaml 复制代码
# 可能的配置问题
eureka:
  client:
    initial-instance-info-replication-interval-seconds: 40  # 初始注册延迟太长
    instance-info-replication-interval-seconds: 30

2. Eureka Server清理策略

yaml 复制代码
# Eureka Server可能过于激进地清理实例
eureka:
  server:
    eviction-interval-timer-in-ms: 60000  # 清理间隔
    enable-self-preservation: false       # 自我保护模式关闭

3. 网络问题导致注册失败

实例ID中的 host 可能存在DNS解析问题。

解决方案

1. 修复服务注册配置

yaml 复制代码
eureka:
  client:
    service-url:
      defaultZone: http://eureka-server:8761/eureka/
    register-with-eureka: true
    fetch-registry: true
    initial-instance-info-replication-interval-seconds: 5
    instance-info-replication-interval-seconds: 10
  instance:
    prefer-ip-address: true
    ip-address: xxx.xxx.xxx.xxx
    instance-id: ${spring.application.name}:${spring.cloud.client.ip-address}:${server.port}
    lease-renewal-interval-in-seconds: 10
    lease-expiration-duration-in-seconds: 30

2. 启用Eureka Server自我保护模式

yaml 复制代码
eureka:
  server:
    enable-self-preservation: true
    renewal-percent-threshold: 0.85
    eviction-interval-timer-in-ms: 120000

3. 添加重试机制

yaml 复制代码
# 为Feign客户端添加重试
feign:
  client:
    config:
      default:
        retryer: feign.Retryer.Default

4. 监控和诊断

java 复制代码
@Component
public class ServiceHealthMonitor {
    
    @Autowired
    private EurekaClient eurekaClient;
    
    @Scheduled(fixedRate = 30000)
    public void checkServiceHealth() {
        Application app = eurekaClient.getApplication("xxx-job");
        if (app == null || app.getInstances().isEmpty()) {
            logger.warn("xxx-job服务不可用");
        }
    }
}

5. 应急预案

java 复制代码
@Component
public class ServiceFallback {
    
    @Retryable(value = UnknownHostException.class, maxAttempts = 3)
    public String callXxxjob() {
        // 服务调用逻辑
    }
    
    @Recover
    public String recover(UnknownHostException ex) {
        logger.error("服务调用失败,启用降级策略", ex);
        return "服务暂时不可用";
    }
}

验证步骤

  1. 检查Eureka Dashboard :确认xxx-job服务是否持续在线
  2. 监控日志:观察404错误的频率和时间模式
  3. 测试网络ping host
  4. 检查服务启动顺序:确保Eureka Server先启动

这个问题的核心是服务注册中心的状态不一致,建议重点解决服务注册稳定性问题。

相关推荐
AI绘画哇哒哒6 小时前
【建议收藏!】35岁后端血泪忠告,这3类人别硬转Agent(过来人亲述)
java·人工智能·后端·ai·程序员·大模型·agent
唐青枫7 小时前
一个值多种形态:Zig union、Tagged Union 与内存布局实战
后端
卷无止境7 小时前
Windows 上丝滑开发 Python,并稳定构建 Docker 镜像
后端·python·docker
Nturmoils7 小时前
备份完不算完,先还原到临时库验一遍
后端
Csvn8 小时前
📊 SQL 入门 Day 22:视图与物化视图
后端·sql
Csvn8 小时前
🐍 Day 4: Python 控制流 — 条件、循环与推导式的艺术
后端·python
2601_953720828 小时前
【计算机毕业设计】基于Vue与Spring Boot的高校兼职信息服务平台设计与实现
spring boot·后端·课程设计
再吃一根胡萝卜10 小时前
用 Rust 写一个桌面悬浮图标:为什么它比 Python 更适合 AI 桌面工具?
后端
IT_陈寒10 小时前
Vue的computed属性把我坑惨了,原来我一直用错姿势
前端·人工智能·后端
evans在进步11 小时前
Spring Boot 核心机制详解:可执行 JAR、CORS、静态资源与配置绑定
spring boot·后端·jar