SpringCloud踩坑记录二

栏目: Java · 发布时间: 5年前

内容简介:继第一次搭建springcloud环境踩坑之后,时隔三个月,第二次踩坑记录也跟着上线了,SpringCloudConfig坑系列。第一次踩坑让我理解了出现此错误可以检查一下以下几点:回顾下错误发生点:
SpringCloud踩坑记录二

前言

继第一次搭建springcloud环境踩坑之后,时隔三个月,第二次踩坑记录也跟着上线了,SpringCloudConfig坑系列。第一次踩坑让我理解了 用户线程和守护线程 这一块的知识盲点,这次踩的坑就是基本就是 配置 上的坑。但是多踩踩坑会让我们更容易理解具体配置起到了什么样的作用。

坑一:抛出异常 :No instances found of configserver (myserver)

出现此错误可以检查一下以下几点:

  1. 需要依赖的config-server服务myserver(自己注册的服务名)是否注册到了eureka注册中心上。
  2. 如果注册上了,检查 spring.cloud.config.discovery.service-id 配置是否和服务名能对应上。
  3. eureka.client.fetch-registry 是否为true(其实默认值就是true,防止手贱误操作)。

回顾下错误发生点:

    public List<ServiceInstance> getConfigServerInstances(String serviceId) {
        logger.debug("Locating configserver (" + serviceId + ") via discovery");
        List<ServiceInstance> instances = this.client.getInstances(serviceId);
        if (instances.isEmpty()) {
            throw new IllegalStateException(
                    "No instances found of configserver (" + serviceId + ")");
        }
        logger.debug("Located configserver (" + serviceId
                + ") via discovery. No of instances found: " + instances.size());
        return instances;
    }
复制代码

从上方代码可以看出,在 this.client.getInstances(serviceId) 获取到实例为空的时候会抛出此异常,一步步追踪一下,发现最终会调用到 DiscoveryClient.getInstancesByVipAddress() 方法。

    public List<InstanceInfo> getInstancesByVipAddress(String vipAddress, boolean secure,
                                                       @Nullable String region) {
        if (vipAddress == null) {
            throw new IllegalArgumentException(
                    "Supplied VIP Address cannot be null");
        }
        Applications applications;
        if (instanceRegionChecker.isLocalRegion(region)) {
            applications = this.localRegionApps.get();
        } else {
            applications = remoteRegionVsApps.get(region);
            if (null == applications) {
                logger.debug("No applications are defined for region {}, so returning an empty instance list for vip "
                        + "address {}.", region, vipAddress);
                return Collections.emptyList();
            }
        }

        if (!secure) {
            return applications.getInstancesByVirtualHostName(vipAddress);
        } else {
            return applications.getInstancesBySecureVirtualHostName(vipAddress);

        }

    }
复制代码

从这里可以明显看出,要么 applications 为空,即注册中心没有可用服务或者 eureka.client.fetch-registry 配置成了false;要么通过 vipAddressapplications 查询不出实例结果,即给定的 service-id 在注册中心中不存在。

①注册中心没有可用服务,获取不到服务列表很容易理解。

service-id 对应不上,也很容易理解。就比如拿一个不存在的 key 去一个 collection 中获取 value ,肯定是获取不到服务的。

eureka.client.fetch-registry 配置成了false,这一点需要解释一下:

要知道咱们内存中存储的 applications 列表并不是每次请求都会进行刷新,而是维护了一个 CacheRefreshThread 去定时轮询获取注册中心中的服务,然后塞到 localRegionApps 中,然而,这个线程开启需要一个条件, clientConfig.shouldFetchRegistry()==true ,看方法名就知道需要 eureka.client.fetch-registry=true 任务才会开启。但是默认这个值就是true,当时不晓得是不是脑子抽风了配置成了false,然后找这个bug迷糊了好一会儿。具体开启任务线程的代码如下所示:

   private void initScheduledTasks() {
        if (clientConfig.shouldFetchRegistry()) {
            // registry cache refresh timer
            int registryFetchIntervalSeconds = clientConfig.getRegistryFetchIntervalSeconds();
            int expBackOffBound = clientConfig.getCacheRefreshExecutorExponentialBackOffBound();
            scheduler.schedule(
                    new TimedSupervisorTask(
                            "cacheRefresh",
                            scheduler,
                            cacheRefreshExecutor,
                            registryFetchIntervalSeconds,
                            TimeUnit.SECONDS,
                            expBackOffBound,
                            new CacheRefreshThread()
                    ),
                    registryFetchIntervalSeconds, TimeUnit.SECONDS);
        }
       ...
   }
复制代码

坑二:refresh的`endpoints`访问不到了

访问ip:port/actuator/refresh返回404。在搭建的过程中,很多老版本的教程都只是说引入下方依赖即可。

<dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
复制代码

但在springboot 2.x以上的版本,默认只对 healthinfo 这两个端点进行暴露出来,如下图所示。

SpringCloud踩坑记录二

而对 refresh 端点并未暴露出来,这里就需要咱们自己去手动配置暴露,感兴趣的朋友可以去Endpoints看一下具体有哪些可以暴露的端点,咱们也可以使用 management.endpoints.web.exposure.include=* 将所有端点全部暴露出来,当然,实际生产环境中也不建议如此。目前我测试配置 management.endpoints.web.exposure.include=refresh,info,health 暴露了 refresh,info,health 三个端点。

注意:

  1. 使用refresh端点时,它只会针对有@RefreshScope注解的类和方法进行刷新。

  2. 访问这些端点时都需要加上actuator这个basePath。

最后附上config-server端和config-client端的bootstrap.yml配置。

server端:

spring:
  cloud:
    config:
      server:
        git:
          uri: https://github.com/crazyStrongboy/config/
          searchPaths: foo
  application:
    name:  myserver
server:
  port:  8003
eureka:
  instance:
    hostname: TTT-HJ
    instance-id: ${spring.application.name}:${server.port}
  client:
    fetch-registry: false
    service-url:
      defaultZone: http://${eureka.instance.hostname}:8000/eureka/
复制代码

client端:

spring:
  application:
    name: application
  cloud:
    config:
      discovery:
        service-id: myserver
        enabled: true
      profile: dev

server:
  port: 8004
eureka:
  instance:
    hostname: TTT-HJ
    instance-id: ${spring.application.name}:${server.port}
  client:
    service-url:
      defaultZone: http://${eureka.instance.hostname}:8000/eureka/
    fetch-registry: true

management:
  endpoints:
    web:
      exposure:
        include: refresh,info,health
复制代码

后续

目前仅仅只是简单的测试一下springcloud config注册中心,后续会加上springcloud bus消息总线安排一下,看看还有木有坑点继续分享~~,具体案例见 github

END


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

The Art of Computer Programming, Volumes 1-3 Boxed Set

The Art of Computer Programming, Volumes 1-3 Boxed Set

Donald E. Knuth / Addison-Wesley Professional / 1998-10-15 / USD 199.99

This multivolume work is widely recognized as the definitive description of classical computer science. The first three volumes have for decades been an invaluable resource in programming theory and p......一起来看看 《The Art of Computer Programming, Volumes 1-3 Boxed Set》 这本书的介绍吧!

HTML 编码/解码
HTML 编码/解码

HTML 编码/解码

URL 编码/解码
URL 编码/解码

URL 编码/解码

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换