最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

TC?集群Seata1.6高可用架構(gòu)源碼解析

 更新時間:2022年12月26日 09:23:26   作者:Applehope  
這篇文章主要為大家介紹了TC?集群Seata1.6高可用架構(gòu)源碼解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪

一、背景

TC 集群具有高可用架構(gòu),應(yīng)用到集群是這樣一個間接的關(guān)系:應(yīng)用 -》事務(wù)分組 -》TC 集群,應(yīng)用啟動后所指定的事務(wù)分組不能變,可通過配置中心變更事務(wù)分組所屬的 TC 集群,Seata 客戶端監(jiān)聽到這個變更后,會切換到新的 TC 集群。

本篇從源碼梳理這個高可用能力是如何實現(xiàn)的。

二、環(huán)境配置

客戶端配置使用nacos配置中心和nacos注冊中心,

seata:
  enabled: true
  # Seata 應(yīng)用編號
  application-id: seataclistock
  # Seata 事務(wù)組編號,用于 TC 集群名。該配置需要與服務(wù)端提到的group相對應(yīng),也需要與下面的相對應(yīng)
  tx-service-group: tx_group_stock
  # 關(guān)閉自動代理
  enable-auto-data-source-proxy: false
  config:
    # support: nacos, consul, apollo, zk, etcd3
    type: nacos
    nacos:
      serverAddr: 
      namespace: seata # 需要與服務(wù)端添加的配置文件相同
      group: SEATA_GROUP_ROCKTEST
      username: seata
      password: seata
      data-id: seataClient.tx_group_busin.properties
  registry:
    # support: nacos, eureka, redis, zk, consul, etcd3, sofa
    type: nacos
    nacos:
      application: seata-server
      serverAddr: 
      namespace: seata  # 需要與服務(wù)端添加的配置文件相同
      group: SEATA_GROUP_ROCKTEST   # 需要與服務(wù)端添加的配置文件相同
      username: seata
      password: seata

三、從配置中心獲取TC集群

服務(wù)注冊的能力要依賴配置中心,從nacos的配置中心獲取配置NacosConfiguration#initSeataConfig

Data Id:seataClient.tx_group_stock.properties

Group:SEATA_GROUP_LWKTEST

其中的service.vgroupMapping.tx_group_stock的值是dev_cluster_1,接下來注冊能力就要使用這個集群來工作。

private static void initSeataConfig() {
    try {
        String nacosDataId = getNacosDataId();
        String config = configService.getConfig(nacosDataId, getNacosGroup(), DEFAULT_CONFIG_TIMEOUT);
        if (StringUtils.isNotBlank(config)) {
            seataConfig = ConfigProcessor.processConfig(config, getNacosDataType());
            NacosListener nacosListener = new NacosListener(nacosDataId, null);
            configService.addListener(nacosDataId, getNacosGroup(), nacosListener);
        }
    } catch (NacosException | IOException e) {
        LOGGER.error("init config properties error", e);
    }
}

RegistryFactory#getInstance()這是個單例機制,所以源碼梳理起來很簡單,下邊獲取TC服務(wù)的時候會調(diào)用此單例方法做初始化。

  • 讀取配置文件中registry.type,
  • 配置的值是nacos,所以讀出的值是nacos
  • 通過SPI加載并實例化 NacosRegistryProvider
public class RegistryFactory {
    /**
     * Gets instance.
     *
     * @return the instance
     */
    public static RegistryService getInstance() {
        return RegistryFactoryHolder.INSTANCE;
    }
    private static RegistryService buildRegistryService() {
        RegistryType registryType;
        //registryTypeName = "registry.type"
        String registryTypeName = ConfigurationFactory.CURRENT_FILE_INSTANCE.getConfig(
            ConfigurationKeys.FILE_ROOT_REGISTRY + ConfigurationKeys.FILE_CONFIG_SPLIT_CHAR
                + ConfigurationKeys.FILE_ROOT_TYPE);
        try {
            // nacos
            registryType = RegistryType.getType(registryTypeName);
        } catch (Exception exx) {
            throw new NotSupportYetException("not support registry type: " + registryTypeName);
        }
        // 通過SPI 加載并實例化 NacosRegistryProvider
        return EnhancedServiceLoader.load(RegistryProvider.class, Objects.requireNonNull(registryType).name()).provide();
    }
    private static class RegistryFactoryHolder {
        private static final RegistryService INSTANCE = buildRegistryService();
    }
}

