標籤:
近來公司redmine伺服器表現很糟糕,在16核,64GRAM的機器上,壓測結果竟然只有每秒5~7個請求,部分頁面一個都出不來。
以下是我對Redmine效能最佳化方案:
redmine伺服器效能問題排查與最佳化建議:
以下建議的方案是基於redmine運行期的log檔案中的render耗時、activerecord耗時,linux系統效能指標採樣與 mysql 效能指標採樣分析,以及redmine在不同web server下的benchmark而得:
一. 問題排查與定量分析通過分析redmine運行期的log,對比mysql高峰時段的請求量與此時系統cpu、mem、disk、iowait等指標,以及我在本地的相同環境下的偽造並發量的效能測試結果,可以看出伺服器中高峰時段並未有效利用cpu與記憶體. 最主要的4個原因是:1. rails架構過於笨重,運行效率低,2. 一個ruby進程只能利用單核cpu,其多線程受GIL所控,多線程效率較低,無法有效利用多核cpu,因此在高峰時段只有passenger進程佔用的幾個cpu滿載,其餘利用率基本為0。3. 目前redmine的發布方式是apache+passenger, passenger沒有進過最佳化,只開啟了6個worker,而且只是進程級支援,這導致了iredmine伺服器的輸送量非常低。4. mysql的運行模式沒有進過最佳化配置,基本裸跑。
1.1 效能指標說明:效能指標資料已經儲存,如需分析可以參考如下: 1. linux系統採樣指令碼:在~/performanceLog/collectLog.sh中; 採樣結果在~/performanceLog下,以日期命名的檔案中。 註: 如果以後想使用此指令碼採集資料,如果mysql的地址或者目錄有更換,此指令碼中dstat 的mysql相關資料的採集需要重寫其mysql串連部分的代碼。 2. mysql的指標資料可以通過運行如下命令: mycheckpoint --user=root --password=xxxx --socket=/redmine/mysql/tmp/mysql.sock --database=mycheckpoint http 然後瀏覽器開啟: http://172.26.1xx.xx:8080/mycheckpoint/ 可以查看mysql的各項指標。
1.2 benchmark定量分析方法說明:偽造並發http請求,查看每秒並發10個請求時,不同web server的效能表現。針對不同web server的負載測試方法如下:在量化效能時,本方案帶來的的效能提升時,為了方便ab測試,建議關閉redmine代碼中csrf保護,並利用session,自動登陸,以保證測試的地址有sql操作,確保測試過程包含sql請求,方法如下:
取消csrf保護方法:找到redmine發布的代碼中controller目錄下的ApplicationController.rb檔案,將其中的csrf保護函數protect_from_forgery中cookie.delete(auto_cookie_name)行注釋掉。 (production模式記得調回來)
ab類比並發測試步驟:0. ./ctlscript.sh stop apache1. 使用puma -w 16 -t 16 -p 8080 /redmine/apps/redmine/htdocs/config.ru啟動 redmine2. chrome瀏覽器,開啟url, 查看inspect tools, 複製cookies3. 使用ab工具: ab -n 800 -c 16 -H “Cookie: Key1=Value1; Key2=Value2” http://localhost:8080/issues/48575
二:最佳化方案說明:
1. 並發量過大時反應慢的問題 #ok,使用multi-process * multi-thread的 web server2. 資料庫讀寫效能過低 #ok,開啟mysql查詢快取等。3. 使用非同步io庫em-Synchrony,提升IO輸送量。 #failed, 經測試,不穩定,介面版本有時不匹配,需3.1以上版的rails。4. 使用rubinus or jruby 提升執行效能 #failed,經測試jruby 記憶體損耗太大, rubinus有相容性問題。5. 去除rails預設載入的非必需的middleware #rails預設載入20多個中介軟體,有些是無需的。 進過以上幾個步驟的最佳化調整,進過ab測試發現,輸送量可以提升2到3倍, 負載能力也有提升,但沒有去測極限資料。
三:web伺服器最佳化建議: 建議使用多進程多線程版的puma替代多進程單線程passenger, 或者 任然使用passenger,但是配置成預設開啟14個worker,方便高峰時段留兩個cpu給mysql使用。 另外, 由於puma可以一定程度利用多線程來serve http請求,為了保證安全執行緒,需修改iredmine代碼: 添加config.threadsafe!到config/enviroment目錄下的production.rb檔案中 # enable multithread, and keep thread safe. config.threadsafe!1. puma的使用: 啟動14個背景工作處理序*16個線程,提升吞吐率。 puma -w 14 -t 16 -p 8080 /redmine/apps/redmine/htdocs/config.ru
2. 配置passenger方法: 設定檔在:/redmine/apache2/conf/bitnami 目錄下,添加以下: PassengerMaxPoolSize 14
四:mysql伺服器最佳化建議:1. 在mysql的設定檔中開啟一下設定(以下有兩個變數設定後需要重啟mysql): Threads_cached -> ON thread_cache_size = 64; query_cache_size (>= 8M) join_buffer_size (> 128.0K) tmp_table_size (> 16M) max_heap_table_size (> 16M) thread_cache_size (start at 4) table_open_cache (> 800) innodb_buffer_pool_size (>= 371M)另外還有: thread_concurrency = 32; (cpu*2)關於mysql的使用者請求壓力情況,請查看http://172.26.1xx.xx:8080/mycheckpoint/
五:rails最佳化建議: 刪除不需要的middleware請聯合目前redmine外掛程式開發人員,根據當前rails的實際middleware使用方式進行篩選刪除。方法:可以在application configuration 檔案中添加以下代碼來刪除。# config/application.rbconfig.middleware.delete "Rack::Lock"config.middleware.delete ‘Rack::Cache‘ # 整頁緩衝,似乎在redmine中沒有用上。config.middleware.delete ‘Rack::Runtime‘ # 記錄X-Runtime(方便用戶端查看執行時間)config.middleware.delete ‘ActionDispatch::RequestId‘ # 記錄X-Request-Id(方便查看請求在群集中的哪台執行)config.middleware.delete ‘ActionDispatch::RemoteIp‘ # IP SpoofAttackconfig.middleware.delete ‘ActionDispatch::Callbacks‘ # 在請求前後設定callbackconfig.middleware.delete ‘ActionDispatch::Head‘ # 如果是HEAD請求,按照GET請求執行,但是不返回bodyconfig.middleware.delete ‘ActionDispatch::BestStandardsSupport‘ # 設定X-UA-Compatible, 在nginx上設定等等。。
六: 去除production 模式下rails不需要的log 與 某些異常的修正。
1. 由於在production.log中發現了大段的debug模式才需要的log全部輸出到了log檔案中,耗時較長,建議刪除。
2. 某些url出現了 runexception. 建議修正, 或者在 middleware中去除名稱為: use ActionDispatch::ShowExceptionsuse ActionDispatch::DebugExceptions
七: 部分redmine外掛程式寫的比較糟糕,render耗時間長度達3000ms
相關資訊:
1. linux系統效能定位與排查: http://www.cnblogs.com/ToDoToTry/p/4423577.html
2. ab壓力測試方法:
3. mysql效能記錄與分析:
4. mysql最佳化工具:
5. linux IO問題分析與排查:
6. mysql效能測試工具與方法:
Redmine效能最佳化方案