counter服務介紹:
我們sae這邊counter服務給使用者提供的功能為計數器服務,使用的軟體為redis。而我們對counter服務的監控,是通過monitor來做的,主要操作就是set,get,delete,increase,create,remove等操作。而counter報警問題,之前也存在,大概兩三天會有一次報警。
報警問題主要分為如下兩個階段:
一,某天counter服務頻繁報警:
是因為之前monitor的counter監控隻監控了com組webruntime, 把ent,bigapp加進去之後,頻繁報警。這是因為ent,bigapp組sae-php-saecounter軟體包版本比較低, 而低版本的包代碼中沒有添加執行redis操作失敗的重試機制。軟體版本統一之後,每天counter的報警大概在十幾條左右。
注:ent,bigapp組counter沒更新的原因為新counter的軟體包一直在com組做灰階
二,counter服務每天十幾條的報警:
通過分析報警内容,redis的 aof檔案,monitor報警邏輯及分析tcpdump抓的資料包發現一些問題,具體如下:
1,報警内容都是create和remove的時候沒有成功,其它的set,get,increase操作沒問題。
2,create和remove一個key的時候,是一個事物操作。但是,在aof檔案中看涉及對兩個key的操作。和服務負責人确認,是代碼邏輯添加的。涉及到的一個key是hash表中用戶端要操作的key本身,資料結構:appname -> {"count_1":num,"count_2":num},即keyname為這個應用的appname,hash表中的value為這個應用建立的所有計數器,限制為每個應用最多100個計數器;另一個key是記錄此hash表的key數量,資料結構:appname_len -> num,即keyname為這個應用appname加字元串"_len",value為hash表的長度,由于com組monitor是com組的一個應用,ent和bigapp組的monitor同理也是一個應用,是以,ent或com或 bigapp組每組的counter的monitor會共用一個key;
3,在抓包中看到,報警的ent webruntime機器在執行一個remove key事物操作前,已經被redis watch的key(這個key為此hash表的key數量,watch操作也是在代碼中的)被另一台ent webruntime給修改了(因為monitor報警是并發的,故對redis的操作在一段時間内,不一定隻有一台機器執行),導緻remove或者 create的時候,redis發現被watch的key修改了,故停止執行此事物操作,重試5次沒有成功,故導緻monitor報警
解決辦法:
1,适當增大redis指令執行失敗後的delay時間和重試次數,這樣當事務執行失敗後,會在延遲後繼續重試執行,一定程度降低失敗率
2,修改counter代碼邏輯,可以通過hlen指令獲得hash表的長度。可以解決這個問題
最終我們才用第二種方法解決了這個問題。
本文轉自 leejia1989 51CTO部落格,原文連結:http://blog.51cto.com/leejia/1758172,如需轉載請自行聯系原作者