springBoot集成Elasticsearch 報(bào)錯(cuò) Health check failed的解決
springBoot集成Elasticsearch 報(bào)錯(cuò) Health check failed
今天集成Elasticsearch 時(shí)啟動(dòng)報(bào)錯(cuò)
報(bào)錯(cuò)信息如下:
2018-11-01 20:52:51.310 INFO [hstao-supersearch,,,] 8528 --- [ main] .s.c.n.e.s.EurekaAutoServiceRegistration : Updating port to 8009 2018-11-01 20:52:51.314 INFO [hstao-supersearch,,,] 8528 --- [ main] c.i.g.hstaoSupersearchApplication : Started hstaoSupersearchApplication in 32.467 seconds (JVM running for 34.971) 2018-11-01 20:52:53.729 WARN [hstao-supersearch,,,] 8528 --- [on(6)-127.0.0.1] s.b.a.h.ElasticsearchJestHealthIndicator : Health check failed org.apache.http.conn.HttpHostConnectException: Connect to localhost:9200 [localhost/127.0.0.1, localhost/0:0:0:0:0:0:0:1] failed: Connection refused: connect at org.apache.http.impl.conn.DefaultHttpClientConnectionOperator.connect(DefaultHttpClientConnectionOperator.java:159) ~[httpclient-4.5.3.jar:4.5.3] at org.apache.http.impl.conn.PoolingHttpClientConnectionManager.connect(PoolingHttpClientConnectionManager.java:359) ~[httpclient-4.5.3.jar:4.5.3] at org.apache.http.impl.execchain.MainClientExec.establishRoute(MainClientExec.java:381) ~[httpclient-4.5.3.jar:4.5.3] at org.apache.http.impl.execchain.MainClientExec.execute(MainClientExec.java:237) ~[httpclient-4.5.3.jar:4.5.3] at org.apache.http.impl.execchain.ProtocolExec.execute(ProtocolExec.java:185) ~[httpclient-4.5.3.jar:4.5.3] at org.apache.http.impl.execchain.RetryExec.execute(RetryExec.java:89) ~[httpclient-4.5.3.jar:4.5.3] at org.apache.http.impl.execchain.RedirectExec.execute(RedirectExec.java:111) ~[httpclient-4.5.3.jar:4.5.3] at org.apache.http.impl.client.InternalHttpClient.doExecute(InternalHttpClient.java:185) ~[httpclient-4.5.3.jar:4.5.3] at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:83) ~[httpclient-4.5.3.jar:4.5.3] at org.apache.http.impl.client.CloseableHttpClient.execute(CloseableHttpClient.java:108) ~[httpclient-4.5.3.jar:4.5.3] at io.searchbox.client.http.JestHttpClient.execute(JestHttpClient.java:50) ~[jest-0.1.7.jar:na] at org.springframework.boot.actuate.health.ElasticsearchJestHealthIndicator.doHealthCheck(ElasticsearchJestHealthIndicator.java:44) ~[spring-boot-actuator-1.5.6.RELEASE.jar:1.5.6.RELEASE] at org.springframework.boot.actuate.health.AbstractHealthIndicator.health(AbstractHealthIndicator.java:43) ~[spring-boot-actuator-1.5.6.RELEASE.jar:1.5.6.RELEASE] at org.springframework.boot.actuate.health.CompositeHealthIndicator.health(CompositeHealthIndicator.java:68) [spring-boot-actuator-1.5.6.RELEASE.jar:1.5.6.RELEASE] at org.springframework.boot.actuate.endpoint.HealthEndpoint.invoke(HealthEndpoint.java:85) [spring-boot-actuator-1.5.6.RELEASE.jar:1.5.6.RELEASE] at org.springframework.boot.actuate.endpoint.HealthEndpoint.invoke(HealthEndpoint.java:35) [spring-boot-actuator-1.5.6.RELEASE.jar:1.5.6.RELEASE] at org.springframework.boot.actuate.endpoint.jmx.DataEndpointMBean.getData(DataEndpointMBean.java:46) [spring-boot-actuator-1.5.6.RELEASE.jar:1.5.6.RELEASE] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_121] at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_121] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_121] at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_121] at sun.reflect.misc.Trampoline.invoke(MethodUtil.java:71) [na:1.8.0_121] at sun.reflect.GeneratedMethodAccessor131.invoke(Unknown Source) ~[na:na] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_121] at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_121] at sun.reflect.misc.MethodUtil.invoke(MethodUtil.java:275) [na:1.8.0_121] at javax.management.modelmbean.RequiredModelMBean$4.run(RequiredModelMBean.java:1252) [na:1.8.0_121] at java.security.AccessController.doPrivileged(Native Method) [na:1.8.0_121] at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:80) [na:1.8.0_121] at javax.management.modelmbean.RequiredModelMBean.invokeMethod(RequiredModelMBean.java:1246) [na:1.8.0_121] at javax.management.modelmbean.RequiredModelMBean.invoke(RequiredModelMBean.java:1085) [na:1.8.0_121] at org.springframework.jmx.export.SpringModelMBean.invoke(SpringModelMBean.java:90) [spring-context-4.3.8.RELEASE.jar:4.3.8.RELEASE] at javax.management.modelmbean.RequiredModelMBean.getAttribute(RequiredModelMBean.java:1562) [na:1.8.0_121] at org.springframework.jmx.export.SpringModelMBean.getAttribute(SpringModelMBean.java:109) [spring-context-4.3.8.RELEASE.jar:4.3.8.RELEASE] at com.sun.jmx.interceptor.DefaultMBeanServerInterceptor.getAttribute(DefaultMBeanServerInterceptor.java:647) [na:1.8.0_121] at com.sun.jmx.mbeanserver.JmxMBeanServer.getAttribute(JmxMBeanServer.java:678) [na:1.8.0_121] at javax.management.remote.rmi.RMIConnectionImpl.doOperation(RMIConnectionImpl.java:1445) [na:1.8.0_121] at javax.management.remote.rmi.RMIConnectionImpl.access$300(RMIConnectionImpl.java:76) [na:1.8.0_121] at javax.management.remote.rmi.RMIConnectionImpl$PrivilegedOperation.run(RMIConnectionImpl.java:1309) [na:1.8.0_121] at javax.management.remote.rmi.RMIConnectionImpl.doPrivilegedOperation(RMIConnectionImpl.java:1401) [na:1.8.0_121] at javax.management.remote.rmi.RMIConnectionImpl.getAttribute(RMIConnectionImpl.java:639) [na:1.8.0_121] at sun.reflect.GeneratedMethodAccessor58.invoke(Unknown Source) ~[na:na] at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_121] at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_121] at sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:346) [na:1.8.0_121] at sun.rmi.transport.Transport$1.run(Transport.java:200) [na:1.8.0_121] at sun.rmi.transport.Transport$1.run(Transport.java:197) [na:1.8.0_121] at java.security.AccessController.doPrivileged(Native Method) [na:1.8.0_121] at sun.rmi.transport.Transport.serviceCall(Transport.java:196) [na:1.8.0_121] at sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:568) [na:1.8.0_121] at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:826) [na:1.8.0_121] at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$0(TCPTransport.java:683) [na:1.8.0_121] at java.security.AccessController.doPrivileged(Native Method) [na:1.8.0_121] at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:682) [na:1.8.0_121] at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) ~[na:1.8.0_121] at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) ~[na:1.8.0_121] at java.lang.Thread.run(Thread.java:745) ~[na:1.8.0_121] Caused by: java.net.ConnectException: Connection refused: connect
在報(bào)錯(cuò)日志中看到 Connect to localhost:9200 被拒絕,檢查代碼發(fā)現(xiàn)項(xiàng)目中并沒有 localhost:9200 的相關(guān)配置項(xiàng),繼續(xù)看上一步的日志
s.b.a.h.ElasticsearchJestHealthIndicator : Health check failed
可以看到執(zhí)行了es的healthCheck,聯(lián)想到以往集成redis也有healthCheck,便增加如下配置來試圖關(guān)掉healthCheck
management.security.health.elasticsearch.enabled=false
竟然成功了,意外收獲,Mark一下!
SpringBoot集成ElasticSearch出現(xiàn)的異常
1. 異常
在使用springboot2.2.8+elasticsearch6.8.10時(shí),測(cè)試時(shí)報(bào)錯(cuò):
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'elasticsearchClient' defined in class path resource [org/springframework/boot/autoconfigure/data/elasticsearch/ElasticsearchAutoConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.elasticsearch.client.transport.TransportClient]: Factory method 'elasticsearchClient' threw exception; nested exception is java.lang.IllegalStateException: availableProcessors is already set to [4], rejecting [4]
2. 原因
Elasticsearch 和 Redis 底層都使用到了 Netty , 在項(xiàng)目啟動(dòng)時(shí)會(huì)沖突。
涉及到的類:NettyRuntime,Netty4Util。
查看NettyRuntime類,可以看下源碼:
public final class NettyRuntime {
private static final NettyRuntime.AvailableProcessorsHolder holder = new NettyRuntime.AvailableProcessorsHolder();
public static void setAvailableProcessors(int availableProcessors) {
holder.setAvailableProcessors(availableProcessors);
}
public static int availableProcessors() {
return holder.availableProcessors();
}
private NettyRuntime() {
}
static class AvailableProcessorsHolder {
private int availableProcessors;
AvailableProcessorsHolder() {
}
synchronized void setAvailableProcessors(int availableProcessors) {
ObjectUtil.checkPositive(availableProcessors, "availableProcessors");
// 簡(jiǎn)單說明:在項(xiàng)目啟動(dòng)時(shí),redis自動(dòng)設(shè)置好Netty處理器(availableProcessors就不為0),而此時(shí)elasticsearch也啟動(dòng),發(fā)現(xiàn)Netty處理器已經(jīng)被設(shè)置好了(發(fā)現(xiàn)availableProcessors!=0)然后會(huì)報(bào)異常。無論哪一個(gè)先啟動(dòng),都會(huì)有判斷去報(bào)這樣的異常
if (this.availableProcessors != 0) {
// 看到這一句:跟上面報(bào)錯(cuò)的格式是一樣的
String message = String.format(Locale.ROOT, "availableProcessors is already set to [%d], rejecting [%d]", this.availableProcessors, availableProcessors);
throw new IllegalStateException(message);
} else {
this.availableProcessors = availableProcessors;
}
}
@SuppressForbidden(
reason = "to obtain default number of available processors"
)
synchronized int availableProcessors() {
if (this.availableProcessors == 0) {
int availableProcessors = SystemPropertyUtil.getInt("io.netty.availableProcessors", Runtime.getRuntime().availableProcessors());
this.setAvailableProcessors(availableProcessors);
}
return this.availableProcessors;
}
}
}
而 Elasticsearch 底層使用了 Netty4Util ,這個(gè)類調(diào)用NettyRuntime的方法:
public static void setAvailableProcessors(final int availableProcessors) {
// we set this to false in tests to avoid tests that randomly set processors from stepping on each other
// 而這里就是解決辦法:
final boolean set = Booleans.parseBoolean(System.getProperty("es.set.netty.runtime.available.processors", "true"));
if (!set) {
return;
}
/*
* This can be invoked twice, once from Netty4Transport and another time from Netty4HttpServerTransport; however,
* Netty4Runtime#availableProcessors forbids settings the number of processors twice so we prevent double invocation here.
*/
if (isAvailableProcessorsSet.compareAndSet(false, true)) {
// 看著,回去調(diào)用NettyRuntime的setAvailableProcessors
NettyRuntime.setAvailableProcessors(availableProcessors);
} else if (availableProcessors != NettyRuntime.availableProcessors()) {
/*
* We have previously set the available processors yet either we are trying to set it to a different value now or there is a bug
* in Netty and our previous value did not take, bail.
*/
// 看下面的格式跟報(bào)錯(cuò)的格式一樣
final String message = String.format(
Locale.ROOT,
"available processors value [%d] did not match current value [%d]",
availableProcessors,
NettyRuntime.availableProcessors());
throw new IllegalStateException(message);
}
}
3. 解決
在Netty4Util源碼可以看到,配置es.set.netty.runtime.available.processors設(shè)置為false就不會(huì)去檢查Netty處理器是否配置。
因?yàn)榈脝?dòng)的時(shí)候就得去解決沖突,所以設(shè)置在 啟動(dòng)類那
@SpringBootApplication
public class XXXApplication {
@PostConstruct
public void init() {
// 解決netty啟動(dòng)沖突的問題(主要體現(xiàn)在啟動(dòng)redis和elasticsearch)
// 可以看Netty4Util.setAvailableProcessors(..)
System.setProperty("es.set.netty.runtime.available.processors", "false");
}
public static void main(String[] args) {
SpringApplication.run(CommunityApplication.class, args);
}
}
配置在main函數(shù),調(diào)用run方法前也可以。
這個(gè)問題搞我一天時(shí)間,當(dāng)時(shí)是直接copy Netty4Util類的System… , 沒發(fā)現(xiàn)它是getProperty,導(dǎo)致還是出現(xiàn)這個(gè)異常,我真的不知道咋解決了。所以要看清楚,這里是setProperty
4. 其他注意點(diǎn)
一定要讓本地的ElasticSearch跟SpringBoot集成的es版本保持一致。否則可能會(huì)出錯(cuò)。特別是一個(gè)使用6版本和一個(gè)使用7版本。
Maven可以看SpringBoot集成的es版本:

