默认JVM会缓存每一次DNS的查询结果,并且使缓存结果永远有效,直到你对该JVM重启为止。有时候业务需要系统能对域名切换及时而自动进行切换。这时候你就需要禁用或调整JVM的DNS缓存机制。在独立运行程序中(非容器环境),可以在应用启动的时候通过以下代码完成:
//设置解析成功的域名记录JVM中缓存的有效时间,JVM默认是永远有效,这样一来域名IP重定向必须重启JVM,这里修改为3秒钟有效,0表示禁止缓存,-1表示永远有效
//设置解析失败的域名记录JVM中缓存的有效时间,JVM默认是10秒,0表示禁止缓存,-1表示永远有效
Security.setProperty(“networkaddress.cache.negative.ttl”, “3”);
代码中设置“networkaddress.cache.ttl”值的方式只适用于非容器环境,当应用部署与resin等容器中时该设置控制不了JVM的行为。可行的办法是通过在容器的启动参数中设置JDK系统变量“sun.net.inetaddr.ttl“或“sun.net.inetaddr.negative.ttl”,该参数跟“networkaddress.cache.ttl”和“networkaddress.cache.negative.ttl”的值定义一样,只是一个用于命令行,一个用于程序内部。具体操作方法:
修改httpd.sh,在”args=”选项添加参数,如:-Dsun.net.inetaddr.ttl=0
如果非Resin容器的Java应用中同时配置了命令参数“sun.net.inetaddr.ttl”和Security属性“networkaddress.cache.ttl”,那么会以Security属性的设置为准。
一般情况下我们不需要完全取消JVM的DNS缓存,只需要调小有效时间,经过一些测试发现一下结论:
1)1个域名对应一个IP和一个域名对应12个IP,DNS查询响应时间差别极少,后者占用cpu稍高一点点;
2)在高并发时,不做DNS缓存时的CPU耗用比做了3s缓存的CPU耗用要高3/4倍,实时DNS请求相当耗用CPU;
3)3s和30s缓存有效时间对dns查询响应时间的影响差别不大,cpu内存占用都比较接近;
4)建议使用3秒缓存,兼顾运维和性能;