DRM 常見問題
本文匯介紹動態(tài)配置(DRM)在使用過程中遇到的常見問題及解決方法。
如何利用 DRM 動態(tài)設(shè)置日志等級?
基于 SOFABoot 開發(fā)的程序,對于日志有如下默認(rèn)配置:
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 來動態(tài)更新日志等級,步驟如下:
在 SOFABoot 工程中定義對應(yīng)的動態(tài)配置類。
示例如下:
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 配置的值作為默認(rèn)值。 @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 設(shè)置目標(biāo) logger 的日志等級。 loggingSystem.setLogLevel("com.hula.sofa", level); } }
在 SOFA 微服務(wù)平臺上新增如下動態(tài)配置。
操作步驟,請參見 新增動態(tài)配置。
說明在客戶端值處,推送成功的情況下不會顯示新的值。
重啟服務(wù)后,為何屬性獲取的是動態(tài)配置推送過的值,而不是默認(rèn)值?
動態(tài)配置的默認(rèn)用法是:當(dāng)服務(wù)端推送配置后啟動,客戶端會默認(rèn)同步加載服務(wù)端配置值。如果您不想使用該默認(rèn)同步加載,需設(shè)置 @DAttribute(dependency = DependencyLevel.NONE
。
更多依賴級別,說明如下:
依賴等級 | 依賴描述 |
---|---|
NONE | 無依賴,啟動期不加載服務(wù)端值。啟動此級別后,客戶端僅會接收服務(wù)端在運(yùn)行期間產(chǎn)生的配置推送。 |
ASYNC | 異步更新,啟動期異步加載服務(wù)端值,不關(guān)注加載結(jié)果。 |
WEAK | 弱依賴,啟動期同步加載服務(wù)端推送值。
|
STRONG | 強(qiáng)依賴,啟動期同步加載服務(wù)端值。
|
EAGER | 最強(qiáng)依賴,啟動期必須拉取到服務(wù)端值。如服務(wù)端未推送過值則拋異常,應(yīng)用啟動失敗。 |
如何給屬性賦初始值?
您可以通過以下方式為屬性賦值:
直接在定義式賦值。例如:
private String loglevel = "info"
。從
application.properties
中獲取,示例如下:@DAttribute private String loglevel ="info"; //初始值為 info
或
@Value("${logging.level.com.hula.sofa}") @DAttributeprivate String loglevel;
注意請勿在 init 方法里賦值,否則客戶端重啟后會覆蓋推送值,并變回默認(rèn)值,造成后續(xù)推送無法生效。示例如下:
public void init(){ DRMClient.getInstance().register(this); setLoglevel("info"); }
發(fā)布部署卡在部署服務(wù)中,直到超時,導(dǎo)致發(fā)布部署失敗
問題現(xiàn)象:
發(fā)布部署卡在部署服務(wù)中,直到 8 分鐘后超時,導(dǎo)致發(fā)布部署失敗。
問題原因:
在 DRM 中設(shè)置了 RefreshCacheDRM.refreshCacheType = GEOHASH
,業(yè)務(wù)代碼在收到該項更新后,需花費(fèi)十幾分鐘處理業(yè)務(wù)邏輯。
解決方案:
臨時方案:設(shè)置
RefreshCacheDRM.refreshCacheType = null
,這樣暫時不會觸發(fā)業(yè)務(wù)處理邏輯。長期方案:需要優(yōu)化您的業(yè)務(wù)代碼,在收到 DRM 的屬性更新后,使用異步線程,延遲處理該業(yè)務(wù),并及時反饋更新成功的信號給 DRM。