天天看點

調式源碼解決 seata 報錯 can not get cluster name 問題

作者:碼上code

最近在使用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 報錯 can not get cluster name 問題

總結就是需要在用戶端的配置檔案添加配置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:

調式源碼解決 seata 報錯 can not get cluster name 問題

添加配置之後,就不報錯了,文檔有說明:

擷取事務分組(服務啟動時加載配置) spring/springboot可配置在yml、properties中,對應值"my_test_tx_group"即為事務分組名,若不配置則預設以:spring.application.name值+-seata-service-group拼接後的字元串作為分組名。

seata還是按照預設的配置spring.application.name + -seata-service-group去配置中心找配置,上面的配置沒有生效。

調式源碼

報錯是在NettyClientChannelManager類的176行:

調式源碼解決 seata 報錯 can not get cluster name 問題

transactionServiceGroup表示事務分組名,調式到分組名值為nacos-provide-stock-seata-service-group,說明配置seata.tx-service-group沒有生效,就需要找到transactionServiceGroup來源。

一般調式代碼,都是調式下一步,往上調式就用到了調式的上一步:

調式源碼解決 seata 報錯 can not get cluster name 問題

從上面的斷點調式上一步,就定位到RmNettyRemotingClient類的第194行:

調式源碼解決 seata 報錯 can not get cluster name 問題

transactionServiceGroup是一個執行個體變量,需要唯一指派該變量的地方就在RmNettyRemotingClient類的第140行:

調式源碼解決 seata 報錯 can not get cluster name 問題

setTransactionServiceGroup方法被本類的getInstance方法調用,也就是RmNettyRemotingClient類99行,添加斷點,重新開機服務:

調式源碼解決 seata 報錯 can not get cluster name 問題

調式上一步,定位到RMClient類的init方法:

調式源碼解決 seata 報錯 can not get cluster name 問題

調式上一步,定位到GlobalTransactionScanner類的201行:

調式源碼解決 seata 報錯 can not get cluster name 問題

此時txServiceGroup又是一個執行個體變量,找到變量指派的位置:

調式源碼解決 seata 報錯 can not get cluster name 問題

添加斷點之後,重新開機服務,到了斷點,再點選上一步,一直定位到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屬性來設定。

官方文檔更新不及時的時候,這就需要我們調式源碼的能力。前段時間一直在寫解析源碼的文章,是以也在嘗試一步步調式代碼,最終解決了問題,對自己能力也是一次提高。平時開發遇到問題,通過調式源碼,可以快速的定位問題。

授人以魚不如授人以漁,作為程式員,重要的不是找到問題,而是找到問題的解決方案。要追根溯源,做到心中有數,遇問題也不慌。

繼續閱讀