almost 2 years ago

前陣子在最佳化公司的 WebAPI 效能,學習到不少寶貴的經驗。

還沒進公司的時候,寫 WebAPI 主要使用 php,接過的案子也都不大,不太需要做太徹底的最佳化,頂多自己玩玩技術。
以下為之前嘗試過的效能最佳化:

  • 前端:靜態元素使用 CDN、lazy load javascript、預先快取圖片、minimize resource、cookie-free domain for static files、yslow 分析
  • CDN:採用 cloudflare,進行過細部的效能調整
  • Reverse proxy:使用 varnish,並和 application custom header 搭配調整快取效能
  • Web Server:apache + php-cgi -> apache-worker / event + php-fpm -> nginx + php-fpm
  • PHP:調整 fpm 設定、加入 php opcode cache,關閉動態更新功能、session改存在redis中、HHVM / PHP7
  • Application:整頁快取 + 部份快取機制(php-apc)

這些是我架設網站會使用的效能最佳化技巧,但是進公司就要面對公司的複雜的噁心的架構,往往和自己做會有不少差異。敝公司的 WebAPI 全都是使用 C++ 寫成(什麼?PHP HipHop?我們不需要XD),但就算是 C++,在架構日益龐大的情況下還是可能發生效能問題。

我們是一間很重視效能的公司,但就跟其他公司一樣,feature都做不完了還管效能,當然是先上再說,就像 IOS7 剛出的時候舊ipad升級之後解鎖要等30秒我現在都還餘悸猶存。但成山的feature做完之後,該面對的還是要面對。

最近公司的 API 比上一個大版本來的緩慢,找了很久發現速度的瓶頸其實是在 dlopen 時載入的 so 太多,導致一隻 API 所用到,全部 so 載入進來至少需要 80ms 以上的時間,對比上一個大版本大概只要 3x ms,足足落後了一倍以上。進行夾板測試之後,我們發現是 library 拆小的策略所導致,在這一季我們將大的 library 拆成很多個小 library,導致 so 數量是以往的兩倍以上。

知道原因之後,接下來我們就開始進行兩個方針,其一為所有 project link 的時候都加上 -Wl,--as-needed,避免連結到不必要的 so;其二為將 webapi 基本使用到的 library 再拆小,用不到的就不要 link,這兩個方針下下去之後,我們成功的將延遲時間提升到 30 ms 左右。

 
comments powered by Disqus