[alibaba/arthas]使用Arthas 获取 Spring 应用运行时配置值

2023-12-12 259 views
3
背景

众所周之,Spring 应用的配置注入方式非常多。除了我们熟悉的方式,比如

  • System Properties/System Env
  • application.properties/application.yaml
  • spring profiles
  • spring cloud config

还有很多配置注入的方式,令人眼花缭乱:

获取运行时具体配置

对于开发人员来说,在运行时怎样确定某个配置是否生效?它的具体值是什么?

用Arthas可以一行命令获取。

比如获取server.port的具体值:

$ vmtool --action getInstances --className org.springframework.context.ConfigurableApplicationContext --express 'instances[0].getEnvironment().getProperty("server.port")'
@String[7001]
获取具体的配置来源

但是怎样具体是从哪个配置源来的?

  1. 对于 spring boot应用,可以打开一个新的 terminal 窗口,执行 telnet 127.0.0.1 3658连接上Arthas。

  2. 直接 watch 下面的函数

  3. 在原来窗口用上面的vmtool命令来获取server.port的值

可以看到 watch 返回结果里有具体的配置来源application.yml

$ watch org.springframework.boot.context.properties.source.ConfigurationPropertySourcesPropertySource findConfigurationProperty
Press Q or Ctrl+C to abort.
Affect(class count: 1 , method count: 2) cost in 217 ms, listenerId: 5
method=org.springframework.boot.context.properties.source.ConfigurationPropertySourcesPropertySource.findConfigurationProperty location=AtExit
ts=2023-11-27 16:08:07.696; [cost=0.327042ms] result=@ArrayList[
    @Object[][isEmpty=false;size=1],
    @ConfigurationPropertySourcesPropertySource[ConfigurationPropertySourcesPropertySource {name='configurationProperties'}],
    @ConfigurationProperty[[ConfigurationProperty@18fb3ec9 name = server.port, value = 7001, origin = class path resource [application.yml] - 2:9]],
]
总结
  1. 用 vmtool 来获取 spring context
  2. 调用 Environment().getProperty 来获取具体的值
  3. 通过 watch spring boot 内部的 findConfigurationProperty 函数来获取具体的配置来源

回答

0

arthas idea plugin 里面已经集成了这个能力 image

  • 所有属性

    vmtool -x 3 --action getInstances --className org.springframework.core.env.ConfigurableEnvironment  --express '#standardServletEnvironment=instances[0],#allProperties={},#propertySourceIterator=#standardServletEnvironment.getPropertySources().iterator(),#propertySourceIterator.{#key=#this.getName(),#allProperties.add("                "),#allProperties.add("------------------------- name:"+#key),#this.getSource() instanceof java.util.Map ?#this.getSource().entrySet().iterator.{#key=#this.key,#allProperties.add(#key+"="+#standardServletEnvironment.getProperty(#key))}:#{}},#allProperties'  
  • 单个属性 (选中某个属性配置 右键唤起插件功能)

vmtool -x 3 --action getInstances --className org.springframework.core.env.ConfigurableEnvironment  --express 'instances[0].getProperty("spring.jackson.time-zone") '
1

我使用这个功能的时候 给的我是ognl -x 3 这个格式的命令而不是vmtool 是我们插件版本不同么