项目中将springboot的项目改造为docker环境运行,并将配置文件放入nacos中,在改造完成启动的时候,报错unknown setting [host].......和unknown setting [port].......,搜索了大量的资料也翻看了源代码,虽然没有找到错误的根本原因或者是跟其他的哪个jar包有冲突也不一定,不过也算是解决了报错问题了,就给大家分享一下
出现这个问题一般是在集成spring-boot-starter-data-elasticsearch的时候,使用了继承ElasticsearchRepository的接口导致的
首先出现这个问题的原因是在初始化TransportClient的时候没有正确获取到es的对应配置,但是在spring的配置项中并没有host和port的配置,只有cluster-nodes的配置
spring:
data:
elasticsearch:
cluster-name: elasticsearch
cluster-nodes: x.x.x.x:30936
repositories:
enabled: true
因此尝试过网上说的方法之后发现并没有用,所以就自己编写配置类采用PreBuiltTransportClient来初始化,代码如下:
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.TransportAddress;
import org.elasticsearch.transport.client.PreBuiltTransportClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.net.InetAddress;
@Configuration
@Slf4j
public class ElasticSearchConfig {
@Value("${spring.data.elasticsearch.cluster-nodes}")
private String nodes;
@Value("${spring.data.elasticsearch.cluster-name}")
private String clusterName;
@Value("${spring.data.elasticsearch.sniffTag")
private String sniffTag;
@Bean
public TransportClient getTransportClient() {
TransportClient transportClient = null;
try {
Settings settings = Settings.builder()
.put("cluster.name",clusterName)
.put("client.transport.sniff",sniffTag.equals("true") ? true : false)
.build();
transportClient = new PreBuiltTransportClient(settings);
if(sniffTag.equals("true") && nodes.contains(",")){
String[] splitNode = nodes.split(",");
for(String node : splitNode){
TransportAddress firstAddress = new TransportAddress(InetAddress.getByName(node.split(":")[0]), Integer.parseInt(node.split(":")[1]));
transportClient.addTransportAddress(firstAddress);
}
}else{
TransportAddress firstAddress = new TransportAddress(InetAddress.getByName(nodes.split(":")[0]), Integer.parseInt(nodes.split(":")[1]));
transportClient.addTransportAddress(firstAddress);
}
}catch (Exception e){
e.printStackTrace();
log.error("getTransportClient fail:{}",e);
}
return transportClient;
}
}
其中sniffTag参数是我自定义的,用来区分是节点是否是集群状态
注意:client.transport.sniff 这个一定要和节点状态保持一致,要不然会报错(true代表集群,false代表单节点)
NoNodeAvailableException[None of the configured nodes are available: [{#transport#-1}{QVFHsEVaRHiYIb
另外,如果采用了docker镜像的方式,需要在es的docker容器elasticsearch.yml配置中添加如下几个参数:
network.host: 0.0.0.0
transport.host: 0.0.0.0
http.host: 0.0.0.0
如此改造之后,程序在容器中可以正常运行,也可以读取nacos配置中心的配置信息
总结:
最后建议能不采用spring-boot-starter-data-elasticsearch就尽量不采用,直接用org.elasticsearch.client单独引入的方式自己构建