0%

Spring系列之SpringCloud

TodoItem

整理一下springcloud一站式解决方案的每个环节中,现在有哪些框架已经是不维护的? todo

Dubbo的生态在最近有没有经常颠覆性的完善? todo

为什么本地配置文件还要有从git加载的模式? todo

@RefreshScope用法和避坑 todo

Refresh Scope
A Spring @Bean that is marked as @RefreshScope will get special treatment when there is a configuration change. This addresses the problem of stateful beans that only get their configuration injected when they are initialized. For instance if a DataSource has open connections when the database URL is changed via the Environment, we probably want the holders of those connections to be able to complete what they are doing. Then the next time someone borrows a connection from the pool he gets one with the new URL.

Refresh scope beans are lazy proxies that initialize when they are used (i.e. when a method is called), and the scope acts as a cache of initialized values. To force a bean to re-initialize on the next method call you just need to invalidate its cache entry.

spring.cloud.config.uri的默认值作用是什么?启动警告是否需要排除掉?todo

@SpringBootApplication中指定scanBasePackages和不指定scanBasePackages的区别 todo

spring.profiles || yml配置文件

关于spring boot profiles可以参考:
https://dzone.com/articles/spring-boot-profiles-1
文中翻译的大概意思如下:
spring.profiles会以灵活切换的方式切换整个应用环境配置的各种相关属性,通过相关属性所在配置文件的文件名为条件做切换。

spring.profiles.active:native

这个标记为配置文件从本地路径加载,但是有点奇怪,按道理这么危险的配置文件应该只能本地才对,即使从svn或者git上加载也只能从私服去取,在非开发模式下不应该存在去公网取配置文件才对。
网上说可以从native,svn和git加载,但是官方的最新文档其comma-separated list出现的有

1
active: dev,mysql,git,redis,awss3,credhub,composite,vault

在查阅官方文档之后发现这几段话:

There is also a “native” profile in the Config Server that does not use Git but loads the config files from the local classpath or file system (any static URL you want to point to with spring.cloud.config.server.native.searchLocations). To use the native profile, launch the Config Server with spring.profiles.active=native.

意思是,当spring.profiles.active=native,配置服务会从本地的类路径classpath读取配置文件,如果指定了spring.cloud.config.server.native.searchLocations的话,那么将从指定的路径去读取配置属性文件。

