中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》
  • 首頁 > 
  • 教程 > 
  • 開發技術 > 
  • springboot使用zookeeper(curator)實現注冊發現與負載均衡的方法

springboot使用zookeeper(curator)實現注冊發現與負載均衡的方法

發布時間:2020-10-22 16:39:19 來源:億速云 閱讀:546 作者:小新 欄目:開發技術

小編給大家分享一下springboot使用zookeeper(curator)實現注冊發現與負載均衡的方法,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!

最簡單的實現服務高可用的方法就是集群化,也就是分布式部署,但是分布式部署會帶來一些問題。比如:

1、各個實例之間的協同(鎖)

2、負載均衡

3、熱刪除

這里通過一個簡單的實例來說明如何解決注冊發現和負載均衡。

 

1、先解決依賴,這里只給出zk相關的依賴,pom.xml如下

  
            org.apache.zookeeper
            zookeeper
            3.4.8
        
        
            org.apache.curator
            curator-recipes
            2.9.1
        

        
            org.apache.curator
            curator-client
            2.9.1  

 

2、ZkClient

這里使用的是curator,curator是對zookeeper的簡單封裝,提供了一些集成的方法,或者是提供了更優雅的api,舉例來說

zk的create(path, mode, acl, data)方法 == curator create().withMode(mode).forPath(path)調用鏈

package com.dqa.prometheus.client.zookeeper;import org.apache.curator.RetryPolicy;import org.apache.curator.framework.CuratorFramework;import org.apache.curator.framework.CuratorFrameworkFactory;import org.apache.curator.retry.ExponentialBackoffRetry;import org.apache.zookeeper.CreateMode;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import java.net.InetAddress;import java.util.ArrayList;import java.util.List;public class ZkClient {    private final Logger logger = LoggerFactory.getLogger(this.getClass());    private CuratorFramework client;    private String zookeeperServer;    private int sessionTimeoutMs;    private int connectionTimeoutMs;    private int baseSleepTimeMs;    private int maxRetries;    public void setZookeeperServer(String zookeeperServer) {        this.zookeeperServer = zookeeperServer;
    }    public String getZookeeperServer() {        return zookeeperServer;
    }    public void setSessionTimeoutMs(int sessionTimeoutMs) {        this.sessionTimeoutMs = sessionTimeoutMs;
    }    public int getSessionTimeoutMs() {        return sessionTimeoutMs;
    }    public void setConnectionTimeoutMs(int connectionTimeoutMs) {        this.connectionTimeoutMs = connectionTimeoutMs;
    }    public int getConnectionTimeoutMs() {        return connectionTimeoutMs;
    }    public void setBaseSleepTimeMs(int baseSleepTimeMs) {        this.baseSleepTimeMs = baseSleepTimeMs;
    }    public int getBaseSleepTimeMs() {        return baseSleepTimeMs;
    }    public void setMaxRetries(int maxRetries) {        this.maxRetries = maxRetries;
    }    public int getMaxRetries() {        return maxRetries;
    }    public void init() {
        RetryPolicy retryPolicy = new ExponentialBackoffRetry(baseSleepTimeMs, maxRetries);
        client = CuratorFrameworkFactory.builder().connectString(zookeeperServer).retryPolicy(retryPolicy)
                .sessionTimeoutMs(sessionTimeoutMs).connectionTimeoutMs(connectionTimeoutMs).build();
        client.start();
    }    public void stop() {
        client.close();
    }    public CuratorFramework getClient() {        return client;
    }    public void register() {        try {
            String rootPath = "/" + "services";
            String hostAddress = InetAddress.getLocalHost().getHostAddress();
            String serviceInstance = "prometheus" + "-" +  hostAddress + "-";
            client.create().creatingParentsIfNeeded().withMode(CreateMode.EPHEMERAL_SEQUENTIAL).forPath(rootPath + "/" + serviceInstance);
        } catch (Exception e) {
            logger.error("注冊出錯", e);
        }
    }    public List getChildren(String path) {
        List childrenList = new ArrayList<>();        try {
            childrenList = client.getChildren().forPath(path);
        } catch (Exception e) {
            logger.error("獲取子節點出錯", e);
        }        return childrenList;
    }    public int getChildrenCount(String path) {        return getChildren(path).size();
    }    public List getInstances() {        return getChildren("/services");
    }    public int getInstancesCount() {        return getInstances().size();
    }
}

2、configuration如下

package com.dqa.prometheus.configuration;import com.dqa.prometheus.client.zookeeper.ZkClient;import org.springframework.beans.factory.annotation.Value;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;

@Configurationpublic class ZkConfiguration {
    @Value("${zookeeper.server}")    private String zookeeperServer;
    @Value(("${zookeeper.sessionTimeoutMs}"))    private int sessionTimeoutMs;
    @Value("${zookeeper.connectionTimeoutMs}")    private int connectionTimeoutMs;
    @Value("${zookeeper.maxRetries}")    private int maxRetries;
    @Value("${zookeeper.baseSleepTimeMs}")    private int baseSleepTimeMs;

