You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

部署在Cloud Run的Spring Boot应用如何获取IPv4地址?

解决Cloud Run上Spring Boot应用获取IPv4地址的问题

核心原因

Cloud Run的网络架构基于IPv6构建,前端负载均衡会将用户的IPv4地址转换为::ffff:x.x.x.x这类IPv6映射格式,注入到X-FORWARDED-FOR请求头中。你之前添加的JVM参数-Djava.net.preferIPv4Stack=true和-Djava.net.preferIPv4Addresses=true只控制应用自身的网络栈行为,无法改变反向代理注入的请求头内容,所以无效。

可行解决方案

1. 解析IPv6映射的IPv4地址

直接从X-FORWARDED-FOR的IPv6格式中提取IPv4部分,工具类示例:

public static String getIPv4FromForwardedHeader(String forwardedFor) {
    if (forwardedFor == null) return null;
    // 处理IPv4映射的IPv6地址(前缀为::ffff:)
    if (forwardedFor.startsWith("::ffff:")) {
        return forwardedFor.substring(7);
    }
    // 直接返回标准IPv4地址(如果存在)
    if (forwardedFor.contains(".") && !forwardedFor.contains(":")) {
        return forwardedFor;
    }
    return forwardedFor;
}

调用方式:

String clientIp = getIPv4FromForwardedHeader(req.getHeader("X-FORWARDED-FOR"));

2. 处理多代理场景的IP列表

如果X-FORWARDED-FOR包含多个IP(比如经过多层代理),取第一个非本地地址后再解析:

public static String extractClientIPv4(String forwardedFor) {
    if (forwardedFor == null) return null;
    String[] ips = forwardedFor.split(",");
    for (String ip : ips) {
        String trimmedIp = ip.trim();
        // 跳过本地/内网IP,提取真实用户IP
        if (!trimmedIp.startsWith("127.") && !trimmedIp.startsWith("192.168.") && !trimmedIp.startsWith("10.")) {
            return getIPv4FromForwardedHeader(trimmedIp);
        }
    }
    return null;
}

3. 移除无效的JVM参数

既然-Djava.net.preferIPv4Stack=true和-Djava.net.preferIPv4Addresses=true对请求头无影响,建议从启动命令中移除,避免冗余配置。


内容的提问来源于stack exchange,提问作者Srinivasan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 07:34:54