springboot项目集成apollo总结

公司最近使用了携程的开源框架apollo来对配置文件进行管理,总体上来说还是非常简单的。

1.接入apollo

1.1 在yml或者properties文件中添加apollo配置

在resource目录下创建bootstrap.properties/yml或者application.properties/yml,配置内容如下:

#apollo中的服务名称
app.id=你在apollo后台中的项目唯一标示码
#注入默认application
apollo.bootstrap.enabled=true
#优先加载apollo配置 
apollo.bootstrap.eagerLoad.enabled=true
#注入多个namespace,配置在前的优先级更高
apollo.bootstrap.namespaces=profile,application

1.2将现有resource下的yml或者properties配置添加到apollo后台,并删除本地文件

1.3增加pom依赖


    com.ctrip.framework.apollo
    apollo-client
    1.4.0

1.4如果代码中有使用 @ConfigurationProperties 。通过增加以下代码来支持自动更新,同时这段代码也支持了日志级别自动更新

import com.ctrip.framework.apollo.model.ConfigChangeEvent;
import com.ctrip.framework.apollo.spring.annotation.ApolloConfigChangeListener;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.context.environment.EnvironmentChangeEvent;
import org.springframework.cloud.context.scope.refresh.RefreshScope;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;
 
import javax.annotation.Resource;
 
@Slf4j
@Component
public class ApolloRefreshConfig {
    @Resource
    private AppConfig appConfig;
    @Resource
    private RefreshScope refreshScope;
    @Resource
    private ApplicationContext applicationContext;
 
    //value对应配置的namespace 
    //prefixes 为你的配置前缀,没有可不写
    //refreshScope.refresh的参数是自定义配置的BeanName
    @ApolloConfigChangeListener(value = {"profile", "application"}, interestedKeyPrefixes = "prefixes.")
    public void appConfigChange(ConfigChangeEvent changeEvent) {
        log.info("配置更新前|{}", appConfig);
        refreshScope.refresh("appConfig");
        log.info("配置更新后|{}", appConfig);
    }
 
    @ApolloConfigChangeListener(value = {"profile", "application"}, interestedKeyPrefixes = "logging.level.")
    public void loggingLevelChange(ConfigChangeEvent changeEvent) {
        applicationContext.publishEvent(new EnvironmentChangeEvent(changeEvent.changedKeys()));
        log.info("日志级别配置更新完成|{}", changeEvent.changedKeys());
    }
}

1.5 如果项目中有使用xml配置的,例如dubbo的provider和consumer等配置中需要引用apollo中的配置项,则需在xml配置文件中添加如下配置,该配置可以传递,即xml中加载新的xml文件,新的xml文件不必配置,仅需配置一次即可

xmlns:apollo="http://www.ctrip.com/schema/apollo"
http://www.ctrip.com/schema/apollo http://www.ctrip.com/schema/apollo.xsd

2.日常开发使用apollo

1.本地配置apollo

1.1使用全局配置

在/opt/settings/server.properties(Mac/Linux)或C:\opt\settings\server.properties(Windows)文件添加配置:

apollo.meta=http://local-apollo.devops.kaishustory.com
apollo.cacheDir=修改为本地目录

1.2idea配置

启动参数中增加:-Dapollo.meta=你的apollo对应地址,从Apollo对应地址读取配置。

本地缓存路径修改:-Dapollo.cacheDir=/Users/${mac username}/Downloads/apollo.cacheDir,注意需要修改此路径。

1.3本地缓存配置:

Apollo客户端会把从服务端获取到的配置在本地文件系统缓存一份,用于在遇到服务不可用,或网络不通的时候,依然能从本地恢复配置,不影响应用正常运行。

本地缓存路径默认位于以下路径,所以请确保/opt/dataC:\opt\data\目录存在,且应用有读写权限。

Mac/Linux: /opt/data/{appId}/config-cache

Windows: C:\opt\data\{appId}\config-cache

本地配置文件会以下面的文件名格式放置于本地缓存路径下:

{appId}+{cluster}+{namespace}.properties

文件内容以properties格式存储,比如如果有两个key,一个是name,另一个是password,那么文件内容就是如下格式:

name=root
password=123456

自定义缓存路径

1.0.0版本开始支持以下方式自定义缓存路径,按照优先级从高到低分别为:

通过Java System Property apollo.cacheDir

   a.可以通过Java的System Property apollo.cacheDir来指定

       b.在Java程序启动脚本中,可以指定-Dapollo.cacheDir=/opt/data/some-cache-dir

   c.如果是运行jar文件,需要注意格式是java -Dapollo.cacheDir=/opt/data/cacheDir -jar xxx.jar

       d. 通过程序指定,如System.setProperty("apollo.cacheDir", "/opt/data/some-cache-dir")

1.4单元测试

引入pom文件


    com.ctrip.framework.apollo
    apollo-mockserver
    1.1.0

在resource下防治mock数据,约定名称为mockdata-你的namespace.properties

编写测试类

@RunWith(SpringJUnit4ClassRunner.class)

@SpringApplicationConfiguration(classes = TestConfiguration.class)

public class SpringIntegrationTest {

  // 启动apollo的mockserver

  @ClassRule

  public static EmbeddedApollo embeddedApollo = new EmbeddedApollo();



  @Test

  @DirtiesContext 

  public void testPropertyInject(){

    assertEquals("key1", testBean.key1);

    assertEquals("key2", testBean.key2);

  }



  @Test

  @DirtiesContext

  public void testListenerTriggeredByAdd() throws InterruptedException, ExecutionException, TimeoutException {

    String namespace = "";

    embeddedApollo.addOrModifyPropery(namespace,"key","value");

    ConfigChangeEvent changeEvent = testBean.futureData.get(5000, TimeUnit.MILLISECONDS);

    assertEquals(namespace, changeEvent.getNamespace());

    assertEquals("value", changeEvent.getChange("key").getNewValue());

  }



  @EnableApolloConfig("application")

  @Configuration

  static class TestConfiguration{

    @Bean

    public TestBean testBean(){

      return new TestBean();

    }

  }



  static class TestBean{

    @Value("${key1}")

    String key1;

    @Value("${key2}")

    String key2;



    SettableFuture futureData = SettableFuture.create();



    @ApolloConfigChangeListener("namespace")

    private void onChange(ConfigChangeEvent changeEvent) {

      futureData.set(changeEvent);

    }

  }

}

 

 

你可能感兴趣的:(java)