本文汇介绍动态配置(DRM)在使用过程中遇到的常见问题及解决方法。
如何利用 DRM 动态设置日志等级?
基于 SOFABoot 开发的程序,对于日志有如下默认配置:
application.properties
# log level for current application with groupid com.hula.sofa
logging.level.com.hula.sofa=INFO
logback-spring.xml
<springProperty scope="context" name="logging.level" source="logging.level.com.hula.sofa"/>
您可以通过 DRM 来动态更新日志等级,步骤如下:
在 SOFABoot 工程中定义对应的动态配置类。
示例如下:
import com.alipay.drm.client.DRMClient; import com.alipay.drm.client.api.annotation.DAttribute; import com.alipay.drm.client.api.annotation.DObject; import com.alipay.drm.client.api.model.DependencyLevel; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.logging.LogLevel; import org.springframework.boot.logging.LoggingSystem; @DObject(region="hula", appName ="dynamic-log-level", id ="com.hula.sofa.config.DynamicConfig") public class DynamicConfig{ // 取 application.properties 配置的值作为默认值。 @DAttribute @Value("${logging.level.com.hula.sofa}") private String loglevel; @Autowired LoggingSystem loggingSystem; public void init(){ DRMClient.getInstance().register(this); } public String getLoglevel(){ return loglevel; } public void setLoglevel(String loglevel){ this.loglevel = loglevel; LogLevel level =LogLevel.valueOf(loglevel.toUpperCase()); // 使用 springboot的LoggingSystem 设置目标 logger 的日志等级。 loggingSystem.setLogLevel("com.hula.sofa", level); } }
在 SOFA 微服务平台上新增如下动态配置。
操作步骤,请参见 新增动态配置。
说明在客户端值处,推送成功的情况下不会显示新的值。
重启服务后,为何属性获取的是动态配置推送过的值,而不是默认值?
动态配置的默认用法是:当服务端推送配置后启动,客户端会默认同步加载服务端配置值。如果您不想使用该默认同步加载,需设置 @DAttribute(dependency = DependencyLevel.NONE
。
更多依赖级别,说明如下:
依赖等级 | 依赖描述 |
---|---|
NONE | 无依赖,启动期不加载服务端值。启动此级别后,客户端仅会接收服务端在运行期间产生的配置推送。 |
ASYNC | 异步更新,启动期异步加载服务端值,不关注加载结果。 |
WEAK | 弱依赖,启动期同步加载服务端推送值。
|
STRONG | 强依赖,启动期同步加载服务端值。
|
EAGER | 最强依赖,启动期必须拉取到服务端值。如服务端未推送过值则抛异常,应用启动失败。 |
如何给属性赋初始值?
您可以通过以下方式为属性赋值:
直接在定义式赋值。例如:
private String loglevel = "info"
。从
application.properties
中获取,示例如下:@DAttribute private String loglevel ="info"; //初始值为 info
或
@Value("${logging.level.com.hula.sofa}") @DAttributeprivate String loglevel;
注意请勿在 init 方法里赋值,否则客户端重启后会覆盖推送值,并变回默认值,造成后续推送无法生效。示例如下:
public void init(){ DRMClient.getInstance().register(this); setLoglevel("info"); }
发布部署卡在部署服务中,直到超时,导致发布部署失败
问题现象:
发布部署卡在部署服务中,直到 8 分钟后超时,导致发布部署失败。
问题原因:
在 DRM 中设置了 RefreshCacheDRM.refreshCacheType = GEOHASH
,业务代码在收到该项更新后,需花费十几分钟处理业务逻辑。
解决方案:
临时方案:设置
RefreshCacheDRM.refreshCacheType = null
,这样暂时不会触发业务处理逻辑。长期方案:需要优化您的业务代码,在收到 DRM 的属性更新后,使用异步线程,延迟处理该业务,并及时反馈更新成功的信号给 DRM。