如果需要改就在這里:pom中
<properties>
<java.version>1.8</java.version>
<!--定義elasticsearch版本依賴,保證跟本地版本一致,否則可能出錯(cuò)-->
<!-- <elasticsearch.version>7.6.2</elasticsearch.version>-->
</properties>
7版本不太熟,改動(dòng)也很大,以后有時(shí)間再升級(jí)。
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Java循環(huán)隊(duì)列與非循環(huán)隊(duì)列的區(qū)別總結(jié)
今天給大家?guī)淼氖顷P(guān)于Java的相關(guān)知識(shí)總結(jié),文章圍繞著Java循環(huán)隊(duì)列與非循環(huán)隊(duì)列的區(qū)別展開,文中有非常詳細(xì)的介紹及代碼示例,需要的朋友可以參考下2021-06-06
Java多線程并發(fā)開發(fā)之DelayQueue使用示例
這篇文章主要為大家詳細(xì)介紹了Java多線程并發(fā)開發(fā)之DelayQueue使用示例,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-09-09
本地編譯打包項(xiàng)目部署到服務(wù)器并且啟動(dòng)方式
這篇文章主要介紹了本地編譯打包項(xiàng)目部署到服務(wù)器并且啟動(dòng)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-02-02
解決java.sql.SQLException:?validateConnection?false問題的方法匯總(最
這篇文章主要給大家介紹了關(guān)于解決java.sql.SQLException:?validateConnection?false問題的方法匯總,文中通過圖文介紹的非常詳細(xì),需要的朋友可以參考下2023-03-03
java實(shí)現(xiàn)讀取txt文件并以在每行以空格取數(shù)據(jù)
今天小編就為大家分享一篇java實(shí)現(xiàn)讀取txt文件并以在每行以空格取數(shù)據(jù),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2018-07-07
java實(shí)現(xiàn)簡(jiǎn)易局域網(wǎng)聊天功能
這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)簡(jiǎn)易局域網(wǎng)聊天功能,使用UDP模式編寫一個(gè)聊天程序,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-04-04