TM、RM 客戶端需要與TC通信,所以在其初始化時必然會有獲取TC集群的邏輯,對應(yīng)在源碼TmNettyRemotingClient#init 中的reconnect方法。

@Override
public void init() {
    // registry processor
    registerProcessor();
    if (initialized.compareAndSet(false, true)) {
        //父類中會開啟定時任務(wù)來執(zhí)行 getClientChannelManager().reconnect(transactionServiceGroup)
        super.init();
        if (io.seata.common.util.StringUtils.isNotBlank(transactionServiceGroup)) {
            getClientChannelManager().reconnect(transactionServiceGroup);
        }
    }
}

reconnect中的.NettyClientChannelManager#getAvailServerList 是根據(jù)seata.tx-service-group的值來檢索TC集群信息。直接提供出來調(diào)用堆棧,方便大家快速熟悉調(diào)用鏈路:

getServiceGroup:111, RegistryService (io.seata.discovery.registry)
lookup:145, NacosRegistryServiceImpl (io.seata.discovery.registry.nacos)
getAvailServerList:257, NettyClientChannelManager (io.seata.core.rpc.netty)
reconnect:171, NettyClientChannelManager (io.seata.core.rpc.netty)
init:198, TmNettyRemotingClient (io.seata.core.rpc.netty)
init:47, TMClient (io.seata.tm)
initClient:220, GlobalTransactionScanner (io.seata.spring.annotation)
afterPropertiesSet:512, GlobalTransactionScanner (io.seata.spring.annotation)

這里便是通過Seata客戶端 seata.tx-service-group的值,找到最終TC集群的關(guān)鍵之處。在getServiceGroup中從nacos中獲取service.vgroupMapping.tx_group_stock的值,即dev_cluster_1

default String getServiceGroup(String key) {
    //key = service.vgroupMapping.tx_group_stock
    key = PREFIX_SERVICE_ROOT + CONFIG_SPLIT_CHAR + PREFIX_SERVICE_MAPPING + key;
    if (!SERVICE_GROUP_NAME.contains(key)) {
        ConfigurationCache.addConfigListener(key);
        SERVICE_GROUP_NAME.add(key);
    }
    return ConfigurationFactory.getInstance().getConfig(key);
}

然后NettyClientChannelManager#reconnect中獲取 TC 集群中的所有 TC 服務(wù)節(jié)點,對每個TC 服務(wù)節(jié)點建連。

for (String serverAddress : availList) {
    try {
        acquireChannel(serverAddress);
        channelAddress.add(serverAddress);
    } catch (Exception e) {
        LOGGER.error("{} can not connect to {} cause:{}", FrameworkErrorCode.NetConnect.getErrCode(),
            serverAddress, e.getMessage(), e);
    }
}

再梳理一下,梳理這么多的關(guān)鍵就是通過tx_group_stock 找到 TC 集群 dev_cluster_1

客戶端:

seata:
  # 默認關(guān)閉,如需啟用spring.datasource.dynami.seata需要同時開啟
  enabled: true
  # Seata 事務(wù)組編號,用于 TC 集群名。該配置需要與服務(wù)端提到的group相對應(yīng),也需要與下面的相對應(yīng)
  tx-service-group: tx_group_stock

nacos:

Data ID: seataClient.tx_group_stock.properties
Group: SEATA_GROUP_ROCKTEST
配置內(nèi)容:
    ...
    service.vgroupMapping.tx_group_stock=dev_cluster_1
    ...

TC服務(wù)端:

registry:
  # support: nacos 、 eureka 、 redis 、 zk  、 consul 、 etcd3 、 sofa
  type: nacos
  preferred-networks: 30.240.*
  nacos:
    application: seata-server
    cluster: dev_cluster_1

RegistryService#getServiceGroup中從nacos獲取值的時候,有個細節(jié)需要注意:通過namespace + Group + Key(Data Id) 三維來唯一標(biāo)示一個Key。

