我发现“prometheusMeterRegistry”bean当前处于创建错误状态(请参阅下面的确切堆栈跟踪)当使用Prometheus与springboot执行器沿着RestTemplate时。这似乎是由于当与RestTemplate/Builder一起使用时循环引用prometheusMeterRegistry,RestTemplate/Builder在我的应用程序和springboot依赖性库中自动连接。我已经花了三天的时间来分析和修复这个问题,并参考了几个论坛提供的解决方案,但没有运气。我在服务器启动时得到这个错误,但令人惊讶的是/actuator/promethus url在我的本地运行良好,但当然没有API细节,因为restTemplate由于PrometheusMeterRegistry而存在一些依赖注入问题。(我试图部署在服务器上,因为它是在本地工作,除了有启动错误),由于启动时出错,应用程序无法成功部署到内置的Tomcat服务器上。请分享您对如何解决此问题的想法。
错误堆栈跟踪:
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'metricsRestTemplateCustomizer' defined in class path resource [org/springframework/boot/actuate/autoconfigure/metrics/web/client/RestTemplateMetricsConfiguration.class]: Unsatisfied dependency expressed through method 'metricsRestTemplateCustomizer' parameter 0; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'prometheusMeterRegistry': Requested bean is currently in creation: Is there an unresolvable circular reference?
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:800)
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:541)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1352)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1195)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:582)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208)
at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:276)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.addCandidateEntry(DefaultListableBeanFactory.java:1616)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:1573)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveMultipleBeans(DefaultListableBeanFactory.java:1417)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1349)
at org.springframework.beans.factory.support.DefaultListableBeanFactory$DependencyObjectProvider.resolveStream(DefaultListableBeanFactory.java:2119)
at org.springframework.beans.factory.support.DefaultListableBeanFactory$DependencyObjectProvider.orderedStream(DefaultListableBeanFactory.java:2113)
at org.springframework.boot.autoconfigure.web.client.RestTemplateAutoConfiguration.restTemplateBuilderConfigurer(RestTemplateAutoConfiguration.java:61)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:154)
... 140 more
Caused by: org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'prometheusMeterRegistry': Requested bean is currently in creation: Is there an unresolvable circular reference?
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.beforeSingletonCreation(DefaultSingletonBeanRegistry.java:355)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:227)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208)
at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:276)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1391)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1311)
at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:887)
at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:791)
正如在一些论坛中建议的那样,我也配置了below属性来打破循环引用,它在打破循环引用时工作得很好,因为它是预期的,但我在启动时再次得到不同的错误。
属性条目:
spring.main.allow-circular-references=true
错误堆栈跟踪:
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'healthRegistryCustomizer' defined in class path resource [org/sample/monitor/MeterConfig.class]: Unsatisfied dependency expressed through method 'healthRegistryCustomizer' parameter 0; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.boot.actuate.health.HealthContributorRegistry' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
at app//org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:800)
at app//org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:541)
at app//org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1352)
at app//org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1195)
at app//org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:582)
at app//org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542)
at app//org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335)
at app//org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
at app//org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333)
at app//org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208)
at app//org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:276)
at app//org.springframework.beans.factory.support.DefaultListableBeanFactory.addCandidateEntry(DefaultListableBeanFactory.java:1616)
at app//org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:1573)
at app//org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveMultipleBeans(DefaultListableBeanFactory.java:1417)
at app//org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1349)
at app//org.springframework.beans.factory.support.DefaultListableBeanFactory$DependencyObjectProvider.resolveStream(DefaultListableBeanFactory.java:2119)
at app//org.springframework.beans.factory.support.DefaultListableBeanFactory$DependencyObjectProvider.orderedStream(DefaultListableBeanFactory.java:2113)
at app//org.springframework.boot.actuate.autoconfigure.metrics.MeterRegistryConfigurer.asOrderedList(MeterRegistryConfigurer.java:90)
at app//org.springframework.boot.actuate.autoconfigure.metrics.MeterRegistryConfigurer.customize(MeterRegistryConfigurer.java:77)
at app//org.springframework.boot.actuate.autoconfigure.metrics.MeterRegistryConfigurer.configure(MeterRegistryConfigurer.java:63)
at app//org.springframework.boot.actuate.autoconfigure.metrics.MeterRegistryPostProcessor.postProcessAfterInitialization(MeterRegistryPostProcessor.java:64)
at app//org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization(AbstractAutowireCapableBeanFactory.java:455)
at app//org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1808)
at app//org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:620)
... 111 more
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.boot.actuate.health.HealthContributorRegistry' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
at app//org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1801)
at app//org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1357)
at app//org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1311)
at app//org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:887)
at app//org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:791)
下面是我对RestTemplate和MeterRegistryCustomizer Bean的实现
@Configuration
public class MeterConfig {
@Bean
public MeterRegistryCustomizer<MeterRegistry> healthRegistryCustomizer(@Autowired HealthContributorRegistry healthRegistry) {
return registry -> healthRegistry.stream()
.forEach(namedContributor -> registry.gauge("health",
details(namedContributor),
healthRegistry, health -> {
Status status = ((HealthIndicator) health
.getContributor(namedContributor.getName()))
.getHealth(true)
.getStatus();
return healthToCode(status);
}));
}
private static Iterable<Tag> details(NamedContributor<HealthContributor> contributor) {
HealthContributor contrib = contributor.getContributor();
HealthIndicator healthContributor = (HealthIndicator) contrib;
String name = contributor.getName();
List<Tag> tagList = new ArrayList<>();
tagList.add(Tag.of("name", name));
String details = healthContributor.getHealth(true).getDetails().toString();
tagList.add(Tag.of("details", details));
return tagList;
}
public static int healthToCode(Status status) {
return status.equals(Status.UP) ? 1 : 0;
}
}
@Configuration
@EnableScheduling
public class AppConfig {
@Bean
@ConditionalOnMissingBean
public RestTemplate restTemplate(RestTemplateBuilder restTemplateBuilder) {
return restTemplateBuilder.build();
}
}
@Component
public class MyHealthIndicator implements HealthIndicator {
@Autowired
MyRepo myrepo;
@Override
public Health health() {
return myrepo.ping() == "SUCCESS" ? Health.UP.build(): Health.DOWN.build(); //this will return the
}
}
@Repository
public class MyRepo {
@Autowired
RestTemplate restTemplate;
public String ping() {
return restTemplate.exchange("url", GET, new HttpEntity(requestBody, headers), String.class);
}
}
如果您在我的代码中观察到,假设PrometheusMeterRegistryMeterRegistryBean的创建依赖于restTemplate/PrometheusMeterRegistry,我还尝试了@Lazy初始化和@DependsOn来延迟Bean初始化。
我可能在这里做了一些关于注入bean的错误。请分享你的想法如何解决这个问题。我正在使用Springboot 2. 7. 2和依赖管理来控制依赖版本,并且还为io. micronium注册表添加了prometheus的依赖。
1条答案
按热度按时间qzwqbdag1#
我分享了我的经验,因为它花了更多的时间来检查循环引用的根本原因。我在升级到sprintboot 2.6.x和2.7.x后遇到了prometheusMeterRegistry相同的问题,因为我在POM文件中依赖于micrometer-registry-prometheus。
代码是手动将prometheus的metricRegistry设置为HikariDataSource,但是在新版本的springboot中,它会自动设置每个Hikari数据源,所以我只需从我的方法中删除该代码,然后它就可以正常工作。
注意:设置
spring.main.allow-circular-references=true
不适用于我的多数据源项目。希望能有所帮助。