Remember to use the file: prefix for file resources (the default without a prefix is usually the classpath). As with any Spring Boot configuration, you can embed ${}-style environment placeholders, but remember that absolute paths in Windows require an extra / (for example, file:///${user.home}/config-repo).

意思是,spring.cloud.config.server.native.searchLocations可以用${}引用变量这种占位符的方式指定路径。

The default value of the searchLocations is identical to a local Spring Boot application (that is, [classpath:/, classpath:/config, file:./, file:./config]). This does not expose the application.properties from the server to all clients, because any property sources present in the server are removed before being sent to the client.

意思是,spring.cloud.config.server.native.searchLocations有四个默认值,在不配置它的时候可以默认生效,并且如果配置了native的话,路径下所有的配置文件都会被默认加载。

prefer-ip-address

这个配置我在官方文档找到的解释是这样的:
In some cases, it is preferable for Eureka to advertise the IP addresses of services rather than the hostname. Set eureka.instance.preferIpAddress to true and, when the application registers with eureka, it uses its IP address rather than its hostname.
翻译:在某些情况下,Eureka显示服务列表用ip地址的形式来展示比用hostname的形式可能更加合适。把eureka.instance.preferIpAddress(低版本)设置为true,当服务被注册到eureka的时候,注册中心会使用它的ip地址而不是hostname。

lease-renewal-interval-in-seconds

1
2
3
4
5
6
7
8
9
10
11
   /**
* Indicates how often (in seconds) the eureka client needs to send heartbeats to
* eureka server to indicate that it is still alive. If the heartbeats are not
* received for the period specified in leaseExpirationDurationInSeconds, eureka
* server will remove the instance from its view, there by disallowing traffic to this
* instance.
*
* Note that the instance could still not take traffic if it implements
* HealthCheckCallback and then decides to make itself unavailable.
*/
private int leaseRenewalIntervalInSeconds = 30;

翻译:指定一个eureka客户端发送心跳包给eureka服务的频率(以秒为单位),以此来确保服务是否还活着。如果心跳包在leaseExpirationDurationInSeconds指定的时间段之内没有收到回应,那么eureka的服务将从他们可用微服务列表中移除掉对应的微服务实例,不再允许向该实例发送流量。要注意的是,如果实例实现了HealthCheckCallback接口,并且决定让实例自己置为不可用的话,那么它任然是不能接受流量的。

lease-expiration-duration-in-seconds

1
2
3
4
5
6
7
8
9
10
11
12
   /**
* Indicates the time in seconds that the eureka server waits since it received the
* last heartbeat before it can remove this instance from its view and there by
* disallowing traffic to this instance.
*
* Setting this value too long could mean that the traffic could be routed to the
* instance even though the instance is not alive. Setting this value too small could
* mean, the instance may be taken out of traffic because of temporary network
* glitches.This value to be set to atleast higher than the value specified in
* leaseRenewalIntervalInSeconds.
*/
private int leaseExpirationDurationInSeconds = 90;

翻译:指定一个从它最后一次接收某个服务实例的心跳包后等待的时间(以秒为单位),如果超过这个时间还不能接收到心跳包,那么eureka将会从他的服务列表中移除该实例,并不再允许向该实例发送流量。设置leaseExpirationDurationInSeconds的值太大的话,可能意味着某个实例不是活着的情况下,流量依然被发送到该实例中。设置的值太小的话,可能会由于临时网络故障导致实例抛弃了流量。这个值至少要比leaseRenewalIntervalInSeconds的值要高,也就是上面提到的lease-renewal-interval-in-seconds。

registry-fetch-interval-seconds

1
2
3
4
  /**
* Indicates how often(in seconds) to fetch the registry information from the eureka
* server.
*/

翻译:指定从eureka抓取注册服务的信息的频率(以秒为单位)

spring.cloud.config.fail-fast

https://blog.csdn.net/liubenlong007/article/details/87885567

处理过的问题

Request execution error. endpoint=DefaultEndpoint{ serviceUrl=’XX’}

这个报错非常奇葩,我是从网上下的手脚架,运行起来直接报错,后来通过谷歌找到了解决方案,就是在eureka服务的配置文件中加入register-with-eureka和fetch-registry:

1
2
3
4
5
6
7
8
9
10
# 注册中心配置
eureka:
instance:
prefer-ip-address: true
hostname: pig-eureka
client:
register-with-eureka: false
fetch-registry: false
service-url:
defaultZone: http://pig:pig@pig-eureka:8761/eureka/

后来再仔细跟一下,发现我是忘记先把eureka注册中心的服务启动了。。。

Cannot execute request on any known server

确认yml配置文件地址和格式没有问题的话,那么可能是eureka注册中心的服务没有关闭csrf,在eureka注册中心增加WebSecurityConfigurerAdapter,如下:

1
2
3
4
5
6
7
8
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

@Override
protected void configure(HttpSecurity http) throws Exception {
http.csrf().disable();
}
}

java.lang.NoClassDefFoundError: com/netflix/hystrix/contrib/javanica/aop/aspectj/HystrixCommandAspect

需要增加断容器依赖spring-cloud-starter-netflix-hystrix

@org.springframework.beans.factory.annotation.Qualifier(value=webFluxConversionService)}

如果引入一些第三方的Spring
抛出了这个依赖异常,原因是我同时引入依赖:spring-cloud-starter-gateway 和 spring-boot-starter-web。去除了父模块的spring-boot-starter-web依赖即可。

If you want an embedded database (H2, HSQL or Derby), please put it on the classpath.

如果遇到新建的微服务报错如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
***************************
APPLICATION FAILED TO START
***************************

Description:

Failed to configure a DataSource: 'url' attribute is not specified and no embedded datasource could be configured.

Reason: Failed to determine a suitable driver class


Action:

Consider the following:
If you want an embedded database (H2, HSQL or Derby), please put it on the classpath.
If you have database settings to be loaded from a particular profile you may need to activate it (no profiles are currently active).

检查关于数据库的链接拼写,和驱动包依赖,如果都没问题,有可能是因为新的微服务使用了配置中心忘记引用配置中心的客户端pom依赖了,我就是忘记下面这个引用:

1
2
3
4
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>

另外,可能性也会有如下几点:
1,yml,properties文件缺失、配置写错等;
2,没有在@SpringBootApplication注解的Application的同级包或者子级包下增加配置类也会报这个错;
3,也有可能是因为引入了不必要的spring-boot-starter-web模块,这个模块会强制要配置数据源;
4,引入了其他依赖到数据源配置的包比如

1
2
3
4
5
6
<!--mybatis-plus-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>${mybatis-plus.version}</version>
</dependency>

Feign PathVariable annotation was empty on param 0.

使用Feign的时候,如果参数中带有@PathVariable形式的参数,则要用value=””标明对应的参数,否则会抛出IllegalStateException异常

The bean ‘ngbip-baf-service.FeignClientSpecification’ could not be registered. A bean with that name has already been defined and overriding is disabled.

这个原因基本是因为注解了FeignClient的客户端类,同个id的要被重复注册进注册中心才报的错,可以检查一下是否有@FeignClient的id重复,或者pom的依赖重复了导致feign服务注册多次。