springcloud线上一个问题,当config-server连不上git时,微服务集群慢慢的都挂掉。

在入口层增加了日志跟踪问题:

org.springframework.cloud.config.server.environment.EnvironmentController.java

  1. @RequestMapping("/{name}/{profiles}/{label:.*}")
  2. public Environment labelled(@PathVariable String name, @PathVariable String profiles,
  3. @PathVariable String label) {
  4. if (name != null && name.contains("(_)")) {
  5. // "(_)" is uncommon in a git repo name, but "/" cannot be matched
  6. // by Spring MVC
  7. name = name.replace("(_)", "/");
  8. }
  9. if (label != null && label.contains("(_)")) {
  10. // "(_)" is uncommon in a git branch name, but "/" cannot be matched
  11. // by Spring MVC
  12. label = label.replace("(_)", "/");
  13. }
  14. StopWatch sw = new StopWatch("labelled");
  15. sw.start();
  16. logger.info("EnvironmentController.labelled()开始,name={},profiles={},label={}", name, profiles, label);
  17. Environment environment = this.repository.findOne(name, profiles, label);
  18. sw.stop();
  19. logger.info("EnvironmentController.labelled()结束,name={},profiles={},label={},耗时={}毫秒,耗时={}秒", name, profiles, label, sw.getTotalTimeMillis(), sw.getTotalTimeSeconds());
  20. return environment;
  21. }

健康检查的入口ConfigServerHealthIndicator.java增加日志:

  1. @Override
  2. protected void doHealthCheck(Health.Builder builder) throws Exception {
  3. StopWatch sw = new StopWatch("doHealthCheck");
  4. sw.start();
  5. logger.info("ConfigServerHealthIndicator.doHealthCheck()开始,builder={}", builder);
  6. builder.up();
  7. List<Map<String, Object>> details = new ArrayList<>();
  8. for (String name : this.repositories.keySet()) {
  9. Repository repository = this.repositories.get(name);
  10. String application = (repository.getName() == null)? name : repository.getName();
  11. String profiles = repository.getProfiles();
  12.  
  13. try {
  14. Environment environment = this.environmentRepository.findOne(application, profiles, repository.getLabel());
  15.  
  16. HashMap<String, Object> detail = new HashMap<>();
  17. detail.put("name", environment.getName());
  18. detail.put("label", environment.getLabel());
  19. if (environment.getProfiles() != null && environment.getProfiles().length > 0) {
  20. detail.put("profiles", Arrays.asList(environment.getProfiles()));
  21. }
  22.  
  23. if (!CollectionUtils.isEmpty(environment.getPropertySources())) {
  24. List<String> sources = new ArrayList<>();
  25. for (PropertySource source : environment.getPropertySources()) {
  26. sources.add(source.getName());
  27. }
  28. detail.put("sources", sources);
  29. }
  30. details.add(detail);
  31. } catch (Exception e) {
  32. HashMap<String, String> map = new HashMap<>();
  33. map.put("application", application);
  34. map.put("profiles", profiles);
  35. builder.withDetail("repository", map);
  36. builder.down(e);
  37. return;
  38. }
  39. }
  40. builder.withDetail("repositories", details);
  41. sw.stop();
  42. logger.info("ConfigServerHealthIndicator.doHealthCheck()结束,耗时={}毫秒,耗时={}秒,builder={}", sw.getTotalTimeMillis(), sw.getTotalTimeSeconds(), builder);
  43. }

通过耗时统计的日志分析后,发现是EnvironmentController和ConfigServerHealthIndicator调用次数太多,这两个调用最终会调用JGitEnvironmentRepository.fetch()方法,这个fetch方法会去请求git,超时时间大概是5秒。

由于请求的数量过多,服务请求不过来,线程阻塞了很长时间。

分析:

1、EnvironmentController的调用是每个微服务模块发起的,为什么?