四、刷新TC集群

AbstractNettyRemotingClient#init中默認會每隔10s進行一次 TC 服務(wù)清單刷新與重連

timerExecutor.scheduleAtFixedRate(new Runnable() {
    @Override
    public void run() {
        clientChannelManager.reconnect(getTransactionServiceGroup());
    }
}, SCHEDULE_DELAY_MILLS, SCHEDULE_INTERVAL_MILLS, TimeUnit.MILLISECONDS);

以上就是TC 集群Seata1.6高可用架構(gòu)源碼解析的詳細內(nèi)容,更多關(guān)于TC 集群Seata高可用架構(gòu)的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • java二分查找插入法

    java二分查找插入法

    當(dāng)你需要構(gòu)建一個大的有序隊列,用插入發(fā)太慢了,可以先用二分查找法,找到在隊列要插入的位置,把數(shù)后移一下,然后放進去。比較效率,下面是java使用示例,需要的朋友可以參考下
    2014-03-03
  • Spring Cloud Gateway調(diào)用Feign異步問題記錄

    Spring Cloud Gateway調(diào)用Feign異步問題記錄

    這篇文章主要介紹了Spring Cloud Gateway調(diào)用Feign異步問題記錄,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-04-04
  • JDK10新特性之本地變量類型var的深入理解

    JDK10新特性之本地變量類型var的深入理解

    這篇文章主要給大家介紹了J關(guān)于DK10新特性之本地變量類型var的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家學(xué)習(xí)或者使用JDK10具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-05-05
  • Java實現(xiàn)文件上傳保存

    Java實現(xiàn)文件上傳保存

    這篇文章主要為大家詳細介紹了Java實現(xiàn)文件上傳保存,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-06-06
  • SpringBoot如何取消內(nèi)置Tomcat啟動并改用外接Tomcat

    SpringBoot如何取消內(nèi)置Tomcat啟動并改用外接Tomcat

    這篇文章主要介紹了SpringBoot如何取消內(nèi)置Tomcat啟動并改用外接Tomcat,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2019-11-11
  • Spring Boot中的Properties的使用詳解

    Spring Boot中的Properties的使用詳解

    這篇文章主要介紹了Spring Boot中的Properties的使用詳解,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-02-02
  • 理解Java的序列化與反序列化

    理解Java的序列化與反序列化

    這篇文章主要為大家詳細介紹了Java的序列化與反序列化,序列化是一種對象持久化的手段。普遍應(yīng)用在網(wǎng)絡(luò)傳輸、RMI等場景中。本文通過分析ArrayList的序列化來介紹Java序列化的相關(guān)內(nèi)容,感興趣的小伙伴們可以參考一下
    2016-02-02
  • 使用SpringBoot AOP 記錄操作日志、異常日志的過程

    使用SpringBoot AOP 記錄操作日志、異常日志的過程

    這篇文章主要介紹了使用SpringBoot AOP 記錄操作日志、異常日志的過程,本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-05-05
  • MP(MyBatis-Plus)實現(xiàn)樂觀鎖更新功能的示例代碼

    MP(MyBatis-Plus)實現(xiàn)樂觀鎖更新功能的示例代碼

    這篇文章主要介紹了MP(MyBatis-Plus)實現(xiàn)樂觀鎖更新功能的示例代碼,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-01-01
  • springboot集成mybatisplus的方法

    springboot集成mybatisplus的方法

    這篇文章主要為大家詳細介紹了springboot集成mybatisplus的相關(guān)資料,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-04-04

最新評論

洪洞县| 河南省| 旅游| 建德市| 永定县| 宁蒗| 丰宁| 荥阳市| 枣强县| 措勤县| 盐边县| 永安市| 宁晋县| 枞阳县| 酒泉市| 马关县| 淄博市| 保靖县| 罗田县| 准格尔旗| 奈曼旗| 革吉县| 宣恩县| 米林县| 阳泉市| 琼海市| 石城县| 政和县| 资阳市| 沿河| 沁水县| 巴里| 天峨县| 浦北县| 蕲春县| 静乐县| 西青区| 冕宁县| 天台县| 白山市| 车险|