Cn_Bin 2024-09-13 14:42 采纳率: 0%
浏览 59
已结题

curl 命令调用正常,程序调用报 java.net.ConnectException: connection refused

您好,在您的这篇博客中(【DNS缓存】解决:curl 命令调用正常,程序调用报 java.net.ConnectException: connection refused)
我也遇到了一样的问题,有点疑问请问下您。
您最后的解决方案是调用url前执行代码Security.setProperty("networkaddress.cache.ttl","0")和增加域名白名单么?
这个域名白名单是在我们部署代码的服务器里加么?

  • 写回答

29条回答 默认 最新

  • 才华横溢caozy 2024-09-13 15:02
    关注
    获得0.15元问题酬金

    以下答案是由GPT4-pro回答,本人整理后的结果,如有帮助,还请采纳!

    问题背景

    在开发过程中,常见的一个问题是:使用 curl 命令可以正常访问某个 URL,但在 Java 程序中却出现 java.net.ConnectException: Connection refused 错误。这种问题通常与 DNS 缓存机制有关,因为 Java 默认会缓存 DNS 解析结果,导致程序使用了错误或过期的 IP 地址。

    问题原因分析

    1. DNS 缓存导致的问题:Java 虚拟机(JVM)内部会对 DNS 解析结果进行缓存,这样在调用域名时,程序会使用缓存中的 IP 地址,而不是实时解析最新的 IP 地址。这就可能导致 IP 地址不一致的问题,从而产生连接失败的情况。
    2. 网络配置或防火墙设置:服务器的网络配置、DNS 设置、或防火墙规则可能也会导致此类问题。在 curl 正常的情况下,问题很有可能出在 JVM 的 DNS 缓存或程序内部的配置上。

    解决方案

    针对以上问题,可以采取以下几种方法解决:

    1. 修改 JVM 的 DNS 缓存设置

    首先,考虑修改 JVM 内部 DNS 缓存策略,让程序在每次请求时都重新解析域名,这可以避免 DNS 缓存引起的连接拒绝问题。

    代码实现

    在程序启动时添加以下代码:

    // 设置 DNS 缓存时间为 0,即不缓存 DNS 结果
    java.security.Security.setProperty("networkaddress.cache.ttl", "0");
    

    这段代码的作用是告诉 JVM,不要缓存 DNS 结果,每次都进行新的 DNS 解析。这种做法适用于开发环境或调试阶段,避免由于缓存导致的域名解析错误。

    2. 增加域名白名单

    增加域名白名单是在 DNS 缓存配置失效的情况下,或者当你的应用受到网络代理、负载均衡器等影响时的一种补救措施。

    操作步骤

    1. 配置 hosts 文件:在部署代码的服务器中,手动配置域名与 IP 地址的映射,确保服务器可以正确解析到所需的 IP 地址。

      编辑 /etc/hosts 文件(Linux 系统),添加域名映射,例如:

      192.168.1.100 yourdomain.com
      

      这种做法强制域名解析为特定的 IP,解决 DNS 缓存的问题。

    2. 防火墙与网络代理配置:确认服务器的防火墙或网络代理是否有针对性的域名或 IP 拦截,确保应用服务器与目标地址之间的连通性。

    3. 使用 DNS 服务提供商,设置负载均衡

    如果问题在生产环境中频繁出现,可以考虑引入第三方 DNS 服务(如阿里云、腾讯云的 DNS 解析服务),通过专业 DNS 服务商的动态解析和负载均衡能力来减少 IP 变动对程序的影响。

    配置方式

    • 修改域名的 DNS 解析服务为第三方 DNS,确保解析过程稳定且有冗余。
    • 使用 DNS 负载均衡服务,确保解析到的 IP 地址是当前可用的。

    4. 确认网络和防火墙配置

    确保应用服务器所在网络与目标服务器之间没有防火墙阻断,或者网络代理阻断。检查以下网络配置:

    • 确认目标服务器的端口是否开放。
    • 确认应用程序所在服务器的出站请求是否被防火墙策略阻断。
    • 确认代理服务器配置没有异常。

    5. 使用系统级别的 DNS 缓存清理

    在一些复杂的网络环境中,系统级的 DNS 缓存可能影响应用访问。可以通过以下命令清理系统缓存:

    • Linux

      sudo systemd-resolve --flush-caches
      
    • Windows

      ipconfig /flushdns
      

    这些命令清理系统级 DNS 缓存,可以确保下次访问时重新解析域名。

    代码示例

    以下是一个综合性的代码示例,展示如何在 Java 中调整 DNS 缓存设置,并确保访问正常:

    import java.net.HttpURLConnection;
    import java.net.URL;
    
    public class DNSConnectionExample {
        public static void main(String[] args) {
            // 设置 DNS 缓存时间为 0
            java.security.Security.setProperty("networkaddress.cache.ttl", "0");
            
            try {
                // 定义目标 URL
                URL url = new URL("http://yourdomain.com");
                // 打开连接
                HttpURLConnection connection = (HttpURLConnection) url.openConnection();
                // 设置请求方法
                connection.setRequestMethod("GET");
                // 获取响应码
                int responseCode = connection.getResponseCode();
                
                if (responseCode == 200) {
                    System.out.println("连接成功");
                } else {
                    System.out.println("连接失败,响应码:" + responseCode);
                }
            } catch (Exception e) {
                // 打印错误信息
                System.out.println("连接异常:" + e.getMessage());
            }
        }
    }
    

    总结

    1. 调整 DNS 缓存设置:通过 Security.setProperty("networkaddress.cache.ttl", "0") 来避免 DNS 缓存问题。

    2. 手动配置 hosts 文件:强制域名解析,确保域名正确指向。

    3. 检查网络配置和防火墙设置:排除网络配置问题。

    4. 使用专业 DNS 服务:通过第三方 DNS 服务商确保解析过程稳定。

    这些方法结合起来可以有效解决 curl 正常而程序异常的 DNS 解析问题,提高程序的连接稳定性。

    评论

报告相同问题?

问题事件

  • 系统已结题 9月21日
  • 创建了问题 9月13日

悬赏问题

  • ¥15 微信小程序 用oss下载 aliyun-oss-sdk-6.18.0.min client报错
  • ¥15 ArcGIS批量裁剪
  • ¥15 labview程序设计
  • ¥15 为什么在配置Linux系统的时候执行脚本总是出现E: Failed to fetch http:L/cn.archive.ubuntu.com
  • ¥15 Cloudreve保存用户组存储空间大小时报错
  • ¥15 伪标签为什么不能作为弱监督语义分割的结果?
  • ¥15 编一个判断一个区间范围内的数字的个位数的立方和是否等于其本身的程序在输入第1组数据后卡住了(语言-c语言)
  • ¥15 Mac版Fiddler Everywhere4.0.1提示强制更新
  • ¥15 android 集成sentry上报时报错。
  • ¥15 抖音看过的视频,缓存在哪个文件