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

Java動態(tài)線程池插件dynamic-tp集成zookeeper

 更新時間:2023年03月02日 09:48:27   作者:Redick01  
ZooKeeper是一個分布式的,開放源碼的分布式應(yīng)用程序協(xié)調(diào)服務(wù),是Google的Chubby一個開源的實現(xiàn),是Hadoop和Hbase的重要組件。它是一個為分布式應(yīng)用提供一致性的軟件,提供的功能包括:配置維護(hù)、域名服務(wù)、分布式同步、組服務(wù)等

前言

dynamic-tp是一個輕量級的動態(tài)線程池插件,它是一個基于配置中心的動態(tài)線程池,線程池的參數(shù)可以通過配置中心配置進(jìn)行動態(tài)的修改,在配置中心的支持上最開始的時候支持NacosApollo,由于筆者公司用的配置中心是Zookeeper,所以就想著擴(kuò)展支持Zookeeper,在了解源碼支持發(fā)現(xiàn)dynamic-tp的擴(kuò)展能力做的很好,提供了擴(kuò)展接口,只要我開發(fā)對應(yīng)的配置中心模塊即可,最終筆者實現(xiàn)了Zookeeper的支持并貢獻(xiàn)到社區(qū)。接下來我通過源碼解析方式介紹下Zookeeper配置中心的接入。

配置刷新

dynamic-tp提供了一個刷新配置的接口Refresher,抽象類AbstractRefresher實現(xiàn)刷新配置接口的刷新配置方法refresh,該方法能根據(jù)配置類型內(nèi)容和配置解析配置并刷新動態(tài)線程池的相關(guān)配置,由DtpRegistry負(fù)責(zé)刷新線程池配置,事件發(fā)布訂閱模式操作Web容器參數(shù),代碼如下:

public interface Refresher {
    /**
     * Refresh with specify content.
     * @param content content
     * @param fileType file type
     */
    void refresh(String content, ConfigFileTypeEnum fileType);
}
@Slf4j
public abstract class AbstractRefresher implements Refresher {
    @Resource
    private DtpProperties dtpProperties;
    @Resource
    private ApplicationEventMulticaster applicationEventMulticaster;
    @Override
    public void refresh(String content, ConfigFileTypeEnum fileTypeEnum) {
        if (StringUtils.isBlank(content) || Objects.isNull(fileTypeEnum)) {
            return;
        }
        try {
            // 根據(jù)配置內(nèi)容和配置類型將配置內(nèi)容轉(zhuǎn)成Map
            val prop = ConfigHandler.getInstance().parseConfig(content, fileTypeEnum);
            doRefresh(prop);
        } catch (IOException e) {
            log.error("DynamicTp refresh error, content: {}, fileType: {}",
                    content, fileTypeEnum, e);
        }
    }
    private void doRefresh(Map<Object, Object> properties) {
        // 將Map中的配置轉(zhuǎn)換成DtpProperties
        ConfigurationPropertySource sources = new MapConfigurationPropertySource(properties);
        Binder binder = new Binder(sources);
        ResolvableType type = ResolvableType.forClass(DtpProperties.class);
        Bindable<?> target = Bindable.of(type).withExistingValue(dtpProperties);
        binder.bind(MAIN_PROPERTIES_PREFIX, target);
        // 刷新動態(tài)線程池配置
        DtpRegistry.refresh(dtpProperties);
        // 發(fā)布刷新實現(xiàn),該事件用于控制Web容器線程池參數(shù)控制
        publishEvent();
    }
    private void publishEvent() {
        RefreshEvent event = new RefreshEvent(this, dtpProperties);
        applicationEventMulticaster.multicastEvent(event);
    }
}

Zookeeper配置中心接入擴(kuò)展實現(xiàn)

基于AbstractRefresher就可以實現(xiàn)Zookeeper配置中心的擴(kuò)展了,Zookeeper的擴(kuò)展實現(xiàn)繼承AbstractRefresher,Zookeeper的擴(kuò)展實現(xiàn)只需要監(jiān)聽配置中心的配置變更即可拿到配置內(nèi)容,然后通過refresh刷新配置即可。代碼如下:

ZookeeperRefresher繼承AbstractRefresher,實現(xiàn)InitializingBean,afterPropertiesSet方法邏輯從配置DtpProperties獲取Zookeeper的配置信息,CuratorFrameworkFactory創(chuàng)建客戶端,設(shè)置監(jiān)聽器,這里有兩種監(jiān)聽器,一個是連接監(jiān)聽ConnectionStateListener,一個是節(jié)點變動監(jiān)聽CuratorListener,出發(fā)監(jiān)聽后loadNode負(fù)責(zé)從Zookeeper獲取配置文件配置并組裝配置內(nèi)容,然后通過refresh刷新配置,注意,Zookeeper配置目前配置類型僅支持properties。

