我用docker swarm来部署的nacos和服务。
服务容器启动后,会有两个IP地址,一个是内置的ingress网络的地址(10.255.12.245),另外一个是我自定义的网络的地址(10.0.0.27)。
在nacos服务列表里看到,注册的服务用的IP地址都是ingress网络的IP地址,而没有用我自定义的网络的IP地址。而在sentinel和spring cloud admin中,识别出来的IP地址,都是自定义的网络地址。
我不知道这是随机出现的巧合,还是sentinel和spring cloud admin对此有特殊的处理,我尝试启动多个容器,发现结果都是这样的,nacos总是用ingress网络的IP地址,而sentinel和spring cloud admin总是用自定义网络的地址。
补充下,还出现了同一个容器中的ingress网络IP地址和自定义网络IP地址被识别为两个实例的情况。
@Jnoee 你用的什么客户端注册的服务,注册的IP是由客户端传入的,并非Nacos自己获取的
补充下,还出现了同一个容器中的ingress网络IP地址和自定义网络IP地址被识别为两个实例的情况。
不同的IP就会被视为不同的实例。
我也遇到这个问题了 nacos总是识别到docker的ip nacos能再垃圾点吗
nacos-server是作为服务发现的中心,当nacos-client注册到nacos-server,之后client之间如何通讯是根据client配置的实例ip及port决定的。ip是否可达是根据client之间的网络拓扑决定的。所以设计为client自己配置ip!
怎样解决你的问题,其实看源码之后就很简单了
以spring-cloud为例
这是spring-cloud中client配置获取自身ip的一段代码
org.springframework.cloud.alibaba.nacos.NacosDiscoveryProperties
@PostConstruct
public void init() throws SocketException {
serverAddr = Objects.toString(serverAddr, "");
endpoint = Objects.toString(endpoint, "");
namespace = Objects.toString(namespace, "");
logName = Objects.toString(logName, "");
if (StringUtils.isEmpty(ip)) {
// traversing network interfaces if didn't specify a interface
if (StringUtils.isEmpty(networkInterface)) {
ip = inetUtils.findFirstNonLoopbackHostInfo().getIpAddress();
}
else {
NetworkInterface netInterface = NetworkInterface
.getByName(networkInterface);
if (null == networkInterface) {
throw new IllegalArgumentException(
"no such interface " + networkInterface);
}
Enumeration<InetAddress> inetAddress = netInterface.getInetAddresses();
while (inetAddress.hasMoreElements()) {
InetAddress currentAddress = inetAddress.nextElement();
if (currentAddress instanceof Inet4Address
&& !currentAddress.isLoopbackAddress()) {
ip = currentAddress.getHostAddress();
break;
}
}
if (StringUtils.isEmpty(ip)) {
throw new RuntimeException("cannot find available ip from"
+ " network interface " + networkInterface);
}
}
}
this.overrideFromEnv(environment);
}
这是自动注册到nacos-server的代码
org.springframework.cloud.alibaba.nacos.NacosDiscoveryClientAutoConfiguration
/*
* Copyright (C) 2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.alibaba.nacos;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @author xiaojing
*/
@Configuration
@ConditionalOnMissingBean(DiscoveryClient.class)
@ConditionalOnNacosDiscoveryEnabled
@EnableConfigurationProperties
public class NacosDiscoveryClientAutoConfiguration {
@Bean
public DiscoveryClient nacosDiscoveryClient() {
return new NacosDiscoveryClient();
}
@Bean
@ConditionalOnMissingBean
public NacosDiscoveryProperties nacosProperties() {
return new NacosDiscoveryProperties();
}
}
要想实现你的功能你需要修改client端注册代码,重写NacosDiscoveryClientAutoConfiguration 并 设置NacosDiscoveryProperties中的信息,例如ip,网卡等
同遇到这个问题,直接Close是什么意思?
同遇到这个问题,直接Close是什么意思?
为什么close:
同遇到这个问题,直接Close是什么意思?
为什么close:
- 这是一个spring-cloud-alibaba客户端的问题,请到spring-cloud-alibaba提问;
- 这也不是一个需要修复的bug,如果你看了spring-cloud-alibaba文档,就知道可以通过指定网卡来选择注册的IP;
您的解释我认可,但issues的存在就是提供问题的路径(这个issues描述的场景还是挺具体的),我觉得上面的回答太过粗暴了,至少您上面的回复可以给后来者提供一个去spring-cloud-alibaba寻求的帮助的依据。
同遇到这个问题,直接Close是什么意思?
为什么close:
- 这是一个spring-cloud-alibaba客户端的问题,请到spring-cloud-alibaba提问;
- 这也不是一个需要修复的bug,如果你看了spring-cloud-alibaba文档,就知道可以通过指定网卡来选择注册的IP;
您的解释我认可,但issues的存在就是提供问题的路径(这个issues描述的场景还是挺具体的),我觉得上面的回答太过粗暴了,至少您上面的回复可以给后来者提供一个去spring-cloud-alibaba寻求的帮助的依据。
赞同,既然都是阿里巴巴出品的,而且选为Spring cloud alibaba的注册中心了,问题就不要这样抛来抛去,作为注册中心,不就是要来管理注册来的服务的,这样抛给客户端合适吗,而且nacos中关于多网卡选择那边也描述不清,是不是会影响注册服务的IP选择也不说清楚。
同遇到这个问题,直接Close是什么意思?
为什么close:
- 这是一个spring-cloud-alibaba客户端的问题,请到spring-cloud-alibaba提问;
- 这也不是一个需要修复的bug,如果你看了spring-cloud-alibaba文档,就知道可以通过指定网卡来选择注册的IP;
您的解释我认可,但issues的存在就是提供问题的路径(这个issues描述的场景还是挺具体的),我觉得上面的回答太过粗暴了,至少您上面的回复可以给后来者提供一个去spring-cloud-alibaba寻求的帮助的依据。
之前回复是有点草率,后续会改进,欢迎监督。
同遇到这个问题,直接Close是什么意思?
为什么close:
- 这是一个spring-cloud-alibaba客户端的问题,请到spring-cloud-alibaba提问;
- 这也不是一个需要修复的bug,如果你看了spring-cloud-alibaba文档,就知道可以通过指定网卡来选择注册的IP;
您的解释我认可,但issues的存在就是提供问题的路径(这个issues描述的场景还是挺具体的),我觉得上面的回答太过粗暴了,至少您上面的回复可以给后来者提供一个去spring-cloud-alibaba寻求的帮助的依据。
赞同,既然都是阿里巴巴出品的,而且选为Spring cloud alibaba的注册中心了,问题就不要这样抛来抛去,作为注册中心,不就是要来管理注册来的服务的,这样抛给客户端合适吗,而且nacos中关于多网卡选择那边也描述不清,是不是会影响注册服务的IP选择也不说清楚。
感谢你的建议,nacos和Spring cloud alibaba都是阿里巴巴出品的,但是也是以开源软件的形式运作的,所以请到对应的仓库提出相应的问题。
@Jnoee 同样遇到一样的问题,请问题主解决了吗?能不能分享下是怎么解决的
@Sxxjava
这个问题确实应该属于Spring cloud alibaba的问题,参考org.springframework.cloud.alibaba.nacos.NacosDiscoveryProperties的配置
如果选择固定Ip注册可以配置
spring.cloud.nacos.discovery.ip = xx
spring.cloud.nacos.discovery.port = xxx
如果选择固定网卡配置项
spring.cloud.nacos.discovery.networkInterface = xx
如果想更丰富的选择,可以使用spring cloud 的 InetUtils工具,配置项为,具体说明可以自行检索
spring.cloud.inetutils.default-hostname
spring.cloud.inetutils.default-ip-address
spring.cloud.inetutils.ignored-interfaces
spring.cloud.inetutils.preferred-networks
spring.cloud.inetutils.timeout-seconds
spring.cloud.inetutils.use-only-site-local-interfaces
@SoyMeng 谢谢,解决了
@SoyMeng 客户端获取内网ip 这个问题有解决吗?现在出现同样的问题。在linux不同服务器下部署不同服务。服务间调用不可用。
@singledemon 这个issues说的是在docker部署下的问题,大部分情况配置网卡名称就可以了,您需要自己判断是什么原因产生的。参看我上面的回答
@SoyMeng 我也出现了在linux下不同主机下docker部署的问题,我的环境是docker容器,网络使用的桥接,选网卡可以找到eth0,但是这个eth0下的ip是容器的内网ip,固定ip这方式只能让保证每个服务开一个实例,这并不太现实,所以请教您有什么其它的办法么?
@hellxz 同样遇到这个问题,解决了吗
@hellxz 同样遇到这个问题,解决了吗
我最后用的 @SoyMeng 的办法
spring.cloud.nacos.discovery.ip = xx
spring.cloud.nacos.discovery.port = xxx
加到启动容器命令里,向容器内的java程序传递ip和端口号
-Dspring.cloud.nacos.discovery.ip=xx -Dspring.cloud.nacos.discovery.port=xxx
代码中依赖com.alibaba.cloud:spring-cloud-starter-alibaba-nacos-discovery:2.1.1.RELEASE
其中nacos客户端版本是com.alibaba.nacos:nacos-client:1.1.4
nacos server使用github上1.1.4版本的tar.gz,三台本地虚拟机组成的集群,连接本地mysql,启动无异常。
nacos控制台可以正常打开和使用。
问题:注册服务时,提示连接超时,下面是日志:
java.lang.IllegalStateException: failed to req API:/nacos/v1/ns/instance after all servers([192.168.20.21:8848]) tried: failed to req API:192.168.20.21:8848/nacos/v1/ns/instance. code:500 msg: java.net.SocketTimeoutException: Read timed out
at com.alibaba.nacos.client.naming.net.NamingProxy.reqAPI(NamingProxy.java:467) ~[nacos-client-1.1.4.jar:na]
at com.alibaba.nacos.client.naming.net.NamingProxy.reqAPI(NamingProxy.java:389) ~[nacos-client-1.1.4.jar:na]
at com.alibaba.nacos.client.naming.net.NamingProxy.registerService(NamingProxy.java:191) ~[nacos-client-1.1.4.jar:na]
at com.alibaba.nacos.client.naming.NacosNamingService.registerInstance(NacosNamingService.java:207) ~[nacos-client-1.1.4.jar:na]
at com.alibaba.cloud.nacos.registry.NacosServiceRegistry.register(NacosServiceRegistry.java:63) ~[spring-cloud-alibaba-nacos-discovery-2.1.1.RELEASE.jar:2.1.1.RELEASE]
at org.springframework.cloud.client.serviceregistry.AbstractAutoServiceRegistration.register(AbstractAutoServiceRegistration.java:239) [spring-cloud-commons-2.2.0.RC1.jar:2.2.0.RC1]
at com.alibaba.cloud.nacos.registry.NacosAutoServiceRegistration.register(NacosAutoServiceRegistration.java:75) [spring-cloud-alibaba-nacos-discovery-2.1.1.RELEASE.jar:2.1.1.RELEASE]
at org.springframework.cloud.client.serviceregistry.AbstractAutoServiceRegistration.start(AbstractAutoServiceRegistration.java:138) [spring-cloud-commons-2.2.0.RC1.jar:2.2.0.RC1]
能帮忙看下这个是什么问题吗?
@CharleyCao 同样遇到这个问题,解决了吗?
@zhiyuan5 解决了。需要配置Linux本地的hosts和hostname
Most helpful comment
@SoyMeng 我也出现了在linux下不同主机下docker部署的问题,我的环境是docker容器,网络使用的桥接,选网卡可以找到eth0,但是这个eth0下的ip是容器的内网ip,固定ip这方式只能让保证每个服务开一个实例,这并不太现实,所以请教您有什么其它的办法么?