陪玩原始碼介面效能優化,需要你掌握的關於呼叫的一些事
陪玩原始碼的效能優化其實包含很多層次的內容,像資料庫效能、演算法效能、介面效能等。其中介面效能的優化可以採用的方法有很多,今天我們主要來了解一下從呼叫方面入手的優化方法。
一、遠端呼叫
很多時候,我們需要在陪玩原始碼的某個介面中,呼叫其他服務的介面。
比如有這樣的業務場景:
在使用者資訊查詢介面中需要返回:使用者名稱稱、性別、等級、頭像、積分、成長值等資訊。
而使用者名稱稱、性別、等級、頭像在使用者服務中,積分在積分服務中,成長值在成長值服務中。為了彙總陪玩原始碼中的這些資料統一返回,需要另外提供一個對外介面服務。
於是,使用者資訊查詢介面需要呼叫使用者查詢介面、積分查詢介面 和 成長值查詢介面,然後彙總資料統一返回。
呼叫過程如下圖所示:
呼叫遠端介面總耗時 530ms = 200ms + 150ms + 180ms
顯然這種序列呼叫遠端介面效能是非常不好的,呼叫遠端介面總的耗時為所有的遠端介面耗時之和。
那麼如何優化陪玩原始碼的遠端介面效能呢?
1、 並行呼叫
上面說到,既然陪玩原始碼序列呼叫多個遠端介面效能很差,為什麼不改成並行呢?
如下圖所示:
呼叫遠端介面總耗時 200ms = 200ms(即耗時最長的那次遠端介面呼叫)
在java8之前可以通過實現Callable介面,獲取執行緒返回結果。
java8以後通過CompleteFuture類實現該功能。我們這裡以CompleteFuture為例:
public UserInfo getUserInfo(Long id) throws InterruptedException, ExecutionException { final UserInfo userInfo = new UserInfo(); CompletableFuture userFuture = CompletableFuture.supplyAsync(() -> { getRemoteUserAndFill(id, userInfo); return Boolean.TRUE; }, executor); CompletableFuture bonusFuture = CompletableFuture.supplyAsync(() -> { getRemoteBonusAndFill(id, userInfo); return Boolean.TRUE; }, executor); CompletableFuture growthFuture = CompletableFuture.supplyAsync(() -> { getRemoteGrowthAndFill(id, userInfo); return Boolean.TRUE; }, executor); CompletableFuture.allOf(userFuture, bonusFuture, growthFuture).join(); userFuture.get(); bonusFuture.get(); growthFuture.get(); return userInfo; }
溫馨提醒一下,這兩種方式別忘了使用執行緒池。示例中我用到了executor,表示自定義的執行緒池,為了防止陪玩原始碼在高併發場景下,出現執行緒過多的問題。
2、資料異構
上面說到的使用者資訊查詢介面需要呼叫使用者查詢介面、積分查詢介面 和 成長值查詢介面,然後彙總資料統一返回。
那麼,陪玩原始碼能不能把資料冗餘一下,把使用者資訊、積分和成長值的資料統一儲存到一個地方,比如:redis,存的資料結構就是使用者資訊查詢介面所需要的內容。然後通過使用者id,直接從redis中查詢資料出來,不就OK了?
如果在高併發的場景下,為了提升介面效能,遠端介面呼叫大概率會被去掉,而改成儲存冗餘資料的資料異構方案。
但需要注意的是,如果陪玩原始碼使用了資料異構方案,就可能會出現資料一致性問題。
使用者資訊、積分和成長值有更新的話,大部分情況下,會先更新到資料庫,然後同步到redis。但這種跨庫的操作,可能會導致兩邊資料不一致的情況產生。
二、重複呼叫
重複呼叫在陪玩原始碼中可以說隨處可見,但如果沒有控制好,會非常影響介面的效能。
不信,我們一起看看。
1、迴圈查資料庫
有時候,我們需要從陪玩原始碼指定的使用者集合中,查詢出有哪些是在資料庫中已經存在的。
實現程式碼可以這樣寫:
public List<User> queryUser(List<User> searchList) { if (CollectionUtils.isEmpty(searchList)) { return Collections.emptyList(); } List<User> result = Lists.newArrayList(); searchList.forEach(user -> result.add(userMapper.getUserById(user.getId()))); return result; }
這裡如果有50個使用者,則需要迴圈50次,去查詢資料庫。我們都知道,每查詢一次資料庫,就是一次遠端呼叫。
如果查詢50次資料庫,就有50次遠端呼叫,這是非常耗時的操作。
那麼,我們如何優化呢?
具體程式碼如下:
public List<User> queryUser(List<User> searchList) { if (CollectionUtils.isEmpty(searchList)) { return Collections.emptyList(); } List<Long> ids = searchList.stream().map(User::getId).collect(Collectors.toList()); return userMapper.getUserByIds(ids); }
提供一個根據使用者id集合批量查詢使用者的介面,只遠端呼叫一次,就能查詢出所有的資料。
這裡有個需要注意的地方是:id集合的大小要做限制,最好一次不要請求太多的資料。要根據陪玩原始碼實際情況而定,建議控制每次請求的記錄條數在500以內。
2、死迴圈
有些小夥伴看到這個標題,可能會感到有點意外,死迴圈也算?
陪玩原始碼中不是應該避免死迴圈嗎?為啥還是會產生死迴圈?
有時候死迴圈是我們自己寫的,例如下面這段程式碼:
while(true) { if(condition) { break; } System.out.println("do samething"); }
這裡使用了while(true)的迴圈呼叫,這種寫法在CAS自旋鎖中使用比較多。
當滿足condition等於true的時候,則自動退出該迴圈。
如果condition條件非常複雜,一旦出現判斷不正確,或者少寫了一些邏輯判斷,就可能在某些場景下出現死迴圈的問題。
陪玩原始碼出現死迴圈,大概率是開發人員人為的bug導致的,不過這種情況很容易被測出來。
還有一種隱藏的比較深的死迴圈,是由於陪玩原始碼寫的不太嚴謹導致的。如果用正常資料,可能測不出問題,但一旦出現異常資料,就會立即出現死迴圈。
3、無限遞迴
如果想要列印某個分類的所有父分類,可以用類似這樣的遞迴方法實現:
public void printCategory(Category category) { if(category == null || category.getParentId() == null) { return; } System.out.println("父分類名稱:"+ category.getName()); Category parent = categoryMapper.getCategoryById(category.getParentId()); printCategory(parent); }
正常情況下,這段程式碼是沒有問題的。
但如果某次有人誤操作,把某個分類的parentId指向了它自己,這樣就會出現無限遞迴的情況。導致介面一直不能返回資料,最終陪玩原始碼會發生堆疊溢位。
建議寫遞迴方法時,設定一個遞迴的深度,比如:分類最大等級有4級,則深度可以設定為4。然後在遞迴方法中做判斷,如果深度大於4時,則自動返回,這樣就能避免陪玩原始碼出現無限迴圈的情況。
本文轉載自網路,轉載僅為分享乾貨知識,如有侵權歡迎聯絡雲豹科技進行刪除處理
原文連結:https://mp.weixin.qq.com/s/0ez_mkyr0i4MZd7DEN7M8A
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69996194/viewspace-2849100/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 做好陪玩系統原始碼的前端效能優化,提升系統效能原始碼前端優化
- 陪玩原始碼下單介面調優實戰,提高效能的好辦法原始碼
- 提升陪玩平臺原始碼的整體效能,MySQL資料庫如何優化?原始碼MySql資料庫優化
- 陪玩系統原始碼利用介面非同步呼叫,減少介面耗時原始碼非同步
- 遊戲陪玩原始碼前端效能優化,開發階段可採取的措施遊戲原始碼前端優化
- 關於遊戲陪玩系統原始碼後臺管理系統,需要思考的二三事遊戲原始碼
- 關於效能優化的一些實踐優化
- 關於遊戲陪玩系統效能優化的9大策略和6大指標遊戲優化指標
- 關於spring事務原始碼的一些小理解Spring原始碼
- 遊戲陪玩原始碼前端圖片載入優化的各種技巧遊戲原始碼前端優化
- 陪玩原始碼,與時間、日期相關的程式碼分析原始碼
- 遊戲陪玩平臺原始碼,日期格式化的程式碼分析遊戲原始碼
- 要想實現遊戲陪玩app原始碼的效能測試與調優,應該怎麼做?遊戲APP原始碼
- 陪玩系統原始碼實現音訊編碼的相關步驟原始碼音訊
- 遊戲陪玩app原始碼開發,啟動速度優化與監控遊戲APP原始碼優化
- 優化直播app原始碼介面效能,我們可以採取的手段優化APP原始碼
- 遊戲陪玩系統原始碼開發,如何實現圖片和動畫的優化?遊戲原始碼動畫優化
- 如何實現遊戲陪玩系統原始碼前端效能監控?遊戲原始碼前端
- 如何開發陪玩系統原始碼的列表頁面,相關實現程式碼原始碼
- 陪玩系統原始碼開發,H5頁面中呼叫支付功能的實現原始碼H5
- 遊戲陪玩app開發中,Mysql的sql優化方法遊戲APPMySql優化
- 婚戀app原始碼開發,如何實現介面效能優化?APP原始碼優化
- AndroidAPP效能優化的一些思考AndroidAPP優化
- 關於webpack優化,你需要知道的事(上篇)Web優化
- 實現語音社交原始碼介面效能優化,從索引入手原始碼優化索引
- 不一樣的遊戲陪玩原始碼服務端介面設計模式,值得一看遊戲原始碼服務端設計模式
- 關於介面設計的一些反思
- android 關於記憶體優化的一些總結Android記憶體優化
- 如何進行遊戲陪玩系統原始碼中音視訊的自動化測試?遊戲原始碼
- 效能優化之關於畫素管道及優化(二)優化
- 從比心APP原始碼的成功,分析陪玩系統原始碼應該如何開發APP原始碼
- 聊聊關於效能優化和其他(一)優化
- 關於mysql的優化MySql優化
- 記一次介面效能優化實踐總結:優化介面效能的八個建議優化
- 語音陪玩原始碼如何做到不卡頓?原始碼
- 有關效能優化的感悟.2021優化
- 效能優化的相關策略整理優化
- 漫談ElasticSearch關於ES效能調優幾件必須知道的事Elasticsearch