最近一直在搞每個月一次的抽獎活動,併發量也比平時多了很多,隨之而來的,就是平時遇不到的一些問題。這也是可喜可賀的啊,有問題才能成長,沒有問題就是在浪費生命。前端
其中一個感受比較奇葩的問題,就是:Tomcat在接收POST請求時,偶發性的POST參數接收不全,這個比例還很高。以下所示:java
45應用服務器正常POST參數獲取:nginx
2016-05-19 15:45:15 INFO :request param : body=[{"appDevice":{"qdPlatform":"weixin","qdVersion":"1.4.1"},"activityId":80,"curPlanId":381,"memberId":"ff808081547ef0b401549f64e6cb2ecb","projectId":"31605061701144","prizeIds":[437,436,435,440,439,438],"planIds":[370,371,372,373,374,375,376,377,378,379,380,381,382]}]
複製代碼
45應用服務器不正常POST參數獲取:後端
2016-05-19 16:03:16 INFO :request param : 7D,"activityId":80,"curPlanId":381,"memberId":"ff80808150f0fdd401510f83cae413a9","projectId":"708","prizeIds":[437,436,435,440,439,438][370,371,372,373,374,375,376,377,378,379,380,381,382][370,371,372,373,374,375,376,377,378,379,380,381,382]=[]
複製代碼
排查問題以前,先理清服務架構,如圖:瀏覽器
排查問題開始以前,簡單說下本身排查問題的幾個原則(僅供參考):tomcat
問題重現:必定要先重現問題,任何重現不了的問題,都不是問題。同理,任何存在的問題,都必然能再次重現。bash
由近及遠:先確認本身的代碼無問題,而後再去確認外部代碼無問題(如:框架代碼,第三方代碼等)。服務器
由外到內:程序就是一個IPO,有輸入Input(如:參數、環境等)也有輸出Out(如:結果、異常等),輸出Out是問題的表象,先肯定外部因素Input無問題,再確認程序代碼邏輯無問題。網絡
由淺入深:其實就是由易到難、自上向下,先從上層應用排查問題,如:上層API、應用層、HTTP傳輸等,而後再確認底層應用排查問題,如:底層API、網絡層、系統層、字節碼、JVM等;架構
Map<String, String[]> parameterMap = request.getParameterMap();
Set<String> keySet = parameterMap.keySet();
StringBuilder sb = new StringBuilder();
for(String key : keySet) {
sb.append(key).append("=").append(Arrays.toString(parameterMap.get(key))).append(",");
}
log.info("request param : " + sb.toString()) ;
複製代碼
經過上面的兩條日誌輸出,和以上代碼的分析,能夠得出如下結論:
以上代碼不存在併發問題及邏輯Bug,POST參數是從原始request.getParameterMap()中獲取,獲取先後未作任何寫入、轉換處理;
經過不正常日誌輸出和以上代碼邏輯來看,從request.getParameterMap()中獲取的參數,"body"這個Key已經丟失,且對於的Value也存在部分丟失,ParameterMap中的Key-Val混亂;
很快就排除了這種可能,由於參數不全是偶發性產生的,若是是因爲參數長度限制致使請求參數截斷,而應該是100%產生參數不全的問題。
能夠確認,用戶的請求從瀏覽器發出在到達Nginx以前,POST請求參數就已經丟失;
注意:想要了解更多tcpdump和Wireshark分析使用,請參考聊聊tcpdump與Wireshark抓包分析。
在上面排查問題的過程當中,就已經肯定了是用戶前端傳過來的參數問題,但從前端代碼排查來看,其實也沒有發現問題,只是在前端作了個JSON序列化。因此爲了不問題再次發生,將前端序列化去掉,保持HTTP請求參數原始傳輸,由前端的代理服務再進行序列化後,提交給後端應用。
其實對於問題的解決並不重要,有時或許只是一個空格、一個微小的配置等,重要的是在於問題的分析過程、分析思路,怎麼樣有個清晰的思路,快速的定位問題,纔是解決問題的關鍵。