@Slf4j
public class ZookeeperRefresher extends AbstractRefresher implements InitializingBean {
    @Resource
    private DtpProperties dtpProperties;
    private CuratorFramework curatorFramework;
    @Override
    public void afterPropertiesSet() throws Exception {
        DtpProperties.Zookeeper zookeeper = dtpProperties.getZookeeper();
        curatorFramework = CuratorFrameworkFactory.newClient(zookeeper.getZkConnectStr(),
                new ExponentialBackoffRetry(1000, 3));
        String nodePath = ZKPaths.makePath(ZKPaths.makePath(zookeeper.getRootNode(),
                zookeeper.getConfigVersion()), zookeeper.getNode());
        final ConnectionStateListener connectionStateListener = (client, newState) -> {
            if (newState == ConnectionState.CONNECTED || newState == ConnectionState.RECONNECTED) {
                loadNode(nodePath);
            }};
        final CuratorListener curatorListener = (client, curatorEvent) -> {
            final WatchedEvent watchedEvent = curatorEvent.getWatchedEvent();
            if (null != watchedEvent) {
                switch (watchedEvent.getType()) {
                    case NodeChildrenChanged:
                    case NodeDataChanged:
                        loadNode(nodePath);
                        break;
                    default:
                        break;
                }
            }};
        curatorFramework.getConnectionStateListenable().addListener(connectionStateListener);
        curatorFramework.getCuratorListenable().addListener(curatorListener);
        curatorFramework.start();
        log.info("DynamicTp refresher, add listener success, nodePath: {}", nodePath);
    }
    /**
     * load config and refresh
     * @param nodePath config path
     */
    public void loadNode(String nodePath) {
        try {
            final GetChildrenBuilder childrenBuilder = curatorFramework.getChildren();
            final List<String> children = childrenBuilder.watched().forPath(nodePath);
            StringBuilder content = new StringBuilder();
            children.forEach(c -> {
                String n = ZKPaths.makePath(nodePath, c);
                final String nodeName = ZKPaths.getNodeFromPath(n);
                final GetDataBuilder data = curatorFramework.getData();
                String value = "";
                try {
                    value = new String(data.watched().forPath(n), StandardCharsets.UTF_8);
                } catch (Exception e) {
                    log.error("zk config value watched exception.", e);
                }
                content.append(nodeName).append("=").append(value).append("\n");
            });
            refresh(content.toString(), ConfigFileTypeEnum.PROPERTIES);
        } catch (Exception e) {
            log.error("load zk node error, nodePath is {}", nodePath, e);
        }
    }
}

總結(jié)

dynamic-tp對應(yīng)支持配置中心的擴(kuò)展能力做的非常好,筆者通過Zookeeper客戶端CuratorFramework設(shè)置監(jiān)聽的方式進(jìn)行接入,主要監(jiān)聽CuratorFramework客戶端連接建立和斷開的事件和節(jié)點變動的事件實現(xiàn)了動態(tài)線程池參數(shù)的更新。

到此這篇關(guān)于Java動態(tài)線程池插件dynamic-tp集成zookeeper的文章就介紹到這了,更多相關(guān)Java dynamic-tp內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Spring測試 其實很簡單

    Spring測試 其實很簡單

    這篇文章主要為大家詳細(xì)介紹了Spring測試,其實很簡單,揭開集成測試神秘的面紗,感興趣的小伙伴們可以參考一下
    2016-07-07
  • Spring中SmartLifecycle的用法解讀

    Spring中SmartLifecycle的用法解讀

    這篇文章主要介紹了Spring中SmartLifecycle的用法解讀,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-09-09
  • java虛擬機指令dup詳解

    java虛擬機指令dup詳解

    這篇文章主要為大家詳細(xì)介紹了java虛擬機指令dup,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-10-10
  • SpringBoot3快速整合MyBatisPlus的示例代碼

    SpringBoot3快速整合MyBatisPlus的示例代碼

    本文介紹了快速整合MyBatis-Plus到Spring Boot 3項目中,包括依賴引入、代碼生成器使用等,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2024-12-12
  • JDK多版本共存并自由切換的操作指南(本文為JDK8和JDK17)

    JDK多版本共存并自由切換的操作指南(本文為JDK8和JDK17)

    本文介紹了如何在Windows系統(tǒng)上配置多版本JDK(以JDK8和JDK17為例),并通過圖文結(jié)合的方式給大家講解了詳細(xì)步驟,具有一定的參考價值,需要的朋友可以參考下
    2025-03-03
  • 關(guān)于服務(wù)網(wǎng)關(guān)Spring Cloud Zuul(Finchley版本)

    關(guān)于服務(wù)網(wǎng)關(guān)Spring Cloud Zuul(Finchley版本)

    這篇文章主要介紹了關(guān)于服務(wù)網(wǎng)關(guān)Spring Cloud Zuul(Finchley版本),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-03-03
  • SpringBoot整合mybatisplus和druid的示例詳解

    SpringBoot整合mybatisplus和druid的示例詳解

    這篇文章主要介紹了SpringBoot整合mybatisplus和druid的方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-08-08
  • 基于springboot2集成jpa,創(chuàng)建dao的案例

    基于springboot2集成jpa,創(chuàng)建dao的案例

    這篇文章主要介紹了基于springboot2集成jpa,創(chuàng)建dao的案例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-01-01
  • springboot ehcache 配置使用方法代碼詳解

    springboot ehcache 配置使用方法代碼詳解

    EhCache是一個比較成熟的Java緩存框架,Springboot對ehcache的使用非常支持,所以在Springboot中只需做些配置就可使用,且使用方式也簡易,今天給大家分享springboot ehcache 配置使用教程,一起看看吧
    2021-06-06
  • Spring?@bean和@component注解區(qū)別

    Spring?@bean和@component注解區(qū)別

    本文主要介紹了Spring?@bean和@component注解區(qū)別,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-01-01

最新評論

泾源县| 兴海县| 绿春县| 义乌市| 漳浦县| 方城县| 宣城市| 江城| 四会市| 郁南县| 山阴县| 永宁县| 永泰县| 麻江县| 石楼县| 革吉县| 密山市| 天等县| 历史| 许昌县| 中西区| 开江县| 营口市| 赣州市| 安康市| 咸宁市| 靖西县| 乌鲁木齐县| 三明市| 湘阴县| 江北区| 东安县| 忻城县| 清远市| 通江县| 永平县| 桃园县| 定西市| 财经| 江达县| 满城县|