SpringBoot升级为springCloud 阿里云acm升级问题记录

阿里云acm升级问题记录

背景

公司的项目之前是SpringBoot, 并使用阿里云acm管理应用配置文件,当项目启动时,从acm上读取对应的配置信息,加载到程序里。当我将SpringBoot 改造升级为SpringCloud时,原本的acm配置不生效了,也需要一并升级。

使用SpringBoot时acm的配置

  • 添加acm依赖
   <dependency>
       <groupId>com.alibaba.cloud</groupId>
      <artifactId>spring-cloud-starter-acm</artifactId>
   </dependency>
  • 配置acm控制台

在acm控制后台的配置

在项目里的配置

配置文件内容

升级SppringCloud时的改动

  • 依赖修改
   <dependency>
      <groupId>com.alibaba.cloud</groupId>
       <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
   </dependency>
  <dependency>
       <groupId>org.springframework.cloud</groupId>
       <artifactId>spring-cloud-starter-config</artifactId>
  </dependency>
  • 配置acm控制台

  • 项目里配置

心路历程

从boot升级成cloud, acm的升级一路走来踩了很多坑。阿里云官方acm配置中心废弃了旧版的acm-sdk模式,统一采用新的基于nacos模式的配置中心。

坑点

  • boot里,配置文件是 bootstrap.yml + application-${env}.yml的模式。众所周知,spring配置文件的加载过程是先加载bootstrap.yml 再加载 application.yml 最后加载 application-${env}.yml 。所以在boot里,我们将应用端口、应用context-path都配置在本地,配置是基本不变的本地配置+可能会变的远程配置模式。 比如本地配置(bootstrap.yml):
server:
  servlet:
    contextPath: /moo-ws/api
    session:
      timeout: 604800
  port: 8081

## PageHelper 配置
pagehelper:
  helperDialect: mysql
  reasonable: false
  supportMethodsArguments: true
  params: count=countSql

## spring 配置
spring:
  application:
    name: xxx
    group: com.xxx

本地配置(application-${env}.yml):

alibaba:
  acm:
    namespace: xxx
    accessKey: xx
    secretKey: xxx
    fileExtension: yaml
    endpoint: acm.aliyun.com
    group: moo

远程acm配置(application-${env}.yml):

spring:
  ##默认Redis基础配置
  redis:
    host: xxx
    port: 6379
    password: xxx
    timeout: 3000
    jedis:
      pool:
        max-active: 10
        max-wait: -1
        max-idle: 8
        min-idle: 0
  • 而当升级为cloud时,原本的boot模式不太支持。并且在升级为cloud后,我将所有的配置都放在远程上,本地配置文件只保留指向acm远程的信息。包括端口、contextPath等基本不会变的配置也会放在远程配置中心。

本地配置内容:

spring:
  cloud:
    nacos:
      config:
        enabled: true
        refresh-enabled: true
        group: igor-group
        name: com.xxx.xxx
        access-key: xxx
        secret-key: xxx
        endpoint: acm.aliyun.com
        namespace: xxx
        file-extension: yaml
        

剩下所有的配置信息都在远程配置上。 如果熟悉SpringCloud的生态,就知道nacos config其实也是SpringCloud Config的一个实现。所以为了让nacos config在创建上下文之前就被执行,需要把本地的配置文件改为bootstrap-${env}.yml。这样应用在最开始就去加载远程config。

原本我以为到这里也就结束了,实际项目启动发现尽管回去读远程配置,但实际读到的内容为空。 这个时候就debug了nacos-config的源码调试。 这里不展开赘述,内容太干太长。直接说最后的解决办法。

spring:
  cloud:
    nacos:
      config:
        enabled: true
        refresh-enabled: true
        group: #这个跟acm平台的group一致
        name: #这个跟acm平台的文件名前面一致,但在acm平台的文件名后面要加-dev或者-test或者-prod。因为我的项目环境变量在启动脚本里,并且nacos-config会根据不同的环境自动加载不同的配置文件
        access-key: #阿里云accessKey
        secret-key: #阿里云secret
        endpoint: acm.aliyun.com
        namespace: #命名空间
        file-extension: yaml #acm上文件的后缀,我的文件是yaml
       

根据上面的配置可以看到,程序会根据配置的 spring.cloud.nacos.config.name + “-环境” + spring.cloud.nacos.config.file-extension 去找acm平台对应namespace、group下的文件。

这个地方真的太坑了,我排查问题的时候走了不少弯路。铭记!!

完成以上步骤,基本完成从SpringBoot到SpringCloud acm的升级。

以上。