    @Bean(initMethod = "init", destroyMethod = "stop")    public ZkClient zkClient() {
        ZkClient zkClient = new ZkClient();
        zkClient.setZookeeperServer(zookeeperServer);
        zkClient.setSessionTimeoutMs(sessionTimeoutMs);
        zkClient.setConnectionTimeoutMs(connectionTimeoutMs);
        zkClient.setMaxRetries(maxRetries);
        zkClient.setBaseSleepTimeMs(baseSleepTimeMs);        return zkClient;
    }

}

配置文件如下

    #============== zookeeper ===================
    zookeeper.server=10.93.21.21:2181,10.93.18.34:2181,10.93.18.35:2181
    zookeeper.sessionTimeoutMs=6000
    zookeeper.connectionTimeoutMs=6000
    zookeeper.maxRetries=3
    zookeeper.baseSleepTimeMs=1000

3、注冊發現

是通過上面封裝的ZkClient中的register方法實現的,調用如下。

package com.dqa.prometheus;

import com.dqa.prometheus.client.zookeeper.ZkClient;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.orm.jpa.EntityScan;
import org.springframework.context.ApplicationContext;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;

@SpringBootApplication
@EnableAsync
@EnableScheduling
@EntityScan(basePackages="com.xiaoju.dqa.prometheus.model")
public class Application {
    public static void main(String[] args) {
        ApplicationContext context = SpringApplication.run(Application.class, args);
        ZkClient zkClient = context.getBean(ZkClient.class);
        zkClient.register();
    }
}

注冊代碼說明:

 public void register() {        try {
            String rootPath = "/" + "services";
            String hostAddress = InetAddress.getLocalHost().getHostAddress();
            String serviceInstance = "prometheus" + "-" +  hostAddress + "-";
            client.create().creatingParentsIfNeeded().withMode(CreateMode.EPHEMERAL_SEQUENTIAL).forPath(rootPath + "/" + serviceInstance);
        } catch (Exception e) {
            logger.error("注冊出錯", e);
        }
    }

1、zk中的注冊路徑

/services/prometheus-10.93.21.21-00000000001

2、CreateMode有四種,選擇EPHEMERAL_SEQUENTIAL的原因是,服務關閉的時候session超時,zk節點會自動刪除,同時自增id可以實現鎖和負載均衡,下面再說

1、PERSISTENT

持久化目錄節點,存儲的數據不會丟失。2、PERSISTENT_SEQUENTIAL

順序自動編號的持久化目錄節點,存儲的數據不會丟失,并且根據當前已近存在的節點數自動加 1,然后返回給客戶端已經成功創建的目錄節點名。3、EPHEMERAL

臨時目錄節點,一旦創建這個節點的客戶端與服務器端口也就是session 超時,這種節點會被自動刪除。 

4、EPHEMERAL_SEQUENTIAL

臨時自動編號節點,一旦創建這個節點的客戶端與服務器端口也就是session 超時,這種節點會被自動刪除,并且根據當前已近存在的節點數自動加 1,然后返回給客戶端已經成功創建的目錄節點名。

4、負載均衡

     /*
        *   我是第幾個實例, 做負載均衡
        * */
        List instanceList = zkClient.getInstances();
        Collections.sort(instanceList);
        String hostAddress = NetFunction.getAddressHost();        int instanceNo = 0;        if (hostAddress !=  null) {            for (int i=0; i waitingTasks = checkTaskDao.getTasks(taskType, TaskStatus.WAITING.getValue());
        Iterator waitingIterator = waitingTasks.iterator();        while (waitingIterator.hasNext()) {            if (waitingIterator.next().getTaskId().hashCode() % instanceCount != instanceNo) {
                waitingIterator.remove();
            }
        }

說明:

1、例如有3個實例(zkClient.getInstances()),那么通過IP我們把3個實例按照自增id排序分別標號為0,1,2

2、對第一個實例也就是instanceNo=0,只執行taskId.hashCode() % 3 == 0的任務,其他兩個實例類似

3、當有一個實例掛掉,2個實例,instanceNo=0只執行taskId.hashCode() % 2 == 0的任務,實現熱刪除

以上是springboot使用zookeeper(curator)實現注冊發現與負載均衡的方法的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業資訊頻道!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

清丰县| 从江县| 富裕县| 霍林郭勒市| 金昌市| 尚志市| 抚顺市| 耿马| 康平县| 昭通市| 中方县| 福鼎市| 宝应县| 华池县| 甘南县| 儋州市| 商都县| 长葛市| 兰州市| 荥经县| 平潭县| 义马市| 巴塘县| 两当县| 定边县| 甘泉县| 六枝特区| 台中县| 黔东| 白水县| 定结县| 赤水市| 宁南县| 公主岭市| 开鲁县| 中宁县| 英山县| 襄樊市| 瑞丽市| 龙游县| 榆树市|