2、ConfigServerHealthIndicator的调用是config-server的健康检查,可以通过设置检查的间隔时间缓解问题。

  1. consul:
  2. host: 10.200.110.100
  3. port: 8500
  4. enabled: true
  5. discovery:
  6. enabled: true
  7. hostname: 10.200.110.100
  8. healthCheckInterval: 30s
  9. queryPassing: true

EnvironmentController的请求时用config-server的client端的健康检查发起的调用。看源码:

各个客户端在连接注册中心,获取到配置中心实例后,会调用上面这段代码逻辑从配置中心获取到 Environment数据变量,上线环境后,遇到了一个问题,查看日志,发现这块逻辑被不停的调用,每20多秒就会调用一次,application的name为 app,通过查看SpringCloudConfig的官方文档知道Config Server 通过一个健康指示器来检测配置的EnvironmentRepository是否正常工作。 默认情况下会向EnvironmentRepository询问一个名字为app的应用配置,EnvironmentRepository实例回应default配置。   也就是说当健康监视器默认开启的时候,会不停的调用findOne来检测,配置是否可用,是否会出现异常,

这段代码是org.springframework.cloud.config.server.config.ConfigServerHealthIndicator类里初始化名称为application名字为app的代码

  1. @ConfigurationProperties("spring.cloud.config.server.health")
  2. public class ConfigServerHealthIndicator extends AbstractHealthIndicator {
  3.  
  4. private EnvironmentRepository environmentRepository;
  5.  
  6. private Map<String, Repository> repositories = new LinkedHashMap<>();
  7.  
  8. public ConfigServerHealthIndicator(EnvironmentRepository environmentRepository) {
  9. this.environmentRepository = environmentRepository;
  10. }
  11.  
  12. @PostConstruct
  13. public void init() {
  14. if (this.repositories.isEmpty()) {
  15. this.repositories.put("app", new Repository());
  16. }
  17. }
  18. //...
  19. }

如果想停止掉这样的检测可以通过配置health.config.enabled=false去关闭此功能。

