国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

實現高可用的兩種方案與實戰

seal_de / 1074人閱讀

摘要:高可用的首要想法就是雙機熱備,故障時自動切換,所以我們要給加一個備機。注下面實現高可用都用的是雙機熱備,為了方便,把調度服務器簡稱為主機,把調度服務器的備機簡稱為備機。

我之前在一片文章 用Nginx+Redis實現session共享的均衡負載 中做了一個負載均衡的實驗,其主要架構如下:

debian1作為調度服務器承擔請求分發的任務,即用戶訪問的是debian1,然后debain1把請求按照一定的策略發送給應用服務器:debian2或者debain3,甚至更多的debain4、5、6......

狀態數據可以放在外部的分布式緩存服務分布式數據庫服務中,這樣應用服務本身就是無狀態的,所以機器增減都是很容易的,應用的高可用是有保證的(對于有狀態的高可用不僅要注意機器增減與切換、還要注意備份冗余、數據一致性等問題)。但是當時忽略了一個地方,那就是調度服務器debian1本身的高可用性沒有考慮到,存在單點問題。

高可用的首要想法就是雙機熱備,故障時自動切換,所以我們要給debian1加一個備機debain1"。我現在按照自己的知識粗淺的把解決方案分為兩類:客戶端有感知的高可用、對客戶端透明的高可用,并分別挑選一個示例做一下實驗。

注:下面實現高可用都用的是雙機熱備,為了方便,把調度服務器debian1簡稱為主機,把調度服務器debian1的備機debian1"簡稱為備機。

客戶端有感知的高可用

客戶端有感知的高可用,也就是需要客戶端的配合,客戶端自己去確認服務器的變更并切換訪問的目標。比如說我們的主機、備機都在ZooKeeper(或者其他類似的注冊中心比如redis)中進行注冊,客戶端監聽ZooKeeper中服務器的信息,發現主機下線自己就切換訪問備機即可。

ZooKeeper偽集群搭建

首先在本機搭建包含3個節點的ZooKeeper偽集群。在官網下載版本3.5.4-beta,解壓,然后復制3份,每一份都要做如下操作:

進入conf文件夾 創建一個配置文件zoo.cfg。代碼如下:

    initLimit=10
    syncLimit=5
    clientPort=2181(每個節點不同:2181,3181,4181)
    tickTime=2000
    dataDir=E:/zookeeper-3.5.4-1/data(每個節點不同:3.5.4-2,3.5.4-3)
    dataLogDir=E:/zookeeper-3.5.4-1/datalog(每個節點不同,同上)
    server.1=192.168.*.*::2888:3888(實驗機器的局域網IP或者直接localhost)
    server.2=192.168.*.*::4888:5888
    server.3=192.168.*.*::6888:7888
    

創建上面的dataDirdataLogDir,并在dataDir目錄下必須創建myid文件,寫入不同的整數ID,也就是上面的server.x的x,比如1

分別進入bin目錄,在zkServer.cmdcall之前加入set ZOOCFG=../conf/zoo.cfg 并用其啟動。

順帶一提,代碼開發我就使用我之前的項目CHKV了,因為這個項目中的NameNode或者DataNode也可以用ZooKeeper實現高可用,歡迎和我一起完善這個項目,一塊進步。

調度服務端開發

調度服務器主要向ZooKeeper注冊自己,并向客戶端提供服務。我們使用curator框架來和ZooKeeper交互,特別要注意版本問題。

主要代碼如下:

public static void main(String... arg) throws Exception {

    thisNode = ManagementFactory.getRuntimeMXBean().getName();
    logger.debug("my pid: {}",thisNode);

    // 構造連接
    CuratorFramework curator = CuratorFrameworkFactory
            .builder()
            .connectString(CONNECT_ADDR)
            .connectionTimeoutMs(CONNECTION_TIMEOUT)//連接創建超時時間
            .sessionTimeoutMs(SESSION_TIMEOUT)//會話超時時間
            .retryPolicy(policy)
            .build();
    curator.start();

    // 創建節點也就是成為master,阻塞等待
    boolean result = becomeMaster(curator);
    if (result){
        logger.info("Successfully Became Master");
    }else {
        logger.info("Failed to Became Master");
    }

    // 監聽
    NodeCache cache = new NodeCache(curator, MASTER_NODE_PATH,false);
    cache.getListenable().addListener(()->{
        ChildData data = cache.getCurrentData();
        if (data != null){
            String path = data.getPath();
            Stat stat = data.getStat();
            String dataString = new String(data.getData());
            logger.debug("masterNode info, path:{},data:{},stat,{}",path,dataString,stat);
        }else {
            logger.info("masterNode is down, try to become Master");
            if (becomeMaster(curator)){
                logger.info("Successfully tried to Became Master");
            }else {
                logger.info("Failed to try to Became Master");

            }
        }
    });
    cache.start(true);
}

// 確認master
private static boolean confirm(CuratorFramework curator) throws Exception {
    masterNode = new String(curator.getData().forPath(MASTER_NODE_PATH));
    logger.info("masterNode: {}",masterNode);
    return thisNode.equals(masterNode);

}

// 成為master
private static boolean becomeMaster(CuratorFramework curator) throws Exception {
    String path= "";
    try {
         path =  curator.create()
                .creatingParentContainersIfNeeded()
                .withMode(CreateMode.EPHEMERAL)
                .forPath(MASTER_NODE_PATH,thisNode.getBytes());
        logger.debug(path);
    }catch (Exception e){
        logger.error(e.getMessage());
    }
    return MASTER_NODE_PATH.equals(path);
}

