qindongliang1922 阅读(25) 评论(0)


最近有一个项目中用到了java api连接kafka的代码,原来测试的时候:bootstrap.servers这个值一直写的是ip,然后生产和消费数据都没有问题,但在预发测试的时候配合运维的需求,把ip要改成域名来访问,结果就启动就出问题了,启动不起来,抛出的异常如下:

DNS resolution failed for url in .......


我们的kafka的版本是apache 0.9.0.0,然后我第一时间在网上搜索看是否有相关的例子,结果没找到特别明确的问题解决办法,国内的大部分都是说需要改kafka的服务端配置文件,国外的大部分是说三个域名中,有一个域名出错导致不能连接,虽然跟我的case很像,但不是一回事,因为我确定我的三个域名都是正确的。具体可以参考这个kafka的issue:

https://issues.apache.org/jira/browse/KAFKA-2657



为了排除是环境的问题,我在自己的电脑上用虚拟机搭了一个三节点的kafka的集群,然后用域名访问,结果竟然能访问通,那就算说明域名也是没问题的,然后我对比了我自己机器上的域名和我们预发布环境的域名,发现我的预发布的域名里面包含了大写字符还有符号-和.的操作符,而我自己的域名完全是小写的英文字母加数字。然后我推测是不是加了特殊字符作为分隔符的原因,然后我分别以及联合测试了.和-组合的域名发现跟这个没关系,那最后就剩下了一种可能,域名里面包含大写字母,果然,在我测试之后发现含有大写字母的域名在kafka连接的时候截取的域名完全是错的,所以导致连接不上,故而就出现了dns解析失败的那个问题。最后把域名改成小写字母的组合后,就可以正常访问。


最后查了一下kafka的client的源码,发现用的是下面的代码方式提取域名的规则:

    private static final Pattern HOST_PORT_PATTERN = Pattern.compile(".*?\\[?([0-9a-z\\-.:]*)\\]?:([0-9]+)");

    public static String getHost(String address) {
        Matcher matcher = HOST_PORT_PATTERN.matcher(address);
        return matcher.matches() ? matcher.group(1) : null;
    }


    public static void main(String[] args) {

        System.out.println(getHost("DEV-KAFKA-03"));
        //结果是null
    }



到这里一切都清楚了,在0.9.0.0的版本是不支持大写的域名访问,最后我查了0.10.0.0的kafka的源码,发现这个bug已经修复了,所以大伙在使用的时候可以注意下这个小问题。
有什么问题可以扫码关注微信公众号:我是攻城师(woshigcs),在后台留言咨询。 技术债不能欠,健康债更不能欠, 求道之路,与君同行。