springcloud笔记:问题及解决汇总

intellj idea调试springcloud的配置

springcloud项目搭建好后,项目列表有很多项目,如图1,如果要一个项目一个项目的找到启动类再打开会很繁琐,因此可以借助intellij idea的Run Dashboard面板,下面是配置方法。

图1 项目列表

  1. 将项目列表(Project)调整为项目文件列表(Project Files),打开workspace.xml文件。

    图2 workspace.xml文件

  2. 在workspace.xml中的<component name="RunDashboard">标签第一行添加<option name="configurationTypes">标签代码,代码如下:

    1
    2
    3
    4
    5
    6
    7
    8
    <component name="RunDashboard">
    <option name="configurationTypes">
    <set>
    <option value="SpringBootApplicationConfigurationType" />
    </set>
    </option>
    ...
    </component>
  3. 重新打开intellij idea,Run Dashboard会在左下角打开,如图3,可以看到所有的项目,在项目上右键就可以执行,并且执行和关闭的项目都分别列出来了,使用比较方便。

    图3 Run Dashboard

config客户端无法获取配置

config客户端配置好后,通过${}无法获取中心的配置,并报错如下:

1
2
3
4
5
6
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'indexController': Injection of autowired dependencies failed; nested exception is java.lang.IllegalArgumentException: Could not resolve placeholder 'provider.message' in value "${provider.message}"
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:379) ~[spring-beans-5.0.7.RELEASE.jar:5.0.7.RELEASE]
...
Caused by: java.lang.IllegalArgumentException: Could not resolve placeholder 'provider.message' in value "${provider.message}"
at org.springframework.util.PropertyPlaceholderHelper.parseStringValue(PropertyPlaceholderHelper.java:172) ~[spring-core-5.0.7.RELEASE.jar:5.0.7.RELEASE]
...

上述报错表示provider.message无法获取,但是检查了各种配置发现没有任何问题。最后发现原来是config客户端(indexController所在的项目)没有引入config的jar包… 这是个低级错误,但是对于刚开始搭建springcloud项目的新手来说是很容易犯的,因为大多教程中没有这个步骤,所以很容易遇到这个报错。另外还需要注意服务端的配置是spring-cloud-config-client包,不是spring-cloud-config-server包。

下面附上config服务端和客户端的配置,网上大多是git配置,下面就以native为例(毕竟学习时比较实用)。

服务端:

  • pom.xml
    1
    2
    3
    4
    <dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-config-server</artifactId>
    </dependency>
  • bootstrap.yml
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    spring:
    # native要设置spring.profile.action为native
    profiles:
    active: native
    application:
    name: spring-cloud-config
    cloud:
    config:
    server:
    native:
    search-locations: classpath:properties/
  • providerconfig.yml,配置中心的配置文件(用于测试)
    1
    2
    provider:
    message: from config center

客户端:

  • pom.xml
    1
    2
    3
    4
    <dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-config-client</artifactId>
    </dependency>
  • bootstrap.yml
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    spring:
    application:
    name: spring-cloud-provider
    cloud:
    # 配置文件的名称和config服务端的应用名称
    config:
    name: providerconfig
    discovery:
    enabled: true
    serviceId: spring-cloud-config

服务无法注册到eureka配置中心

服务启动后,报错如下:

1
2
3
RedirectingEurekaHttpClient  : Request execution error. endpoint=DefaultEndpoint{ serviceUrl='http://localhost:8761/eureka/}
Caused by: java.net.ConnectException: Connection refused (Connection refused)
com.netflix.discovery.shared.transport.TransportException: Cannot execute request on any known server。

eureka配置的端口为8000,但服务器却发送到了默认端口,仔细检查配置,发现defaultZone写成了defualt-zone,这是一个坑,这个配置只能使用驼峰,否则就无法正确解析,而serviceUrl则可以写成service-url

1
2
3
4
eureka:
client:
service-url:
defaultZone: http://localhost:8000/eureka

yml配置多profiles的服务

比如启动多个A服务,不需要创建多个A的模块,通过yml文件就可以配置多个A服务。

比如配置端口分别为8000和8001的A服务,分别配置profiles为8000和8001,可以按照如下方式编写yml:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# 公共的注册中心配置单独写
eureka:
client:
service-url:
defaultZone: http://localhost:9100/eureka,http://localhost:9101/eureka

# 通过3个横线符号分隔
---

# 8000的A服务
spring:
application:
name: A-8000
profiles: 8000
server:
port: 8000

# 通过3个横线符号分隔多个profiles配置
---

# 8001的A服务
spring:
application:
name: A-8001
profiles: 8001
server:
port: 8001

启动时,命令行跟上--spring.profiles.active=8000--spring.profiles.active=8001,也可以在idea的Run Configurations中配置Active Profiles为对应profiles。