開心一刻html
醫院裏,一母親帶着小女孩打針。小女孩:「媽媽我不想打針,疼!」媽媽:「寶貝兒聽話,這裏這麼多護士阿姨,我們找個打針不疼的。」小女孩:「那哪一個阿姨打針不疼呢?」媽媽:「媽媽也不知道,我們試試看吧。」小女孩高興的點了點頭。。。linux
路漫漫其修遠兮,吾將上下而求索!git
github:https://github.com/youzhibinggithub
碼雲(gitee):https://gitee.com/youzhibing數據庫
Mycat - 實現數據庫的讀寫分離與高可用寫完以後,本覺得一兩天就能寫完Mycat - 高可用與負載均衡實現,滿滿的乾貨!,可事實是卻用了一個星期;期間雖然產生了一系列的問題,但主要仍是卡在了keeplaived實現mycat的高可用,那時候兩臺keepalived服務器的keepalived.conf內容以下centos
細心的朋友應該已經找到問題了,無論你找沒找到問題,均可以準備好花生、瓜子和啤酒,且看我是如何埋雷和掃雷的 bash
我的一直用ifconfig命令來管理linux的網絡配置,可是keepalived啓動以後經過ifconfig命令卻看不到vip。ifconfig是net-tools中已被廢棄使用的一個命令,許多年前就已經沒有維護了。iproute2套件裏提供了許多加強功能的命令,ip命令便是其中之一,大多數Linux發行版已經預裝了iproute2工具,而沒有預裝net-tools,ip命令功能更強大,旨在取代ifconfig。咱們能夠用ip命令查看vip的綁定狀況,具體以下服務器
這個問題還真卡了我一會,一直覺得vip綁定失敗,可是看/var/log/message,又沒發現有什麼問題,而且還能ping通vip。我這個無知者是有多無畏、多自信呀!網絡
更多關於ifconfig、ip的信息,你們能夠去網上查閱,這裏我就不細講了(實際上是不知道,)。負載均衡
單獨執行命令是正確的;命令放入檢測腳本中,部分是正確的;檢測腳本結合keepalived,正確的更少了,具體咱們往下看
check_pid.sh具體配置以下
#!/bin/bash count=`ps -ef|grep mycat |grep -v grep | wc -l` time=$(date "+%Y-%m-%d %H:%M:%S") if [ $count = 0 ]; then echo "$time : count=$count, mycat is not running..." >> /var/log/keepalived_check.log exit 1 # 返回1說明腳本非正常執行,mycat不在運行中 else echo "$time : count=$count, mycat is running..." >> /var/log/keepalived_check.log exit 0 # 返回0說明腳本正常執行,mycat正在運行中 fi
ps -ef與ps aux效果同樣,我就只演示一個了,結果以下
ps命令單獨執行,當mycat沒啓動時,查詢到的mycat進程數是0,當mycat在運行中,查詢到的是2(大於0表示mycat在運行中),很正確,沒毛病;可當ps命令放到check_pid.sh中,執行的結果卻有點不同,當mycat沒啓動時,查到的進程數居然是2,而當mycat在運行中,查到的進程數是4,爲何是這種結果,至今我還沒搞明白,表面上看着像是單獨執行ps命令的翻倍,爲何翻倍,不得而知 。很顯然,check_pid.sh這麼寫不行。
既然ps命令查mycat進程數行不通,咱們就用mycat命令(將MyCat配置到環境變量中在Mycat - 實現數據庫的讀寫分離與高可用已講過),check_pid.sh具體配置以下
#!/bin/bash count=`mycat status|grep "Mycat-server is running" | wc -l` time=$(date "+%Y-%m-%d %H:%M:%S") if [ $count = 0 ]; then echo "$time : count=$count, mycat is not running..." >> /var/log/keepalived_check.log exit 1 # 返回1說明腳本非正常執行,mycat不在運行中 else echo "$time : count=$count, mycat is running..." >> /var/log/keepalived_check.log exit 0 # 返回0說明腳本正常執行,mycat正在運行中 fi
測試結果以下
單獨執行命令,結果是正確的,單獨執行check_pid.sh,結果也是正確的,可恰恰check_pid.sh結合keepalived卻出錯了,這就難受了 。
雖然上述兩個問題的緣由未知,但咱們最終的目的:keepalived結合check_pid.sh正確執行,仍是要實現的,咱們再換個方式試下,用mycat命令的絕對路勁行不行呢? 具體配置以下
#!/bin/bash count=`/usr/local/mycat/bin/mycat status |grep 'Mycat-server is running' | wc -l` time=$(date "+%Y-%m-%d %H:%M:%S") if [ $count = 0 ]; then echo "$time : count=$count, mycat is not running..." >> /var/log/keepalived_check.log exit 1 # 返回1說明腳本非正常執行,mycat不在運行中 else echo "$time : count=$count, mycat is running..." >> /var/log/keepalived_check.log exit 0 # 返回0說明腳本正常執行,mycat正在運行中 fi
單獨執行命令與單獨執行check_pid.sh我就不演示了,與上述:環境變量中mycat命令 無差,keepalived結合check_pid.sh測試結果以下
終於搞對了,就是你了:用絕對路徑的mycat命令!此刻心情真的是。
在check_pid.sh中有兩種作法能夠知足keepalived進行vip轉移的條件
一、推薦作法,返回mycat檢測結果給keepalived
若是mycat不在運行中,則返回1,若mycat正在運行中則返回0,注意是使用exit 0或exit 1來返回檢測結果,與咱們平時理解的有些不同。keepalived會根據這個返回結果相應的增減優先級,keepalived集羣會根據各個節點的優先級從新選舉master
keepalived優先級 = priority + weight * script的結果,腳本執行返回0,script則爲true,不然script爲false,權重大的搶佔到vip,成爲master
二、野蠻作法,直接殺掉keepalived進程
這是比較野蠻的作法,一旦檢測到mycat進程不存在,則直接killall keepalived,這時候就不須要關注返回值了,至關於將當前keepalived踢出了keepalived集羣。這麼作有點不太好,就是當咱們把mycat修復後,不但要重啓mycat,也須要重啓keepalived。
具體日誌輸出
Jan 17 09:53:44 localhost Keepalived_vrrp[1655]: ip address associated with VRID not present in received packet : 192.168.1.200 Jan 17 09:53:44 localhost Keepalived_vrrp[1655]: one or more VIP associated with VRID mismatch actual MASTER advert Jan 17 09:53:44 localhost Keepalived_vrrp[1655]: bogus VRRP packet received on eth0 !!! Jan 17 09:53:44 localhost Keepalived_vrrp[1655]: VRRP_Instance(VI_1) Dropping received VRRP packet...
意思是說virtual_router_id重複了,當時還愣了一下:virtual_router_id不是應該一致嗎? 主從熱備+負載均衡(LVS + keepalived)中配置的就是一致,當時沒去細想,既然日誌提示重複了,那就改一個讓其不重複唄,一個virtual_router_id值設置成66,一個virtual_router_id值設置成65,此提示消除,vip可以正常綁定上,但此時就出現了keepalived「腦裂」問題,兩臺keepalived服務器上都出現了vip,以下圖
何謂腦裂,指在一個高可用(HA)系統中,當聯繫着的兩個節點斷開聯繫時,原本爲一個總體的系統,分裂爲兩個獨立節點,這時兩個節點開始爭搶共享資源,結果會致使系統混亂,數據損壞。
vip出現了多個,我就主觀的認爲是keepalived出現了腦裂,上網查資料、提問求助、問好友、換centos系統版本、換keepalived版本、查閱keepalive的官網、等等,嘗試各類方法(就是沒有對比keepalived.conf,一直在copy錯的keepalived.conf,),都沒有找到答案,期間一度想放棄,可我一根筋的性格不容許我這麼作;終於皇天不負有心人,無心之中我找到了問題所在,具體排查過程且聽我慢慢道來。
因爲是本地測試,我通常都是關了防火牆的,生產環境不能直接關閉防火牆,而是設置防火牆來放行vrrp包;查看vrrp包狀況:tcpdump -i eth0|grep VRRP
tcpdump命令若不存在,則能夠執行命令:yum install -y tcpdump進行安裝。如上圖所示,兩臺keepalived服務器都是能正常收到彼此的vrrp包
/usr/sbin/sestatus -v 查看selinux狀態;/etc/selinux/config文件能夠配置selinux開始與關閉,修改以後重啓系統生效。
兩臺keepalived服務的selinux也是關閉的
無奈之下我想到了官網,想看看官網中有沒有提到腦裂問題,或者說是哪一個版本修復了腦裂問題,changelog中查詢split關鍵字,結果以下
貌似1.2.9版本有修復腦裂問題,而個人keepalived版本分別是:keepalived-1.2.13-5.el6_6.i686和keepalived-1.3.5-8.el7_6.x86_64,應該不是低版本的問題
感受形式愈來愈不利了,我想到了園子的博問,因而我在博問欄進行了提問:keepalived腦裂,有人瀏覽了,但沒人回答,多是問的姿式不對,亦或是未遇見有緣人
各方面都顯示正確,可結果卻不正確,真的讓人很絕望!!!,此刻個人心情...... 大家懂的
山重水複疑無路,柳暗花明又一村。衆裏尋她千百度,驀然回首,那人卻在燈火闌珊處。撥開雲霧見天日,守得雲開見月明。......實在是裝不下了......
不知道是上天眷顧,仍是本身抽瘋,居然鬼使神差的去比較keepalived.conf文件,結果發現了驚天大冪冪,不對,是驚天大祕密:
此刻心情五味雜陳,怎麼VIP一開始就配置的不同,是否是室友趁我外出動了我代碼?嗯,應該是的。看到vip的不一樣,讓我看到了一絲曙光,更猶如看到剛出浴的美人通常,我緊緊抓住最後這根救命的稻草,從新展開部署與測試,終於出現了意料中的結果,此時我如釋重負,癱倒在牀上思考了一會人生(,你爲什麼如此美?)。keepalived.conf的正確配置,請查看Mycat - 高可用與負載均衡實現,滿滿的乾貨!。
這特麼簡直就是一個天大的烏龍! 個人這波操做真的是、、,太特麼刺激了......,差點把本身玩死......
一、mycat存活檢測腳本中,用絕對路徑的mycat命令,不要用ps查詢mycat進程,也不要用配置好的縮寫mycat命令;固然了,若是咱們用lvs實現了mycat的負載均衡,那麼mycat檢測腳本就能夠省略了;
二、keepalived.conf寫完以後用比較工具進行代碼比較,能夠防止少改、多改以及手抖的狀況,避免出現本文的狀況(mmp的);
三、在MASTER節點的 vrrp_instance中配置nopreempt,當它異常恢復後,即便它的priority更高也不會搶佔,這樣能夠避免正常狀況下作無謂的切換;
一、環境搭建過程當中必定要仔細當心,分步驟、環節,保證各個步驟、環節都正確,即便出現了問題,咱們也能很快定位到是哪一個步驟、環節出了問題,不至於出現相似本文的狀況:明明不是腦裂問題,卻死盯着腦裂不放,背道而馳,怎麼解決的了?
二、若是確實是腦裂問題,咱們能夠從以下幾個方面進行排查
防火牆是否放行vrrp包,推薦放行vrrp包,而不是野蠻式的關閉防火牆;keepalived配置問題,用文件比較工具比較keepalived.conf,不一樣之處很是少,很容易比較;selinux設置,這個我沒研究過,也可做爲一個排查點。通常而言從這三方面入手,基本能解決腦裂問題,實在是不行,則咱們能夠自寫腳本,進行第三方仲裁。
三、虛擬路由編號(virtual_router_id),同集羣,主備必須一致,不一樣集羣不能相同;通常而言,咱們只會有一個keepalived集羣,因此配置成同樣就沒錯,即便報了相關的錯,也應該從其餘方面找問題,而不是改動virtual_router_id。