这篇文档是如何提高moodle(魔灯)性能【performance】和可伸缩性【performance】的编码指南。
性能【performance】是指允许Moodle(魔灯)使用一定数量的硬件支持尽可能多的用户。
当然,你总是可以购买更大的服务器。可伸缩性【scalability】意味着,如果你购买的服务器的功能是原来的两倍,那么它可以处理两倍的负载。
编写可扩展和执行的代码
每个页面应该只使用固定数量的数据库查询
- 如果在循环中看到数据库访问操作,一定要保持警惕。如果数据库访问隐藏在函数中,有时很难发现这一点。
- 使用联接【JOINs】和子查询(get_records_sql、get_recordset_sql等)而不是循环执行多个查询。
- 或者找到一个Moodle API函数,尽可能高效地获取您想要的数据。(例如,get_users_by_capability)。
- 了解如何编写适用于所有受支持数据库的SQL,参考官方的《数据库指南》【Database guidelines】文档。
限制每个页面在生成时所需的内存大小
- 大型报表应该按固定大小的页面进行分页。
- 当您无法使用SQL在数据库中完成所有业务操作时,处理来自数据库的大量数据,应该使用记录集,并使用recordset_walk迭代器(moodle/lib/classes/dml/recordset_walk.php),避免将所有结果加载到大型PHP数组中消耗内存。
警惕外部调用【external call】
与数据库查询一样,还有其他操作比只执行PHP代码慢得多。例如:
- 运行shell脚本;
- 进行web服务调用;
- 处理文件(程度较轻)。
无论何时做这些事情,都要注意性能问题。
限制会话锁【session locks】的范围
如果您不需要会话锁,或者只需要在页面的一部分使用它,请解锁会话。
如何提高代码的性能
在开发过程中评估性能
- 启用显示性能信息【Performance info】(包括数据库查询操作计数)。管理员登录后,在 网站管理->开发->调试 中勾选perfdebug配置项。勾选性能信息设置项,将在标准主题【theme】(以及其他一些主题)的页脚中显示如下性能信息:页面加载时间、用于生成页面的内存量、cpu使用率、负载、记录缓存的命中/未命中率。如果需要对数据库查询操作计数,还需要在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);
小技巧:如果希望只对站点管理员显示性能信息,可以在适当的位置(比如布局页面的顶部),加入如下代码:
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个数据库查询,随时可以插入cronjob并每天给你发电子邮件。脚本可以在这里找到:
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进行一些配置,使其以正确的格式记录内容。
MySQL数据库有⼏个配置选项可以帮助我们及时捕获慢SQL语句:
# 开启日志记录慢查询
slow_query_log = ON
# 阈值,记录执行时间超过2秒的慢查询
long_query_time = 2
# 指定日志文件
slow_query_log_file = path/to/log/file/slowquery.log
# 记录不使用索引查询,即使查询效率不慢
log_queries_not_using_indexes = ON
# 记录数据库管理SQL中慢sql
log-slow-admin-statements = ON
Moodle(魔灯)网站能支持多大负荷
从统计数据来看,目前世界上最大的Moodle(魔灯)站点
- 多达100万用户
- 多达5万门课程
- 每门课程多达5000名用户
- 多达50个角色
- 多达100个课程类别,嵌套深度约为10级。
- 课程中多达XXX项活动。
- 更多内容。。。
在规划和测试代码时,这些是您应该考虑的数字。然而,不要认为Moodle(魔灯)网站永远不会比这更大。
即使不能在开发服务器上测试这么大的站点,也应该使用生成器脚本,这样就可以在一个不小的Moodle(魔灯)站点上测试代码。