做HBase项目,需要配置hosts,,此hosts其实对应了zookeeper的地址,在本地运行很方便,自己直接配置本地文件hosts就可以(或者电脑权限受限不能修改本地的hosts文件)。但是项目要上线发布,其他团队成员要使用等等,我是否都要告诉他们怎么配置hosts问题,这样太麻烦,因此我试着寻求另一种解决方案。
如果在不同的运行环境访问不同的数据源服务器,为了方便切换是否使用域名替代IP?如果使用域名的话,在开发环境就需要配置hosts文件。我希望可以不用修改hosts文件就可直接运行程序。通过我的努力,终于找到了javahost(JVM虚拟DNS)来帮我解决这些烦恼。
引入依赖
<dependency>
<groupId>io.leopard</groupId>
<artifactId>javahost</artifactId>
<version>0.9.12</version>
</dependency>
因为项目是springcloud 项目,所以我们也使用了configserver。因此可以方便的在git上更改对应服务的配置信息。我这里就是打算将hosts信息配置在 git上的配置文件中。
application.properties
# 省略其他配置
dns.resolve.zk.kanyun.zk01.com=10.11.12.32
dns.resolve.zk.kanyun.zk02.com=10.11.12.33
dns.resolve.zk.kanyun.zk03.com=10.11.12.34
# 省略其他配置
可以看到上面我配置了三个域名对应的ip地址,为什么一个zk要配置多个地址呢?因为实际上zookeeper是组成的一个集群。同时上面的配置最终会变成一个Map<String,String>结构。可以参照 链接
接下来我们就需要引入配置了。
import io.leopard.javahost.JavaHost;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import java.io.IOException;
import java.net.InetAddress;
import java.util.Map;
@Slf4j
@Component
@ConfigurationProperties(prefix = "dns.resolve")
public class DnsConfiguration {
/**
* 这里的zk也要跟配置文件中的配置一致
* 如 需要配置多个域名 则在配置文件中配置
* dns.resolve.zk.aabb.com=192.168.1.1
* dns.resolve.zk.ccdd.com=192.168.1.2
* dns.resolve.zk.eeff.com=192.168.1.3
*/
private Map<String, String> zk;
public Map<String, String> getZk() {
return zk;
}
public void setZk(Map<String, String> zk) {
this.zk = zk;
}
public void handler() {
// 业务代码......
if (zk != null && !zk.isEmpty()) {
// 设置域名解析
JavaHost.updateVirtualDns(zk);
for (String host : zk.keySet()) {
try {
// ping 命令,设置超时时间为30秒
boolean status = InetAddress.getByName(host).isReachable(30);
// ping 的结果
log.info("Test Ping Host: [{}] result: [{}]", host, status);
} catch (IOException e) {
log.error("Test Ping Host: [{}] exception: ", host, e);
}
}
}
// 业务代码....
}
}
需要注意的是:上面的代码 @Component / @ConfigurationProperties注解 和 成员变量 zk 的set/get方法 是缺一不可的 。
需要注意的是,在配置域名解析时,域名一定要小写。
对照上面的实例 就是 dns.resolve.zk.kanyun.zk01.com 是小写,如果这里配置的是大写,则会造成解析失败。当去访问域名的时候报UnknownHostException 或者 Name does not resolve。
所以一定要配置成小写,当配置成小写后,访问 大写的域名也是可以解析的到的!