1、背景
某一日晚上,公司的一个微服务上线重启后,双节点,只有一个节点注册到了nacos服务器,另外一个节点一直在nacos界面上无法看到,两个节点的服务启动也没有报错,api网关转发给服务时,时不时有告警日志,产生熔断。
下面就来看看,如何会诞生这个问题,如何解决这个问题。
2、问题排查
(1)代码没问题,都是同一份,启动没有报错
(2)nacos服务器没有问题,能够收到一个节点的注册
(3)两个服务器有何不一样?一个机器是单网卡,一个机器是双网卡
(4)寻找spring-cloud-starter-alibaba-nacos-discovery代码中,服务注册到nacos的配置,发现ip属性,顿时悟了。
3、spring.cloud.nacos.discovery配置
打开项目引用的spring-cloud-starter-alibaba-nacos-discovery的源码,我们看看NacosDiscoveryProperties类的属性。
从类中即可看到,加载我们项目yml配置文件中的属性:spring.cloud.nacos.discovery
/**
* @author dungu.zpf
* @author xiaojing
* @author <a href="mailto:mercyblitz@gmail.com">Mercy</a>
* @author <a href="mailto:lyuzb@lyuzb.com">lyuzb</a>
* @author <a href="mailto:78552423@qq.com">eshun</a>
*/
@ConfigurationProperties("spring.cloud.nacos.discovery")
public class NacosDiscoveryProperties {
private static final Logger log = LoggerFactory
.getLogger(NacosDiscoveryProperties.class);
/**
* Prefix of {@link NacosDiscoveryProperties}.
*/
public static final String PREFIX = "spring.cloud.nacos.discovery";
private static final Pattern PATTERN = Pattern.compile("-(\\w)");
/**
* nacos discovery server address.
*/
private String serverAddr;
/**
* the nacos authentication username.
*/
private String username;
/**
* the nacos authentication password.
*/
private String password;
/**
* the domain name of a service, through which the server address can be dynamically
* obtained.
*/
private String endpoint;
/**
* namespace, separation registry of different environments.
*/
private String namespace;
/**
* watch delay,duration to pull new service from nacos server.
*/
private long watchDelay = 30000;
/**
* nacos naming log file name.
*/
private String logName;
/**
* service name to registry.
*/
@Value("${spring.cloud.nacos.discovery.service:${spring.application.name:}}")
private String service;
/**
* weight for service instance, the larger the value, the larger the weight.
*/
private float weight = 1;
/**
* cluster name for nacos .
*/
private String clusterName = "DEFAULT";
/**
* group name for nacos.
*/
private String group = "DEFAULT_GROUP";
/**
* naming load from local cache at application start. true is load.
*/
private String namingLoadCacheAtStart = "false";
/**
* extra metadata to register.
*/
private Map<String, String> metadata = new HashMap<>();
/**
* if you just want to subscribe, but don't want to register your service, set it to
* false.
*/
private boolean registerEnabled = true;
/**
* The ip address your want to register for your service instance, needn't to set it
* if the auto detect ip works well.
*/
private String ip;
}
从上面最后的属性ip看到,如果是多网卡的服务器,可以指定ip,这样可以解决不同服务器之间没有构成局域网导致服务之间无法调用的问题。
yml配置文件如下:
spring:
cloud:
nacos:
# 配置中心
config:
server-addr: 10.2.20.178:8848
file-extension: txt
namespace: "e55d034a-b71f-4c55-a31a-a085d36e6a80"
username: ""
password: ""
# 注册中心
discovery:
#指定本服务所在ip,避免多网卡导致服务注册的ip不一致,导致服务之间网络不通
ip: 10.2.19.176
server-addr: 10.2.20.178:8848
namespace: "e55d034a-b71f-4c55-a31a-a085d36e6a80"
username: ""
password: ""
最终,discovery属性下加上ip配置,重启节点服务,刷新nacos节点面板即可看到数据。
4、nacos.config需不需要加IP?
我们一起来看看源码就知道,不需要加,因为里面没有ip的属性。
打开maven引入的spring-cloud-starter-alibaba-nacos-config文件。
class NacosConfigProperties.java中,没有IP的属性,因此不需要配置。