完整代碼在GitHub上。

客戶端開發

客戶端主要向ZooKeeper監聽調度服務器變更事件,并向其發起應用請求。實際上應用服務器也可以使用這部分代碼來監聽調度服務器的變化。

主要代碼如下:

public static void main(String... arg) throws Exception {

    CuratorFramework curator = CuratorFrameworkFactory
            .builder()
            .connectString(CONNECT_ADDR)
            .connectionTimeoutMs(CONNECTION_TIMEOUT)
            .sessionTimeoutMs(SESSION_TIMEOUT)
            .retryPolicy(policy)
            .build();
    curator.start(); 

    NodeCache cache = new NodeCache(curator, MASTER_NODE_PATH,false);
    cache.getListenable().addListener(()->{
        ChildData data = cache.getCurrentData();
        if (data != null){
            String path = data.getPath();
            Stat stat = data.getStat();
            String dataString = new String(data.getData());
            logger.debug("masterNode info, path:{},data:{},stat,{}",path,dataString,stat);
            masterInfo = dataString;
        }else {
            logger.info("masterNode is down, waiting");
        }
    });
    cache.start(true);

    // 獲得主機,阻塞等待  
    try {
        masterInfo =  new String(curator.getData().forPath(MASTER_NODE_PATH));
    }catch (Exception e){
        logger.error("no masterInfo");
        masterInfo = null;
    }
    while (masterInfo==null);
    logger.info("masterInfo:{}",masterInfo);

}

完整代碼在GitHub上。

對客戶端透明的高可用

對客戶端透明的高可用,也就是客戶端不需要做什么工作,服務器切換不切換客戶端根本不知道也不關心。主要實現方式有兩種,一種是客戶端通過域名訪問主機,那么監控主機下線后就把域名重新分配給備機,當然這個切換會有時間成本,視定義的DNS緩存時間而定;第二種就是客戶端通過IP訪問主機,監控到主機下線后就通過IP漂移技術把對外的IP(或者說虛擬IP)分配給備機,這樣就能做到及時的切換。

實際環境中常常使用keepalived來實現IP漂移。

搭建過程參考了The keepalived solution for LVS和官網文檔

首先主機、備機都要安裝keepalived,然后配置主機/etc/keepalived/keepalived.conf

vrrp_instance VI_1 {
    state MASTER       # MASTER表示此實例是主機,BACKUP表示此實例是備機
    interface eth0     # 網卡名稱,亦即網絡接口
    virtual_router_id 51
    priority 100
    advert_int 1       # 心跳檢查時間間隔,單位秒
    authentication {   # 認證方式 是 密碼的方式
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {# 虛擬IP地址,也就是對外開放的IP
        10.23.8.80
    }
}
    
virtual_server 10.23.8.80 80 {    # 虛擬服務器,也就是對外開放的IP與端口
    delay_loop 6
    lb_algo wlc                   # 負載均衡調度算法 此處是 加權最少連接
    lb_kind NAT                   # 有 DR,NAT,TUN三種     
    persistence_timeout 600
    protocol TCP

    real_server 172.18.1.11 80 {# 后端的 應用服務器
        weight 100              # 節點的權重
        TCP_CHECK {
            connect_timeout 3   # 3秒超時
        }
    }
    real_server 172.18.1.12 80 {# 后端的 應用服務器
        weight 100
        TCP_CHECK {
            connect_timeout 3
        }
    }
    real_server 172.18.1.13 80 {# 后端的 應用服務器
        weight 100
        TCP_CHECK {
            connect_timeout 3
        }
    }
}

配置備機/etc/keepalived/keepalived.conf,與主機類似,但是state是backup,且權重較低即可:

vrrp_instance VI_1 {
    state BACKUP
    interface eth1
    virtual_router_id 51
    priority 90
    advert_int 1
    authentication { 
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        10.23.8.80
    }
}

反思

說白了,這兩種高可用的實現方式前者是在應用層實現的,而后者是在傳輸層實現的,那么我們就可以想到,計算機網絡的每一層其實都是可以做負載均衡和高可用的。

查看原文,來自MageekChiu

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/69420.html

相關文章

  • 初識架構之可用

    摘要:以集群部署的方式提供服務,確保高可用。無狀態服務,一樣可以通過負載均衡加心跳檢測等手段去部署集群,確保故障轉移來做到高可用。初步原理的一致性可用性分區容錯性。高可用開發流程服務發布通過切流量的方式一臺臺灰度發布。用于預發布驗證。 架構和架構師,可以說是大部分技術人的目標或追求吧。 但架構類比于內功或修為,它不是一門武功,不能學一招走天下。 同一個架構方案在不同公司甚至不同團隊都不一定能...

    lk20150415 評論0 收藏0
  • 必看!java后端,亮劍誅仙(最全知識點)

    摘要:鑒于目前大多數服務器環境都是,提前接觸能夠相輔相成。正則也是必須要掌握的一個知識點。有多種創建多線程的方式,不過目前使用線程池的多一些。 原創:小姐姐味道(微信公眾號ID:xjjdog),歡迎分享,轉載請保留出處。 你可能有所感悟。零散的資料讀了很多,但是很難有提升。到處是干貨,但是并沒什么用,簡單來說就是缺乏系統化。另外,噪音太多,雷同的框架一大把,我不至于全都要去學了吧。 這里,我...

    陳江龍 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<