springBoot集成Elasticsearch 報錯 Health check failed
今天集成Elasticsearch 時啟動報錯
報錯信息如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
|
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 |
在報錯日志中看到 Connect to localhost:9200 被拒絕,檢查代碼發現項目中并沒有 localhost:9200 的相關配置項,繼續看上一步的日志
s.b.a.h.ElasticsearchJestHealthIndicator : Health check failed
可以看到執行了es的healthCheck,聯想到以往集成redis也有healthCheck,便增加如下配置來試圖關掉healthCheck
1
|
management.security.health.elasticsearch.enabled= false |
竟然成功了,意外收獲,Mark一下!
SpringBoot集成ElasticSearch出現的異常
1. 異常
在使用springboot2.2.8+elasticsearch6.8.10時,測試時報錯:
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 , 在項目啟動時會沖突。
涉及到的類:NettyRuntime,Netty4Util。
查看NettyRuntime類,可以看下源碼:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
|
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" ); // 簡單說明:在項目啟動時,redis自動設置好Netty處理器(availableProcessors就不為0),而此時elasticsearch也啟動,發現Netty處理器已經被設置好了(發現availableProcessors!=0)然后會報異常。無論哪一個先啟動,都會有判斷去報這樣的異常 if ( this .availableProcessors != 0 ) { // 看到這一句:跟上面報錯的格式是一樣的 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 ,這個類調用NettyRuntime的方法:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
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)) { // 看著,回去調用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. */ // 看下面的格式跟報錯的格式一樣 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設置為false就不會去檢查Netty處理器是否配置。
因為得啟動的時候就得去解決沖突,所以設置在 啟動類那
1
2
3
4
5
6
7
8
9
10
11
12
|
@SpringBootApplication public class XXXApplication { @PostConstruct public void init() { // 解決netty啟動沖突的問題(主要體現在啟動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函數,調用run方法前也可以。
這個問題搞我一天時間,當時是直接copy Netty4Util類的System… , 沒發現它是getProperty,導致還是出現這個異常,我真的不知道咋解決了。所以要看清楚,這里是setProperty
4. 其他注意點
一定要讓本地的ElasticSearch跟SpringBoot集成的es版本保持一致。否則可能會出錯。特別是一個使用6版本和一個使用7版本。
Maven可以看SpringBoot集成的es版本:
如果需要改就在這里:pom中
1
2
3
4
5
|
< properties > < java.version >1.8</ java.version > <!--定義elasticsearch版本依賴,保證跟本地版本一致,否則可能出錯--> <!-- <elasticsearch.version>7.6.2</elasticsearch.version>--> </ properties > |
7版本不太熟,改動也很大,以后有時間再升級。
以上為個人經驗,希望能給大家一個參考,也希望大家多多支持服務器之家。
原文鏈接:https://blog.csdn.net/u012480148/article/details/89919568