Cn_Bin 2024-09-13 14:42 采纳率: 0%
浏览 28
问题最晚将于09月21日00:00点结题

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

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

  • 写回答

28条回答 默认 最新

  • 才华横溢caozy 2024-09-13 15:02
    关注

    以下答案是由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月13日

悬赏问题

  • ¥15 jetson nano
  • ¥15 :app:debugCompileClasspath'.
  • ¥15 windows c++内嵌qt出现数据转换问题。
  • ¥20 公众号如何实现点击超链接后自动发送文字
  • ¥15 用php隐藏类名和增加类名
  • ¥15 算法设计与分析课程的提问
  • ¥15 用MATLAB汇总拟合图
  • ¥15 智能除草机器人方案设计
  • ¥15 对接wps协作接口实现消息发送
  • ¥15 SQLite 出现“Database is locked” 如何解决?