Memcache在微信中的應用
一、微信應用開發特點和memcache的特點
近些年來微信的風靡讓使用微信API接口開發的微應用的需求大幅增長。在這些應用的開發過程中往往發現,因微信特殊交互方式導致和傳統的WEB應用開發有所不同。微信公眾平臺官網的解釋是:公眾平臺開發接口提供與用戶進行消息交互、自定義菜單交互的能力。對于已接入的第三方接口,當用戶發送消息時,微信會推送至第三方服務器。以上就是微信公眾平臺的開發流程,很多人因不明白而使開發受阻,如圖所示。

用戶主動發送的消息分成普通消息、事件消息、語音識別結果。普通消息包含文本、圖片、語音、視頻、位置、鏈接等多維度消息,也是開發者們最常用的。事件消息包含關注、取消關注、掃描二維碼參數、上報地理位置、自定義菜單(點擊、跳轉)監控等。整個消息按標準XML格式進行傳遞,所以開發人員可以用任何語言進行代碼開發。
在微信應用中遇到的問題
1、響應速度
微信服務器在于第三方開發的應用交互工程中在微信服務器發出消息后五秒內收不到響應會斷掉連接,否則微信都會在公眾號會話中向用戶下發系統提示“該公眾號暫時無法提供服務,請稍后再試”的交互失敗信號。在一些大用戶量的微信應用中對響應速度的要求比普通的WEB應用要高的多。所以如何在開發微信應用中提高其響應速度就成了我們應該關注的問題。為了得到應用的高響應性能,如何減少應用運行中命中數據庫的次數成為了關鍵。
2、用戶會話狀態
在開發微信的應用的時候我們經常會遇到需要保持或處理用戶會話狀態的需求(比如:用戶登錄狀態、用戶信息的共享等),因為微信應用的HTTP交互和傳統的BS結構不同,它不是用戶的瀏覽器與服務器的直接連接,而交互的雙方是微信服務器和第三方服務器,所以不存在不同用戶會話狀態,這就是傳統的WEB應用中用過Session和Cookies處理的用戶會話狀態的方法統統失效了,我們就需要尋找其他的方法來解決這個問題。
3、臨時性數據的存儲
在微信應用開發過程中我們經常需要存取一些訪問頻繁的臨時數據(如:access_token),為了保證應用的響應速度需要尋找一種高效存取方式。
Memcache在微信應用中的問題解決的方法
1、Memcache特性就是決定了它是降低應用的數據庫命中次數,提高HTTP應用響應效率的好方法。
按應用場景的不同一般有以下兩種設計方案:
方案一:把數據庫的SQL查詢結果緩存到memcache,讀取數據的時候優先從memcached讀取,擋住數據庫查詢請求。方案二:把業務處理的最終結果進行緩存,客戶端來請求時可以直接返回這個緩存的結果。
2、在解決微信用戶會會話狀態的時,可以把用戶會話信息(如:用戶ID,登錄狀態等數據)以OPENID為唯一鍵值以key->value的形式存儲在memcache服務器中,需要時以OPENID為標記取出存儲值。代碼樣例如下:

應當注意的是雖然在單一的微信公共號中openid是與用戶賬號一一對應的,但如果是開發跨不同的微信公共號的應用中用戶的openid就會發生變化,不能做到一一對應了。
3、對于存取訪問頻繁的臨時性數據使用memcache應該是非常合適的方法了。我們以存取access_token為例。access_token是公眾號的全局唯一票據,公眾號調用各接口時都需使用access_token。正常情況下access_token有效期為7200秒,重復獲取將導致上次獲取的access_token失效。一般的公共號每天獲取access_token的次數是有限的,過度頻繁的調用獲取接口可能會因達到每天接口調用次數的上限而導致應用無法正常運行,所以我們盡可能的每次獲取access_token后使用到過期再去接口申請新的access_token。代碼樣如下:

為了達到最佳的緩存效果,我們在設計Memcache的緩存更新策略時候要考慮應用場景的特點設計緩存更新策略。兩種常見的方案:
方案一:懶惰式加載,客戶端先查詢memcached,如果命中,返回結果,如果沒命中(沒有數據或已經過期),則從數據庫中加載最新數據,并寫回到memcached中,最后返回結果。方案二:主動更新策略,緩存里的數據永不失效,當有數據更新的時候,由單獨程序來更新這個緩存。
Memcache開發中應注意的幾個問題
批量讀取(multiget):有些較復雜的業務請求可能一次請求要進行多次memcached操作,其中的網絡往返的消耗以及對memcached節點施加的并發壓力還是比較可觀的,這種情況下我們可以考慮進行批量讀取來減少網絡io往返的次數,一次把數據返回,同時還能減輕客戶端的業務處理邏輯。
改變系列化方式:不用編程語言自帶的對象序列化方式,自己序列化,把要緩存的對象序列化成字節數組或者string進行保存。這樣在內存節省和網絡傳輸上都有不錯的效果。
增長因子:合理調整memcached的增長因子,可以有效控制內存的浪費。
空結果的處理:有些場景下我們數據庫里沒有查到數據,緩存里也是空的,這時候需要在緩存里存放一個短時效的空結果來擋住前端的頻繁請求,以免對數據庫造成壓力。
memcache的使用其實非常簡單,性能也很出色,上面這些就是我們在微信應用開發中會碰到的一些場景和問題,使用memcache解決這些問題可以給以后的開發維護帶來不少便利。
(中國江蘇網胡毅蔣志初)