赞
踩
在使用spring config server服务的时候发现在启动之后的一段时间内控制台会抛出异常,spring admin监控爆红,控制台信息如下
--2024-06-26 20:38:59.615 - WARN 2944 --- [oundedElastic-7] o.s.c.c.s.e.JGitEnvironmentRepository : Error occured cloning to base directory.
-
org.eclipse.jgit.api.errors.TransportException: git@gitee.com:xxx/app-config.git: socket is not established
at org.eclipse.jgit.api.FetchCommand.call(FetchCommand.java:254) ~[org.eclipse.jgit-5.1.3.201810200350-r.jar:5.1.3.201810200350-r]
at org.eclipse.jgit.api.CloneCommand.fetch(CloneCommand.java:306) ~[org.eclipse.jgit-5.1.3.201810200350-r.jar:5.1.3.201810200350-r]
at org.eclipse.jgit.api.CloneCommand.call(CloneCommand.java:200) ~[org.eclipse.jgit-5.1.3.201810200350-r.jar:5.1.3.201810200350-r]
配置的 spring.cloud.config.server.git.uri=git@gitee.com:xxx/{application}-config.git
采用的是多微服务git仓库隔离的方式进行管理,但是我当前的集群中仅仅启动了spring cloud config server节点,并且集群中并不存在名字为app的服务,通过断点代码查询发现是actuate health功能导致的,在org.springframework.cloud.config.server.config.EnvironmentRepositoryConfiguration.ConfigServerActuatorConfiguration
根据配置spring.cloud.config.server.health.enabled
实例化了一个health bean,而该值在默认情况下为true
@ConditionalOnClass({AbstractHealthIndicator.class})
@ConditionalOnProperty(
value = {"spring.cloud.config.server.health.enabled"},
matchIfMissing = true
)
protected static class ConfigServerActuatorConfiguration {
protected ConfigServerActuatorConfiguration() {
}
@Bean
public ConfigServerHealthIndicator configServerHealthIndicator(EnvironmentRepository repository) {
return new ConfigServerHealthIndicator(repository);
}
}
ConfigServerHealthIndicator实现了HealthIndicator接口,在当前节点内,在eureka调用/actuator/health 的时候就会执行(之前一一直理解为定时器执行),它的health check如下
@Override protected void doHealthCheck(Health.Builder builder) throws Exception { builder.up(); List<Map<String, Object>> details = new ArrayList<>(); for (String name : this.repositories.keySet()) { Repository repository = this.repositories.get(name); String application = (repository.getName() == null) ? name : repository.getName(); String profiles = repository.getProfiles(); try { Environment environment = this.environmentRepository.findOne(application, profiles, repository.getLabel(), false); HashMap<String, Object> detail = new HashMap<>(); detail.put("name", environment.getName()); detail.put("label", environment.getLabel()); if (environment.getProfiles() != null && environment.getProfiles().length > 0) { detail.put("profiles", Arrays.asList(environment.getProfiles())); } if (!CollectionUtils.isEmpty(environment.getPropertySources())) { List<String> sources = new ArrayList<>(); for (PropertySource source : environment.getPropertySources()) { sources.add(source.getName()); } detail.put("sources", sources); } details.add(detail); } catch (Exception e) { logger.debug("Could not read repository: " + application, e); HashMap<String, String> map = new HashMap<>(); map.put("application", application); map.put("profiles", profiles); builder.withDetail("repository", map); builder.down(e); return; } } builder.withDetail("repositories", details); } @PostConstruct public void init() { if (this.repositories.isEmpty()) { this.repositories.put("app", new Repository()); } }
在bean 构造完成的时候会执行一个init方法,直接推了一个app 进去,这就是罪魁祸首,可以把spring.cloud.config.server.health.enabled
设置为false关闭health的检查或者配置一个spring.cloud.config.server.health.repositories
配置一个真实的应用比如
spring.cloud.config.server.health.repositories.fxdanmugw-config.label=master
spring.cloud.config.server.health.repositories.fxdanmugw-config.name=xxx
排查这个问题的时候还在好奇为什么spring会提供这种能力?不过一想,确实有存在的必要,比如仓库中提供的配置被不小心删除了,微服务那边自己本身有一套默认配置,默认配置也可以让微服务成功启动,但是提供的服务存在差异,此时从服务状态上是很难直接预警的,但是如果有这个能力之后,endpoint 就能提供对应监视仓库文件是否存在,且配合Grafana Prometheus 提供预警能力,另外config server完全可以给客户端提供配置服务,比如游戏的配置服务,还自带版本管理,是一个有效的使用场景
我明确的记得在使用单个固定的git仓库的时候这个配置点是可以正常进行health check的,为什么改为多项目单仓库隔离就会出问题?真是奇怪这个需要进一步探究,又或者在启动的时候直接吧app这个给移除?
对应的官方描述在这里 health_indicator
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。