Memcache在微信中的應(yīng)用
一、微信應(yīng)用開發(fā)特點(diǎn)和memcache的特點(diǎn)
近些年來微信的風(fēng)靡讓使用微信API接口開發(fā)的微應(yīng)用的需求大幅增長。在這些應(yīng)用的開發(fā)過程中往往發(fā)現(xiàn),因微信特殊交互方式導(dǎo)致和傳統(tǒng)的WEB應(yīng)用開發(fā)有所不同。微信公眾平臺官網(wǎng)的解釋是:公眾平臺開發(fā)接口提供與用戶進(jìn)行消息交互、自定義菜單交互的能力。對于已接入的第三方接口,當(dāng)用戶發(fā)送消息時,微信會推送至第三方服務(wù)器。以上就是微信公眾平臺的開發(fā)流程,很多人因不明白而使開發(fā)受阻,如圖所示。
用戶主動發(fā)送的消息分成普通消息、事件消息、語音識別結(jié)果。普通消息包含文本、圖片、語音、視頻、位置、鏈接等多維度消息,也是開發(fā)者們最常用的。事件消息包含關(guān)注、取消關(guān)注、掃描二維碼參數(shù)、上報地理位置、自定義菜單(點(diǎn)擊、跳轉(zhuǎn))監(jiān)控等。整個消息按標(biāo)準(zhǔn)XML格式進(jìn)行傳遞,所以開發(fā)人員可以用任何語言進(jìn)行代碼開發(fā)。
在微信應(yīng)用中遇到的問題
1、響應(yīng)速度
微信服務(wù)器在于第三方開發(fā)的應(yīng)用交互工程中在微信服務(wù)器發(fā)出消息后五秒內(nèi)收不到響應(yīng)會斷掉連接,否則微信都會在公眾號會話中向用戶下發(fā)系統(tǒng)提示“該公眾號暫時無法提供服務(wù),請稍后再試”的交互失敗信號。在一些大用戶量的微信應(yīng)用中對響應(yīng)速度的要求比普通的WEB應(yīng)用要高的多。所以如何在開發(fā)微信應(yīng)用中提高其響應(yīng)速度就成了我們應(yīng)該關(guān)注的問題。為了得到應(yīng)用的高響應(yīng)性能,如何減少應(yīng)用運(yùn)行中命中數(shù)據(jù)庫的次數(shù)成為了關(guān)鍵。
2、用戶會話狀態(tài)
在開發(fā)微信的應(yīng)用的時候我們經(jīng)常會遇到需要保持或處理用戶會話狀態(tài)的需求(比如:用戶登錄狀態(tài)、用戶信息的共享等),因?yàn)槲⑿艖?yīng)用的HTTP交互和傳統(tǒng)的BS結(jié)構(gòu)不同,它不是用戶的瀏覽器與服務(wù)器的直接連接,而交互的雙方是微信服務(wù)器和第三方服務(wù)器,所以不存在不同用戶會話狀態(tài),這就是傳統(tǒng)的WEB應(yīng)用中用過Session和Cookies處理的用戶會話狀態(tài)的方法統(tǒng)統(tǒng)失效了,我們就需要尋找其他的方法來解決這個問題。
3、臨時性數(shù)據(jù)的存儲
在微信應(yīng)用開發(fā)過程中我們經(jīng)常需要存取一些訪問頻繁的臨時數(shù)據(jù)(如:access_token),為了保證應(yīng)用的響應(yīng)速度需要尋找一種高效存取方式。
Memcache在微信應(yīng)用中的問題解決的方法
1、Memcache特性就是決定了它是降低應(yīng)用的數(shù)據(jù)庫命中次數(shù),提高HTTP應(yīng)用響應(yīng)效率的好方法。
按應(yīng)用場景的不同一般有以下兩種設(shè)計方案:
方案一:把數(shù)據(jù)庫的SQL查詢結(jié)果緩存到memcache,讀取數(shù)據(jù)的時候優(yōu)先從memcached讀取,擋住數(shù)據(jù)庫查詢請求。方案二:把業(yè)務(wù)處理的最終結(jié)果進(jìn)行緩存,客戶端來請求時可以直接返回這個緩存的結(jié)果。
2、在解決微信用戶會會話狀態(tài)的時,可以把用戶會話信息(如:用戶ID,登錄狀態(tài)等數(shù)據(jù))以O(shè)PENID為唯一鍵值以key->value的形式存儲在memcache服務(wù)器中,需要時以O(shè)PENID為標(biāo)記取出存儲值。代碼樣例如下:
應(yīng)當(dāng)注意的是雖然在單一的微信公共號中openid是與用戶賬號一一對應(yīng)的,但如果是開發(fā)跨不同的微信公共號的應(yīng)用中用戶的openid就會發(fā)生變化,不能做到一一對應(yīng)了。
3、對于存取訪問頻繁的臨時性數(shù)據(jù)使用memcache應(yīng)該是非常合適的方法了。我們以存取access_token為例。access_token是公眾號的全局唯一票據(jù),公眾號調(diào)用各接口時都需使用access_token。正常情況下access_token有效期為7200秒,重復(fù)獲取將導(dǎo)致上次獲取的access_token失效。一般的公共號每天獲取access_token的次數(shù)是有限的,過度頻繁的調(diào)用獲取接口可能會因達(dá)到每天接口調(diào)用次數(shù)的上限而導(dǎo)致應(yīng)用無法正常運(yùn)行,所以我們盡可能的每次獲取access_token后使用到過期再去接口申請新的access_token。代碼樣如下:
為了達(dá)到最佳的緩存效果,我們在設(shè)計Memcache的緩存更新策略時候要考慮應(yīng)用場景的特點(diǎn)設(shè)計緩存更新策略。兩種常見的方案:
方案一:懶惰式加載,客戶端先查詢memcached,如果命中,返回結(jié)果,如果沒命中(沒有數(shù)據(jù)或已經(jīng)過期),則從數(shù)據(jù)庫中加載最新數(shù)據(jù),并寫回到memcached中,最后返回結(jié)果。方案二:主動更新策略,緩存里的數(shù)據(jù)永不失效,當(dāng)有數(shù)據(jù)更新的時候,由單獨(dú)程序來更新這個緩存。
Memcache開發(fā)中應(yīng)注意的幾個問題
批量讀?。╩ultiget):有些較復(fù)雜的業(yè)務(wù)請求可能一次請求要進(jìn)行多次memcached操作,其中的網(wǎng)絡(luò)往返的消耗以及對memcached節(jié)點(diǎn)施加的并發(fā)壓力還是比較可觀的,這種情況下我們可以考慮進(jìn)行批量讀取來減少網(wǎng)絡(luò)io往返的次數(shù),一次把數(shù)據(jù)返回,同時還能減輕客戶端的業(yè)務(wù)處理邏輯。
改變系列化方式:不用編程語言自帶的對象序列化方式,自己序列化,把要緩存的對象序列化成字節(jié)數(shù)組或者string進(jìn)行保存。這樣在內(nèi)存節(jié)省和網(wǎng)絡(luò)傳輸上都有不錯的效果。
增長因子:合理調(diào)整memcached的增長因子,可以有效控制內(nèi)存的浪費(fèi)。
空結(jié)果的處理:有些場景下我們數(shù)據(jù)庫里沒有查到數(shù)據(jù),緩存里也是空的,這時候需要在緩存里存放一個短時效的空結(jié)果來擋住前端的頻繁請求,以免對數(shù)據(jù)庫造成壓力。
memcache的使用其實(shí)非常簡單,性能也很出色,上面這些就是我們在微信應(yīng)用開發(fā)中會碰到的一些場景和問題,使用memcache解決這些問題可以給以后的開發(fā)維護(hù)帶來不少便利。
(中國江蘇網(wǎng)胡毅蔣志初)