看源码:org.springframework.cloud.config.client.ConfigClientAutoConfiguration.java

  1. @Configuration
  2. public class ConfigClientAutoConfiguration {
  3. @Configuration
  4. @ConditionalOnClass(HealthIndicator.class)
  5. @ConditionalOnBean(ConfigServicePropertySourceLocator.class)
  6. @ConditionalOnProperty(value = "health.config.enabled", matchIfMissing = true)
  7. protected static class ConfigServerHealthIndicatorConfiguration {
  8.  
  9. @Bean
  10. public ConfigServerHealthIndicator configServerHealthIndicator(
  11. ConfigServicePropertySourceLocator locator,
  12. ConfigClientHealthProperties properties, Environment environment) {
  13. return new ConfigServerHealthIndicator(locator, environment, properties);
  14. }
  15. }
  16. //...

Spring Cloud config之三:config-server因为server端和client端的健康检查导致服务超时阻塞问题的更多相关文章

  1. Spring Cloud 入门 之 Config 篇(六)

    原文地址:Spring Cloud 入门 之 Config 篇(六) 博客地址:http://www.extlight.com 一.前言 随着业务的扩展,为了方便开发和维护项目,我们通常会将大项目拆分 ...

  2. Spring Cloud 系列之 Config 配置中心(三)

    本篇文章为系列文章,未读前几集的同学请猛戳这里: Spring Cloud 系列之 Config 配置中心(一) Spring Cloud 系列之 Config 配置中心(二) 本篇文章讲解 Conf ...

  3. Spring Cloud Alibaba Nacos Config 实战

    Nacos 提供用于存储配置和其他元数据的 key/value 存储,为分布式系统中的外部化配置提供服务器端和客户端支持.使用 Spring Cloud Alibaba Nacos Config,您可 ...

  4. Spring Cloud 系列之 Config 配置中心(二)

    本篇文章为系列文章,未读第一集的同学请猛戳这里:Spring Cloud 系列之 Config 配置中心(一) 本篇文章讲解 Config 如何实现配置中心自动刷新. 配置中心自动刷新 点击链接观看: ...

  5. Spring Cloud Alibaba Nacos Config 的使用

    Spring Cloud Alibaba Nacos Config 的使用 一.需求 二.实现功能 1.加载 product-provider-dev.yaml 配置文件 2.实现配置的自动刷新 3. ...

  6. spring cloud provider报“Error parsing HTTP request header”,feign端报“Read timed out“

    这两天在调试spring cloud feign+hystrix报了如下错误: spring cloud provider报“Error parsing HTTP request header”,fe ...

  7. 在socket的server端处理client端发来的数据

    一.楔子 最近做了一个需求遇到一个坑,归结成一个小问题,其实就是在socket的server端处理client端发来的数据的问题,现将这个问题总结一下,本文将数据在server端以字典的形式存储. 另 ...

  8. 用同一台PC的两个网口实现Iperf的server端和client端

    用同一台PC的两个网口实现Iperf的server端和client端 2015年10月20日 20:35:11 阅读数:2943 有时候需要发包,仅仅需要一定速率的流量,并不需要关心收到报文的大小,一 ...

  9. spring cloud 学习(5) - config server

    分布式环境下的统一配置框架,已经有不少了,比如百度的disconf,阿里的diamand.今天来看下spring cloud对应的解决方案: 如上图,从架构上就可以看出与disconf之类的有很大不同 ...

随机推荐

  1. 英语dialogite红纹石dialogite菱锰矿

    红纹石又称菱锰矿(dialogite)属于三方晶系.晶体呈菱面体,通常呈粒状.块状或结核状.玫瑰色,容易氧化而转变成褐黑色.玻璃光泽.解理平行菱面体{1011}完全.硬度3.5-4.5.比重3.6-3 ...

  2. SpringCloud学习第四章-Eureka创建

    注:因为有了父项目,所以不需要引入boot的jar,项目都是maven构建 1.pom.xml <?xml version="1.0" encoding="UTF- ...

  3. 201871010126 王亚涛 《面向对象程序设计(java)》 第四周学习总结

    项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ 这个作业的要求在哪里 https://www.cnblogs.com/nwnu-daizh/p ...

  4. python3字符串的方法及注释/ 字符串格式化符号含义及格式化符号含义

     capitalize()   把字符串的第一个字符改为大写   casefold()   把整个字符串的所有字符改为小写   center(width)   将字符串居中,并使用空格填充至长度wid ...

  5. centos安装安全狗提示Need system command 'locate' to install safedog for linux的解决方法

    今天为客户的centos服务器安装安全狗时提示Need system command 'locate' to install safedog for linux.Installation aborte ...

  6. .eslintrc的配置

    { // 环境定义了预定义的全局变量. "env": { //环境定义了预定义的全局变量.更多在官网查看 "browser": true, "node ...

  7. 实现:笑脸_Crack

    直接载入OD,观察发现弹窗可能为MessageBox,那么进行对windows api函数的搜索 跟进反汇编窗口跟随函数,来到这里,直接进行断点操作 运行程序,跑到断点处,如下图 接着发现堆栈窗口有调 ...

  8. 【java】定时任务停止时间设置

    我的需求:每天9点至20点运行 解决办法:@Scheduled(cron = "0 * 9,10,11,12,13,14,15,16,17,18,19 * * ?") 解释:  逗 ...

  9. 绕过dva dispatch在更新model数据的异步

    我的业务是在更新选择列表后,马上进行总价格更新,那么由于model的更新不是实时的,因此我在this.props得到的值还是旧值,解决办法就是通过dispatch成功返回的值,传给计算函数 handl ...

  10. 机器学习-MNIST数据集-神经网络

    #设置随机种子 seed = 7 numpy.random.seed(seed) #加载数据 (X_train,y_train),(X_test,y_test) = mnist.load_data() ...