Spring Cloud config之三:config-server因为server端和client端的健康检查导致服务超时阻塞问题
springcloud线上一个问题,当config-server连不上git时,微服务集群慢慢的都挂掉。
在入口层增加了日志跟踪问题:
org.springframework.cloud.config.server.environment.EnvironmentController.java
- @RequestMapping("/{name}/{profiles}/{label:.*}")
- public Environment labelled(@PathVariable String name, @PathVariable String profiles,
- @PathVariable String label) {
- if (name != null && name.contains("(_)")) {
- // "(_)" is uncommon in a git repo name, but "/" cannot be matched
- // by Spring MVC
- name = name.replace("(_)", "/");
- }
- if (label != null && label.contains("(_)")) {
- // "(_)" is uncommon in a git branch name, but "/" cannot be matched
- // by Spring MVC
- label = label.replace("(_)", "/");
- }
- StopWatch sw = new StopWatch("labelled");
- sw.start();
- logger.info("EnvironmentController.labelled()开始,name={},profiles={},label={}", name, profiles, label);
- Environment environment = this.repository.findOne(name, profiles, label);
- sw.stop();
- logger.info("EnvironmentController.labelled()结束,name={},profiles={},label={},耗时={}毫秒,耗时={}秒", name, profiles, label, sw.getTotalTimeMillis(), sw.getTotalTimeSeconds());
- return environment;
- }
健康检查的入口ConfigServerHealthIndicator.java增加日志:
- @Override
- protected void doHealthCheck(Health.Builder builder) throws Exception {
- StopWatch sw = new StopWatch("doHealthCheck");
- sw.start();
- logger.info("ConfigServerHealthIndicator.doHealthCheck()开始,builder={}", builder);
- 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());
- 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) {
- 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);
- sw.stop();
- logger.info("ConfigServerHealthIndicator.doHealthCheck()结束,耗时={}毫秒,耗时={}秒,builder={}", sw.getTotalTimeMillis(), sw.getTotalTimeSeconds(), builder);
- }
通过耗时统计的日志分析后,发现是EnvironmentController和ConfigServerHealthIndicator调用次数太多,这两个调用最终会调用JGitEnvironmentRepository.fetch()方法,这个fetch方法会去请求git,超时时间大概是5秒。
由于请求的数量过多,服务请求不过来,线程阻塞了很长时间。
分析:
1、EnvironmentController的调用是每个微服务模块发起的,为什么?
2、ConfigServerHealthIndicator的调用是config-server的健康检查,可以通过设置检查的间隔时间缓解问题。
- consul:
- host: 10.200.110.100
- port: 8500
- enabled: true
- discovery:
- enabled: true
- hostname: 10.200.110.100
- healthCheckInterval: 30s
- 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的代码
- @ConfigurationProperties("spring.cloud.config.server.health")
- public class ConfigServerHealthIndicator extends AbstractHealthIndicator {
- private EnvironmentRepository environmentRepository;
- private Map<String, Repository> repositories = new LinkedHashMap<>();
- public ConfigServerHealthIndicator(EnvironmentRepository environmentRepository) {
- this.environmentRepository = environmentRepository;
- }
- @PostConstruct
- public void init() {
- if (this.repositories.isEmpty()) {
- this.repositories.put("app", new Repository());
- }
- }
- //...
- }
如果想停止掉这样的检测可以通过配置health.config.enabled=false去关闭此功能。
看源码:org.springframework.cloud.config.client.ConfigClientAutoConfiguration.java
- @Configuration
- public class ConfigClientAutoConfiguration {
- @Configuration
- @ConditionalOnClass(HealthIndicator.class)
- @ConditionalOnBean(ConfigServicePropertySourceLocator.class)
- @ConditionalOnProperty(value = "health.config.enabled", matchIfMissing = true)
- protected static class ConfigServerHealthIndicatorConfiguration {
- @Bean
- public ConfigServerHealthIndicator configServerHealthIndicator(
- ConfigServicePropertySourceLocator locator,
- ConfigClientHealthProperties properties, Environment environment) {
- return new ConfigServerHealthIndicator(locator, environment, properties);
- }
- }
- //...
Spring Cloud config之三:config-server因为server端和client端的健康检查导致服务超时阻塞问题的更多相关文章
- Spring Cloud 入门 之 Config 篇(六)
原文地址:Spring Cloud 入门 之 Config 篇(六) 博客地址:http://www.extlight.com 一.前言 随着业务的扩展,为了方便开发和维护项目,我们通常会将大项目拆分 ...
- Spring Cloud 系列之 Config 配置中心(三)
本篇文章为系列文章,未读前几集的同学请猛戳这里: Spring Cloud 系列之 Config 配置中心(一) Spring Cloud 系列之 Config 配置中心(二) 本篇文章讲解 Conf ...
- Spring Cloud Alibaba Nacos Config 实战
Nacos 提供用于存储配置和其他元数据的 key/value 存储,为分布式系统中的外部化配置提供服务器端和客户端支持.使用 Spring Cloud Alibaba Nacos Config,您可 ...
- Spring Cloud 系列之 Config 配置中心(二)
本篇文章为系列文章,未读第一集的同学请猛戳这里:Spring Cloud 系列之 Config 配置中心(一) 本篇文章讲解 Config 如何实现配置中心自动刷新. 配置中心自动刷新 点击链接观看: ...
- Spring Cloud Alibaba Nacos Config 的使用
Spring Cloud Alibaba Nacos Config 的使用 一.需求 二.实现功能 1.加载 product-provider-dev.yaml 配置文件 2.实现配置的自动刷新 3. ...
- 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 ...
- 在socket的server端处理client端发来的数据
一.楔子 最近做了一个需求遇到一个坑,归结成一个小问题,其实就是在socket的server端处理client端发来的数据的问题,现将这个问题总结一下,本文将数据在server端以字典的形式存储. 另 ...
- 用同一台PC的两个网口实现Iperf的server端和client端
用同一台PC的两个网口实现Iperf的server端和client端 2015年10月20日 20:35:11 阅读数:2943 有时候需要发包,仅仅需要一定速率的流量,并不需要关心收到报文的大小,一 ...
- spring cloud 学习(5) - config server
分布式环境下的统一配置框架,已经有不少了,比如百度的disconf,阿里的diamand.今天来看下spring cloud对应的解决方案: 如上图,从架构上就可以看出与disconf之类的有很大不同 ...
随机推荐
- 英语dialogite红纹石dialogite菱锰矿
红纹石又称菱锰矿(dialogite)属于三方晶系.晶体呈菱面体,通常呈粒状.块状或结核状.玫瑰色,容易氧化而转变成褐黑色.玻璃光泽.解理平行菱面体{1011}完全.硬度3.5-4.5.比重3.6-3 ...
- SpringCloud学习第四章-Eureka创建
注:因为有了父项目,所以不需要引入boot的jar,项目都是maven构建 1.pom.xml <?xml version="1.0" encoding="UTF- ...
- 201871010126 王亚涛 《面向对象程序设计(java)》 第四周学习总结
项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ 这个作业的要求在哪里 https://www.cnblogs.com/nwnu-daizh/p ...
- python3字符串的方法及注释/ 字符串格式化符号含义及格式化符号含义
capitalize() 把字符串的第一个字符改为大写 casefold() 把整个字符串的所有字符改为小写 center(width) 将字符串居中,并使用空格填充至长度wid ...
- centos安装安全狗提示Need system command 'locate' to install safedog for linux的解决方法
今天为客户的centos服务器安装安全狗时提示Need system command 'locate' to install safedog for linux.Installation aborte ...
- .eslintrc的配置
{ // 环境定义了预定义的全局变量. "env": { //环境定义了预定义的全局变量.更多在官网查看 "browser": true, "node ...
- 实现:笑脸_Crack
直接载入OD,观察发现弹窗可能为MessageBox,那么进行对windows api函数的搜索 跟进反汇编窗口跟随函数,来到这里,直接进行断点操作 运行程序,跑到断点处,如下图 接着发现堆栈窗口有调 ...
- 【java】定时任务停止时间设置
我的需求:每天9点至20点运行 解决办法:@Scheduled(cron = "0 * 9,10,11,12,13,14,15,16,17,18,19 * * ?") 解释: 逗 ...
- 绕过dva dispatch在更新model数据的异步
我的业务是在更新选择列表后,马上进行总价格更新,那么由于model的更新不是实时的,因此我在this.props得到的值还是旧值,解决办法就是通过dispatch成功返回的值,传给计算函数 handl ...
- 机器学习-MNIST数据集-神经网络
#设置随机种子 seed = 7 numpy.random.seed(seed) #加载数据 (X_train,y_train),(X_test,y_test) = mnist.load_data() ...