最近在使用Spring Cloud整合分布式事務seata,項目啟動之後,控制台一直報錯:
can not get cluster name in registry config 'service.vgroupMapping.nacos-provide-order-seata-service-group', please make sure registry config correct
can not get cluster name in registry config 'service.vgroupMapping.nacos-provide-order-seata-service-group', please make sure registry config correct
can not get cluster name in registry config 'service.vgroupMapping.nacos-provide-order-seata-service-group', please make sure registry config correct
無法在注冊配置上找到service.vgroupMapping.nacos-provide-order-seata-service-group配置。
問題分析
搭建seata服務,需要用到配置中心,将配置檔案config.txt上傳到Nacos配置中心,其中有一項配置是:
service.vgroupMapping.default_tx_group=default
這個配置和控制台報錯資訊很像:
service.vgroupMapping.nacos-provide-order-seata-service-group
這個配置就是事務分組,從 官網文檔 看到事務分組的配置:
總結就是需要在用戶端的配置檔案添加配置seata.tx-service-group=xxx,seata通過這個配置去Nacos配置中心尋找配置service.vgroupMapping.xxx。
上面導入的配置為service.vgroupMapping.default_tx_group,是以在application.yml檔案添加配置:
seata:
tx-service-group: default_tx_group
項目重新啟動,還是同樣的報錯
既然提示找不到配置,在配中心添加配置檔案nacos-provide-order-seata-service-group:
添加配置之後,就不報錯了,文檔有說明:
擷取事務分組(服務啟動時加載配置) spring/springboot可配置在yml、properties中,對應值"my_test_tx_group"即為事務分組名,若不配置則預設以:spring.application.name值+-seata-service-group拼接後的字元串作為分組名。
seata還是按照預設的配置spring.application.name + -seata-service-group去配置中心找配置,上面的配置沒有生效。
調式源碼
報錯是在NettyClientChannelManager類的176行:
transactionServiceGroup表示事務分組名,調式到分組名值為nacos-provide-stock-seata-service-group,說明配置seata.tx-service-group沒有生效,就需要找到transactionServiceGroup來源。
一般調式代碼,都是調式下一步,往上調式就用到了調式的上一步:
從上面的斷點調式上一步,就定位到RmNettyRemotingClient類的第194行:
transactionServiceGroup是一個執行個體變量,需要唯一指派該變量的地方就在RmNettyRemotingClient類的第140行:
setTransactionServiceGroup方法被本類的getInstance方法調用,也就是RmNettyRemotingClient類99行,添加斷點,重新開機服務:
調式上一步,定位到RMClient類的init方法:
調式上一步,定位到GlobalTransactionScanner類的201行:
此時txServiceGroup又是一個執行個體變量,找到變量指派的位置:
添加斷點之後,重新開機服務,到了斷點,再點選上一步,一直定位到GlobalTransactionAutoConfiguration:
@Bean
public GlobalTransactionScanner globalTransactionScanner() {
String applicationName = applicationContext.getEnvironment()
.getProperty("spring.application.name");
String txServiceGroup = seataProperties.getTxServiceGroup();
if (StringUtils.isEmpty(txServiceGroup)) {
txServiceGroup = applicationName + "-seata-service-group";
seataProperties.setTxServiceGroup(txServiceGroup);
}
return new GlobalTransactionScanner(applicationName, txServiceGroup);
}
txServiceGroup首先通過seataProperties.getTxServiceGroup擷取,如果為null,就使用applicationName + -seata-service-group。
從最終報錯位置看,seataProperties.getTxServiceGroup無法擷取txServiceGroup,先看getTxServiceGroup擷取資料:
@ConfigurationProperties("spring.cloud.alibaba.seata")
public class SeataProperties {
// todo support config Seata server information
/**
* Seata tx service group.default is ${spring.application.name}-seata-service-group.
*/
private String txServiceGroup;
public String getTxServiceGroup() {
return txServiceGroup;
}
public void setTxServiceGroup(String txServiceGroup) {
this.txServiceGroup = txServiceGroup;
}
}
最終發現txServiceGroup是通過配置spring.cloud.alibaba.seata.tx-service-group内容擷取。
問題解決
在application.yml檔案配置配置,
spring:
cloud:
alibaba:
seata:
tx-service-group: default_tx_group
seata擷取到default_tx_group屬性後,在nacos配置中心找到service.vgroupMapping.default_tx_group配置。
總結
- Spring Cloud整合seata,控制台報錯can not get cluster name in registry config 'service.vgroupMa
- 查詢文檔,nacos添加了service.vgroupMapping.xxx配置,就需要在yml檔案上seata.tx-service-group=xxx配置。添加後控制台還是報錯。
- 調式源碼,找到報錯代碼位置,一步一步向上調試,找到分組事務無法設定的原因,最後發現分組事務是根據spring.cloud.alibaba.seata.tx-service-group屬性來設定。
官方文檔更新不及時的時候,這就需要我們調式源碼的能力。前段時間一直在寫解析源碼的文章,是以也在嘗試一步步調式代碼,最終解決了問題,對自己能力也是一次提高。平時開發遇到問題,通過調式源碼,可以快速的定位問題。
授人以魚不如授人以漁,作為程式員,重要的不是找到問題,而是找到問題的解決方案。要追根溯源,做到心中有數,遇問題也不慌。