YAZONG 我的开源

“Error creating bean with name ‘healthEndpoint”和”nested exception is java.lang.IllegalStateException: availableProcessors is already set to [4], rejecting [4]”

  ,
0 评论0 浏览

springboot2.1.0项目里整合了redis、mongodb、elasticsearch、mysql、(现在推测再次加入其他中间件也会有下述问题)。启动报下述错误

Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException:
Error creating bean with name ‘healthEndpoint’ defined in class path resource [org/springframework/boot/actuate/autoconfigure/health/HealthEndpointConfiguration.class]:

Unsatisfied dependency expressed through method ‘healthEndpoint’ parameter 1;
nested exception is org.springframework.beans.factory.BeanCreationException:
Error creating bean with name ‘healthIndicatorRegistry’ defined in class path resource [org/springframework/boot/actuate/autoconfigure/health/HealthIndicatorAutoConfiguration.class]:
Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException:
Failed to instantiate [org.springframework.boot.actuate.health.HealthIndicatorRegistry]: Factory method ‘healthIndicatorRegistry’ threw exception;
nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException:
Error creating bean with name ‘org.springframework.boot.actuate.autoconfigure.elasticsearch.ElasticSearchClientHealthIndicatorAutoConfiguration’:
Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException:
Error creating bean with name ‘transportClient’ defined in class path resource [com/idengyun/springboot/conf/elasticsearch/conf/ElasticsearchClientConf.class]:
Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException:
Failed to instantiate [org.elasticsearch.client.transport.TransportClient]: Factory method ‘getTransportClient’ threw exception;
nested exception is java.lang.IllegalStateException: availableProcessors is already set to [4], rejecting [4]

刚开始的解决方案是删除除了elasticsearch的上述所有技术栈,可以正常启动,最后加入redis就不行了,刚开始以为redis某个加载类有冲突,在所有的redis启动配置类中加入@lazy懒加载尝试下也没解决此问题。

然后是在main启动中加入了:System.setProperty(“es.set.netty.runtime.available.processors”, “false”);,解决问题。

可是发现这样并没有实际解决这个问题,再次认真仔细的看了下错误,发现了第二行的黑色字体,又发现了红色字体,突然想到我现在只使用了springboot的基本功能,而并没有使用其监控功能,遂想到pom.xml中配置了
监控的jar包,如下:

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

且监控中应该融入了elasticsearch的监控功能。
接着注释此配置,并且把在main方法中加入的设置false的内容去掉,融入上述所有技术栈,包括elasticsearch,启动项目成功。

当再次加入监控时,还会报上述错误,现在的解决方案还是在main方法中加入false的设置。

由于现在使用的elasticsearch的版本为6.1.4,找到其源码,搜索”es.set.netty.runtime.available.processors”,发现在Netty4Utils的下述部分

/**
 * Set the number of available processors that Netty uses for sizing various resources (e.g., thread pools).
 *
 * @param availableProcessors the number of available processors
 * @throws IllegalStateException if available processors was set previously and the specified value does not match the already-set value
 */
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(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);
	}
}

通过方法描述可知,设置false可以避免由于各种处理器(可理解成引入netty的各种中间件)的互相测试而互相干扰导致的各种各样的问题,所在直接在main方法中加入这种设置项即可根本性解决问题。

从而可知,网络上搜索出来的答案并不严谨,比如netty版本、Lucene等,这些并没有从本质上解决问题。


标题:“Error creating bean with name ‘healthEndpoint”和”nested exception is java.lang.IllegalStateException: availableProcessors is already set to [4], rejecting [4]”
作者:yazong
地址:https://blog.llyweb.com/articles/2019/07/25/1578150842183.html