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先启动

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

相关推荐
大学生资源网20 分钟前
基于springboot的万亩助农网站的设计与实现源代码(源码+文档)
java·spring boot·后端·mysql·毕业设计·源码
苏三的开发日记30 分钟前
linux端进行kafka集群服务的搭建
后端
苏三的开发日记1 小时前
windows系统搭建kafka环境
后端
爬山算法1 小时前
Netty(19)Netty的性能优化手段有哪些?
java·后端
Tony Bai1 小时前
Cloudflare 2025 年度报告发布——Go 语言再次“屠榜”API 领域,AI 流量激增!
开发语言·人工智能·后端·golang
想用offer打牌1 小时前
虚拟内存与寻址方式解析(面试版)
java·后端·面试·系统架构
無量1 小时前
AQS抽象队列同步器原理与应用
后端
9号达人2 小时前
支付成功订单却没了?MyBatis连接池的坑我踩了
java·后端·面试
用户497357337982 小时前
【轻松掌握通信协议】C#的通信过程与协议实操 | 2024全新
后端
草莓熊Lotso2 小时前
C++11 核心精髓:类新功能、lambda与包装器实战
开发语言·c++·人工智能·经验分享·后端·nginx·asp.net