Moodle教学服务器的构建与优化
作者: 罗清波
关键词:LNMP;Moodle;服务器;PHP;高并发;抗拥塞
中图分类号:TP393 文献标识码:A
文章编号:1009-3044(2023)02-0069-03
Moodle是基于PHP语言开发的免费开放学习管理系统(LMS),由于采用了组件化管理,教学手段灵活,功能齐全,所以被国内外教育机构普遍使用。LNMP是当今比较流行的免费开源Web服务框架,该架构涉及技术范围广,安装和配置相对复杂。如果沿用传统的配置方式,不能最大程度发挥Moodle教学服务器的性能,而且系统在安全性和高效性方面也得不到保证。服务器在高并发情况下网页很容易卡死,甚至会导致数据库崩溃,所以对LNMP架构进行优化是亟待解决的问题[1]。
1 LNMP 架构介绍
LNMP架构由Linux 内核服务器、Nginx 服务器、Mysql数据库系统、PHP脚本服务器组合而成。Nginx 是高性能轻量级反向代理服务器,Mysql是一款安全、跨平台、高效的数据库系统,PHP脚本服务器用于编译和执行PHP脚本。LNMP架构数据请求与返回如图1所示[2]。
从图1可以看出,数据总是从客户端浏览器经过Nginx服务器、php-fpm服务器、MySQL数据库后,又按原路返回,形成闭环回路,为了提高Moodle教学服务器的性能,需要对LNMP 架构的各个环节进行优化处理。
2 Moodle 教学平台介绍
Moodle是由澳大利亚教师Martin发起的开放学习管理系统(LMS)[3] 。该学习管理系统采用模块化组件设计,目前系统组件种类高达1967个,提供全方位教学手段。教师可以使用这些组件完成不同的教学方案,可以实现不同的教育教学模式。这些组件安装方便,操作简单,与原有的系统共存使用。目前世界上多个国家近千所高校和教科研机构都采用Moodle 作为网络在线教学平台[4]。
3 服务器处理速度优化
通过开启Opcache 和TMPFS,优化Mysql 数据库的InnoDB,优化PHP进程,开启gzip传输、开启Cron.php定时运行,可以大幅度提高Moodle教学服务器的处理速度。
3.1 开启Opcache
PHP作为一种解释性语言,每次运行都会将代码进行加载解析,运行结束后再释放,下次运行又要重新加载解析再释放。这种方式显然不适合高并发运行的Moodle教学服务器。
为了避免这样的问题出现,PHP开发了Opcache 组件,系统启用Opcache后,在解析过程中可以将一些相同并且重复的中间件保存在Opcache缓存中,下次加载时无须再编译,加快了代码的执行效率,降低了CPU的消耗,减少了PHP网页的响应时间。
3.2 开启TMPFS
服务器的内存储器访问速度比磁盘的访问速度要快得多,如果将Moodle网站的程序文件和数据库直接放置在内存储器中,Moodle站点的处理速度就会大幅度提高。将磁盘文件存储在内存储器中的方法是启用TMPFS缓存系统。TMPFS的特点是暂时存储、高速读写和动态收缩。TMPFS默认的初始化存储空间为物理内存的一半,这部分存储空间不会被独占,仅在挂载存储文件后才会占用。挂载命令:mount-tTMPFS -o size=65536M,mode=0755 tmpfs /var/www/cache。
3.3 多进程处理
为了充分发挥CPU的多核特征,可以将Nginx和php-fpm设置为多进程模式,提高处理效率。Nginx通过反向代理功能将用户浏览器的PHP动态请求分配给空闲的Nginx工作进程。Nginx并不参与PHP的请求编译和运行工作,而是交由php-fpm 管理进程处理。php-fpm将具体的任务分配给空闲的Fast-CGI协议[5],由Fast-CGI协议负责编译和运行,并与后台数据库实现数据交互,最后将结果以超文本形式返回给用户浏览器。
Nginx 通过配置worker_ processes 的值开启多进程工作模式。这个数值必须与CPU的内核数相匹配,如果设置不恰当会使服务器假死。
php-fpm 进程管理有三种模式,分别为onde⁃mand、dynamic和static。配置文件地址为/etc/php/7.2/php-fpm.conf。
如果将配置文件中pm参数设置为Ondemand(按需模式),在php-fpm开始启动时,不会创建任何进程,当有连接请求时才会创建。进程数量取决于pm.max_children设定值,如果空闲进程时间超过pm.pro⁃cess_idle_timeout设定的值,进程将关闭,一般默认设置为10ms。
如果将配置文件中pm参数设置为Dynamic(动态模式),在php-fpm 启动时,初始启动的个数为pm.start_servers 设定值,在运行过程中动态调整进程数量,进程数量最大取决于pm.max_children设定值。
如果将配置文件中的pm参数设置为Static (静态模式),php-fpm开始启动后始终保持pm.max_children 设定值,在运行期间也不会扩容。
Moodle 教学服务器采用static 静态模式。一般php-fpm进程占用最大内存空间为30M,在静态模式下pm.max_children的值可设置为物理内存Mem/30M,但考虑到操作系统、Nginx、MySQL都需要占用内存,所以php-fpm进程数可以设为物理内存Mem/30M/2。
3.4 存储引擎InnoDB
InnoDB作为MySQL数据库的默认存储引擎被广泛应用。MySQL数据库接收SQL请求后,通过InnoDB存储引擎与磁盘存储文件进行交互。在LNMP架构中,和数据库有关的用户请求都要通过InnoDB存储引擎,因此,优化InnoDB 存储引擎的性能决定了LNMP架构的性能。InnoDB存储引擎参数设置文件为/etc/mysql/my.cnf,设置参数如表1所示。
在InnoDB存储引擎中,通常情况下将日志文件组设置为3,为了避免日志覆盖导致缓冲池的不必要刷新,每个日志文件的大小最好设置为InnoDB缓冲池的25%。为了防止线程设置过高产生抖动,一般将线程并发数设置为16。读线程和写线程是InnoDB存储引擎用来同步操作系统中的读写操作,一般设定参数值为8。控制Innodb事务日志写入的参数值设置为2,确保日志及时写入磁盘并刷新,这样设置不仅可以使InnoDB存储引擎的日志存盘时间变小,而且保证了数据的安全。
3.5 Cron.php 计划任务定时运行
在Moodle教学服务器中,Cron.php主要用于计划执行课程备份、邮件收发、临时文件清理、课程整理、删除不需要的检测事件等,设置为每隔5分钟执行一次效果最佳。
通过命令sudo apt-get install cron安装Cron,然后用命令crontab -e 打开活动列表,将下面的命令添加到Cron活动列表中,实现每5分钟执行一次cron.php 程序文件,password的值通过Moodle管理后台获取。
*/5 **** wget –q –o /dev/null
https://ke.qingbosoft.cn/admin/data/cron.php?pass⁃word=”*****”
4 抗拥塞处理
当服务器遇到高并发请求时,会使服务器响应速度变慢,数据库崩溃,甚至服务器宕机等事故发生,所以需要对服务器进行抗拥塞处理。出现拥塞的原因主要有两个方面,一方面MySQL数据库采用默认的单线程处理模式,另一方面PHP进程数开启过大,使数据库同步连接数变大。抗拥塞处理的方法是对MySQL 数据库启用线程池,并配置合理的PHP 进程数。
4.1 Thread Pool 线程池优化
PHP 与MySQL 建立连接后,PHP 通过MySQL 的线程机制来处理请求。MySQL默认的线程调度方式为One-Connection-Per-Thread单线程模式,当使用单线程处理每个客户的连接请求时,对于每一个数据库连接,MySQL 都要创建独立的线程服务,请求结束后再销毁掉,当数据库遇到高并发时,线程频繁创建和销毁,服务器的性能会大幅度降低。
为了解决这个问题,Oracle 公司推出了线程池(Thread Pool Plugin)方案。线程池通过缓存并重用方式,将连接分配给不同的组队列,对用户的SQL 请求进行排队处理,减少上下文切换次数,通过队列机制缩短了处理请求的时间。同时,线程的重用降低了频繁的连接请求次数,即使在访问高峰期,数据库仍然能保持高吞吐量,有效解决拥塞问题。Thread Pool线程池的参数配置文件为/etc/mysql/my.cnf,配置参数如表2所示。
4.2 PHP 进程数配置
在Moodle教学服务器中,用户请求通过Nginx发送到php-fpm,然后以队列的形式发送给多个Fast-CGI 进行处理,每个Fast-CGI 与MySQL 建立连接,MySQL数据库通过Thread Pool线程池处理Fast-CGI 的SQL请求。
当Nginx的pm参数设置为Dynamic动态模式时,如果有1024 个用户同时访问Moodle 应用服务器,MySQL数据库就需要创建1024个链接与php-fpm所创建的1024个Fast-CGI相连,并同时处理1024个工作线程,这样会造成Mysql数据库阻塞,使服务器无法高效运行。
为了提高服务器的运行效率,需要固定PHP的进程数目。所以将Nginx的pm参数设置为Static静态模式。pm.max_children进程值可以根据MySQL数据库的最大允许连接数来推算。如果MySQL数据库的每个连接所占内存容量最大为36.8MB,而分配给数据库的总内存为36G, 则MySQL数据库的最大连接数可以设置为1000,php-fpm中pm.max_children进程数可以设置为1000。但一般情况下Fast-CGI进程占用内存最大值为30MB,而且还要考虑到服务器其他应用的开销,所以pm.max_children进程数的值一般设置为64 就够用了[6]。
5 服务器性能测试
5.1 性能测试
使用Google浏览器自带的Network工具对Moodle 应用服务器进行整体性能测试,测试服务器Request 和Response的请求响应耗时。
发现优化前加载https://ke.qingbosoft.cn/course 课程页面,PHP访问MySQL数据库需要耗时350ms左右,而通过系统优化处理后,Moodle课程页面加载耗时总体稳定在146ms左右,处理速度提高了2.6倍,服务器性能得到了很大程度的提升[7]。
5.2 抗拥塞检测
通过使用Sysbench压力测试工具对MySQL数据库进行只读压力测试。分别设置MySQL数据库为单线程(One-Connection-Per-Thread)模式和线程池(Thread Pool)模式,对两种模式进行高并发条件下TPS数据吞吐量测试,测试结果如图2所示。
检测结果表明,伴随着并发数目的不断增大,单线程模式下TPS数据吞吐量急速下降,当并发数达到5000时,单线程TPS数据吞吐量几乎为0,而线程池模式的TPS 数据吞吐量始终稳定在6500~7100左右。所以使用线程池模式,可以很好地解决数据库在高峰访问时的拥塞问题,有效提高了Moodle教学服务器的访问速度[8]。
6 结束语
本文详细论述了基于LNMP架构的Moodle教学服务器的构建与优化,对服务器的LNMP架构进行深度优化,目前应用在Moodle在线教学平台(网址https://ke.qingbosoft.cn)上,服务器性能稳定可靠,起到了很好的教学应用效果。
文中提出的构建及优化方案对搭建基于Linux内核操作系统的网站服务器具有很好的参考价值。随着科技不断进步,受新冠肺炎疫情影响,更多的教育机构都在开发和搭建自己的在线教学系统,人们对基于LNMP架构的应用服务器进行不断地探索与研究,必将使其能更加安全、快速、高效地提供服务。