分佈式項目中遇到的一些問題:記錄

接口冪等性>>>>


1.當前端沒有限制用戶點擊間隔時,後端接口也沒有做同時點擊多次的攔截,導致同一時間用戶由於網卡,或者手快,各種原因而多次點擊按鈕請求多次接口時,特別是非查詢的接口時,後端執行了N次。比如創建,由於點擊多次,創建了N個,而用戶期望是創建一個。

    解決:將用戶的此次操作標識緩存進redis,如果第一次接口沒處理完該用戶的請求,則攔截第二次請求,並告知正在處理中。


數據一致性>>>>

2.module1 開始①—處理業務邏輯②—調用module2③—處理業務邏輯④—結束⑤,這是一整個事務,如果④出現異常導致整個事務回滾,但是③已經調用了module2,是無法回滾的,會造成數據的最終不一致。


  解決:A:③和④互換,這樣調用module2是最後一步,不會出現以上情況    

             B:如果遇到④一定要在③後面執行的情況,可以使用消息,回滾時再發送一次通知給module2請求module2操作回滾。


3.以上場景module1成功完成事務後需要一個module2的回執,參考場景支付完成後等待module2提示是否支付成功,由於整個支付過程較長所以無法在業務邏輯中直接獲取支付的結果。module2通過發送消息給module1,這其中可能發生超時未送達,或者多發送幾次的情況,以及多次發送每次結果不一致。


    解決:A:超時未送達的需要module1主動調用module2查詢是否成功  。

               A2:接收到時如果是成功,module1執行後續操作,如果後續操作執行失敗,則再次接收時繼續執行。如果接收時提示支付失敗,處理後續操作成功,則再次接收不再執行後續操作。即,記錄後續操作的變更狀態,只變更一次。

              A3:如果第一次接收成功,後續操作失敗,則最好記錄失敗到消息隊列異步執行,第二次接收module2提示失敗時,則應該忽略此次消息,以第一次爲準。若反過來則以第二次爲準。遵循成功後不可能失敗,失敗後可能成功。


循環調用>>>>


4.由於業務場景複雜,可能存在多個模塊之間有依賴關係,module1需要module2的某部分來配合展示。碼代碼時需儘量抽取公共方法避免代碼繁雜。


    解決:A:由於代碼太亂,導致其中有循環調用部分,一調用該接口就內存溢出,這時候應該仔細查看該接口的代碼找出循環調用部分,這是編寫代碼的錯誤。


內存溢出>>>>

5.業務繁雜的情況一個列表的展示可能需要查詢多個模塊的信息並組合起來,這種場景多的話項目運行一天左右就開始報持久代溢出OutOfMemory:permgen space


    解決:A:修改jvm默認參數配置,如:/usr/bin/java -server -Xms1024m -Xmx1024m -Xmn512m -XX:PermSize=128m -XX:MaxPermSize=512m -XX:+UseConcMarkSweepGC -XX:+UseCMSCompactAtFullCollection -XX:CMSInitiatingOccupancyFraction=70 -XX:+CMSParallelRemarkEnabled -XX:SoftRefLRUPolicyMSPerMB=0 -XX:+CMSClassUnloadingEnabled -XX:SurvivorRatio=8 -XX:+DisableExplicitGC -Djava.rmi.server.hostname=192.168.30.100 -Dcom.sun.management.jmxremote.port=9999 -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -jar {jar package}

             A1:其次,儘量優化代碼,並對常用接口做壓力測試。



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章