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

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

相关推荐
韩立学长1 小时前
【开题答辩实录分享】以《智能大学宿舍管理系统的设计与实现》为例进行选题答辩实录分享
数据库·spring boot·后端
编码者卢布3 小时前
【Azure Storage Account】Azure Table Storage 跨区批量迁移方案
后端·python·flask
她说..6 小时前
策略模式+工厂模式实现审批流(面试问答版)
java·后端·spring·面试·springboot·策略模式·javaee
梦梦代码精7 小时前
开源、免费、可商用:BuildingAI一站式体验报告
开发语言·前端·数据结构·人工智能·后端·开源·知识图谱
李慕婉学姐8 小时前
【开题答辩过程】以《基于Spring Boot的疗养院理疗管理系统的设计与实现》为例,不知道这个选题怎么做的,不知道这个选题怎么开题答辩的可以进来看看
java·spring boot·后端
tb_first8 小时前
SSM速通2
java·javascript·后端
一路向北⁢8 小时前
Spring Boot 3 整合 SSE (Server-Sent Events) 企业级最佳实践(一)
java·spring boot·后端·sse·通信
风象南8 小时前
JFR:Spring Boot 应用的性能诊断利器
java·spring boot·后端
爱吃山竹的大肚肚8 小时前
微服务间通过Feign传输文件,处理MultipartFile类型
java·spring boot·后端·spring cloud·微服务
毕设源码-邱学长10 小时前
【开题答辩全过程】以 基于Springboot的酒店住宿信息管理系统的设计与实现为例,包含答辩的问题和答案
java·spring boot·后端