這篇文檔是如何提高moodle(魔燈)性能【performance】和可伸縮性【performance】的編碼指南。
性能【performance】是指允許Moodle(魔燈)使用一定數(shù)量的硬件支持盡可能多的用戶。
當(dāng)然,你總是可以購買更大的服務(wù)器。可伸縮性【scalability】意味著,如果你購買的服務(wù)器的功能是原來的兩倍,那么它可以處理兩倍的負載。
編寫可擴展和執(zhí)行的代碼
每個頁面應(yīng)該只使用固定數(shù)量的數(shù)據(jù)庫查詢
- 如果在循環(huán)中看到數(shù)據(jù)庫訪問操作,一定要保持警惕。如果數(shù)據(jù)庫訪問隱藏在函數(shù)中,有時很難發(fā)現(xiàn)這一點。
- 使用聯(lián)接【JOINs】和子查詢(get_records_sql、get_recordset_sql等)而不是循環(huán)執(zhí)行多個查詢。
- 或者找到一個Moodle API函數(shù),盡可能高效地獲取您想要的數(shù)據(jù)。(例如,get_users_by_capability)。
- 了解如何編寫適用于所有受支持?jǐn)?shù)據(jù)庫的SQL,參考官方的《數(shù)據(jù)庫指南》【Database guidelines】文檔。
限制每個頁面在生成時所需的內(nèi)存大小
- 大型報表應(yīng)該按固定大小的頁面進行分頁。
- 當(dāng)您無法使用SQL在數(shù)據(jù)庫中完成所有業(yè)務(wù)操作時,處理來自數(shù)據(jù)庫的大量數(shù)據(jù),應(yīng)該使用記錄集,并使用recordset_walk迭代器(moodle/lib/classes/dml/recordset_walk.php),避免將所有結(jié)果加載到大型PHP數(shù)組中消耗內(nèi)存。
警惕外部調(diào)用【external call】
與數(shù)據(jù)庫查詢一樣,還有其他操作比只執(zhí)行PHP代碼慢得多。例如:
- 運行shell腳本;
- 進行web服務(wù)調(diào)用;
- 處理文件(程度較輕)。
無論何時做這些事情,都要注意性能問題。
限制會話鎖【session locks】的范圍
如果您不需要會話鎖,或者只需要在頁面的一部分使用它,請解鎖會話。
如何提高代碼的性能
在開發(fā)過程中評估性能
- 啟用顯示性能信息【Performance info】(包括數(shù)據(jù)庫查詢操作計數(shù))。管理員登錄后,在 網(wǎng)站管理->開發(fā)->調(diào)試 中勾選perfdebug配置項。勾選性能信息設(shè)置項,將在標(biāo)準(zhǔn)主題【theme】(以及其他一些主題)的頁腳中顯示如下性能信息:頁面加載時間、用于生成頁面的內(nèi)存量、cpu使用率、負載、記錄緩存的命中/未命中率。如果需要對數(shù)據(jù)庫查詢操作計數(shù),還需要在config.php中加入如下代碼:
// Capture performance profiling data
define('MDL_PERF', true);
// Capture additional data from DB
define('MDL_PERFDB', true);
// Print to log (error_log(),for passive profiling of production servers)
define('MDL_PERFTOLOG', true);
// Print to footer (works with the default theme)
define('MDL_PERFTOFOOT', true);
小技巧:如果希望只對站點管理員顯示性能信息,可以在適當(dāng)?shù)奈恢茫ū热绮季猪撁娴捻敳浚?,加入如下代碼:
if (is_siteadmin()) {
$CFG->perfdebug = 8;
}
- 使用JMeter(https://jmeter.apache.org/)等工具對新代碼做壓力測試。
- 使用https://github.com/moodlehq/moodle-performance-comparison (moodle 2.5及以上版本)比較Moodle的性能。您還可以使用測試站點生成器【Test site generator】或測試課程生成器【Test course generator】(Moodle 2.5及以上版本)。
在運行中評估性能
如果你使用postgres,有一個腳本可以解析日志并輸出最慢的10個數(shù)據(jù)庫查詢,隨時可以插入cronjob并每天給你發(fā)電子郵件。腳本可以在這里找到:
http://git.catalyst.net.nz/gw?p=pgtools.git;a=blob_plain;f=scripts/pg-log-process.pl;hb=refs/heads/pg-log-process-multidb
需要對postgres進行一些配置,使其以正確的格式記錄內(nèi)容。
MySQL數(shù)據(jù)庫有?個配置選項可以幫助我們及時捕獲慢SQL語句:
# 開啟日志記錄慢查詢
slow_query_log = ON
# 閾值,記錄執(zhí)行時間超過2秒的慢查詢
long_query_time = 2
# 指定日志文件
slow_query_log_file = path/to/log/file/slowquery.log
# 記錄不使用索引查詢,即使查詢效率不慢
log_queries_not_using_indexes = ON
# 記錄數(shù)據(jù)庫管理SQL中慢sql
log-slow-admin-statements = ON
Moodle(魔燈)網(wǎng)站能支持多大負荷
從統(tǒng)計數(shù)據(jù)來看,目前世界上最大的Moodle(魔燈)站點
- 多達100萬用戶
- 多達5萬門課程
- 每門課程多達5000名用戶
- 多達50個角色
- 多達100個課程類別,嵌套深度約為10級。
- 課程中多達XXX項活動。
- 更多內(nèi)容。。。
在規(guī)劃和測試代碼時,這些是您應(yīng)該考慮的數(shù)字。然而,不要認(rèn)為Moodle(魔燈)網(wǎng)站永遠不會比這更大。
即使不能在開發(fā)服務(wù)器上測試這么大的站點,也應(yīng)該使用生成器腳本,這樣就可以在一個不小的Moodle(魔燈)站點上測試代碼。