我测试 spring cliud 使用 consul 作为注册中心的时候,发现服务注册的时候,注册的都是 hostname,比如:注册了一个 commonservice,在 consul 中是这样的:
{
“ID”:”commonservice123″,
“address”:”testcommonserver”
……..
}
这肯定是不对的。加入我有一个服务 payservice 需要调用 commonservice,payservice 从 consul 中获取的 commonservice 的地址是 testcommonserver,而 payservice 所在的服务器地址是 121.57.68.98 上,这台服务器无法解析 hostname 是 testcommonserver 的服务器的 ip 地址,无法调用 commonservie,这时候就会报下面这个错误:
unKnownHostException
…….
为了解决这个问题,我需要在注册服务的时候,让服务以 ip 的方式注册,我的测试环境是:
spring cloud Finch1ey.SR2
consul v1.4.3
修改 bootstrap.yml 配置文件:
spring:
cloud:
consul:
host: xxx.xxx.xxx.xxxx
port: 8500
discovery:
prefer-ip-address: true // 这个必须配
tags: version=1.0
instance-id: ${spring.application.name}:${spring.cloud.client.ip-address}
healthCheckInterval: 15s
health-check-url: http://${spring.cloud.client.ip-address}:${server.port}/actuator/health
${spring.cloud.client.ip-address} 这个属性是 spring cloud 内置,用来获取 ip,不同的 spring cloud 版本可能稍有不同,如果想要确定自己的版本是什么样的,可以查看这个文件:HostInfoEnvironmentPostProcessor
@Override
public void postProcessEnvironment(ConfigurableEnvironment environment,
SpringApplication application) {
InetUtils.HostInfo hostInfo = getFirstNonLoopbackHostInfo(environment);
LinkedHashMap<String, Object> map = new LinkedHashMap<>();
map.put(“spring.cloud.client.hostname”, hostInfo.getHostname());
map.put(“spring.cloud.client.ip-address”, hostInfo.getIpAddress());
MapPropertySource propertySource = new MapPropertySource(
“springCloudClientHostInfo”, map);
environment.getPropertySources().addLast(propertySource);
}
这时候再启动项目测试,发现注册地址变了:
{
“ID”:”commonservice123″,
“address”:”10.52.xx.xx”
……..
}
注册的 address 变成了服务的内网地址,如果其它服务和 commonservice 在同一个网络中,可以通过内网访问,这样也是可以的,但是如果内网不能访问,其它服务仍然不能访问,这时候就需要注册服务的时候以公网的 ip 注册才行。修改 bootstrap.yml 配置文件:
spring:
cloud:
consul:
host: xxx.xxx.xxx.xxx
port: 8500
config:
data-key: data
format: yaml
discovery:
prefer-ip-address: true // 这个必须配
tags: version=1.0
instance-id: ${spring.application.name}:${spring.cloud.client.ip-address}
healthCheckInterval: 15s
health-check-url: http://${spring.cloud.client.ip-address}:${server.port}/actuator/health
inetutils:
preferred-networks:
– 公网 ip1
– 公网 ip2
可以看到增加一个 inetutils 配置,这个配置是 spring cloud 的网络工具类,这个配置的含义是如果获取 ip 时获取到多个 ip(内网、外网),就优先选择我配置的 ip 中存在的 ip,这样再测试就会发现,注册 service 的时候就变成了公网 ip。