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

2021-09-13 18:23:05 字數 4385 閱讀 7539

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

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

狀態資料可以放在外部的分布式快取服務分布式資料庫服務中,這樣應用服務本身就是無狀態的,所以機器增減都是很容易的,應用的高可用是***的(對於有狀態的高可用不僅要注意機器增減與切換、還要注意備份冗餘資料一致性等問題)。但是當時忽略了乙個地方,那就是排程伺服器debian1本身的高可用性沒有考慮到,存在單點問題。

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

注:下面實現高可用都用的是雙機熱備,為了方便,把排程伺服器debian1簡稱為主機,把排程伺服器debian1的備機debian1'簡稱為備機

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

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

順帶一提,**開發我就使用我之前的專案chkv了,因為這個專案中的namenode或者datanode也可以用zookeeper實現高可用,歡迎和我一起完善這個專案,一塊進步。

排程伺服器主要向zookeeper註冊自己,並向客戶端提供服務。我們使用curator框架來和zookeeper互動,特別要注意版本問題。

主要**如下:

public static void main(string... arg) throws exception ",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)else

// 監聽

nodecache cache = new nodecache(curator, master_node_path,false);

cache.getlistenable().addlistener(()->,data:{},stat,{}",path,datastring,stat);

}else else

}});

cache.start(true);

}// 確認master

private static boolean confirm(curatorframework curator) throws exception ",masternode);

return thisnode.equals(masternode);

}// 成為master

private static boolean becomemaster(curatorframework curator) throws exception catch (exception e)

return master_node_path.equals(path);

}

完整**在github上。

客戶端主要向zookeeper監聽排程伺服器變更事件,並向其發起應用請求。實際上應用伺服器也可以使用這部分**來監聽排程伺服器的變化。

主要**如下:

public static void main(string... arg) throws exception ,data:{},stat,{}",path,datastring,stat);

masterinfo = datastring;

}else

});cache.start(true);

// 獲得主機,阻塞等待

try catch (exception e)

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 

virtual_ipaddress

}

virtual_server 10.23.8.80 80

}real_server 172.18.1.12 80

}real_server 172.18.1.13 80 }}

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

vrrp_instance vi_1 

virtual_ipaddress

}

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

檢視原文,來自mageekchiu

離散傅利葉變換的兩種實現方案

方案一 dftm sig ones 256,1 t 8 timeslice 8 timeslice f t nfft 256 sig cos 2 pi 1 t dft zeros nfft,nfft n 0 nfft 1 n的行向量,為1 n矩陣 k 0 nfft 1 k的行向量,為1 n矩陣 wn...

Redis安裝 主從配置及兩種高可用集群搭建

redis安裝 主從配置及兩種高可用集群搭建 三颱 192.168.154.129 192.168.154.130 192.168.154.131 使用者名稱 密碼 root 修改sshd config檔案,命令為 vim etc ssh sshd config 將 passwordauthenti...

PHP MySQL 無限級分類的兩種實現方案

方案一 表結構 id int primary key auto increment name varchar 40 pid int default 0 父類id,預設值為0 頂級分類的 pid 預設就是0了。當我們想取出某個分類的子分類樹的時候,基本思路就是遞迴,當然,出於效率問題不建議每次遞迴都查...