====== Moodle Mooc ====== ===== Introduction ===== Telecom SudParis à mis en place en decembre 2013 un MOOC intitulé "Comprendre les concepts des Télécommunication": http://mooc.telecom-sudparis.eu. Cette page presente les aspects techniques systemes mis en oeuvre afin d'assurer la diffusion de ce MOOC. Fort de notre experience sur la plateforme Moodle pour les cours en ligne des formations initiales et continus, et considerant les delais impartis, nous avons jugés opportun de poursuivre sur le LMS Moodle pour la diffusion de ce MOOC. Cette article aborde les aspects tehniques : * applicatifs (moodle, gestionnaire git) et backends (apache, mysql), * des tests de montés en charge (tsung), * reporting, statistiques d'usages ===== References ===== * http://docs.moodle.org/2x/fr/Installation_rapide * http://docs.moodle.org/23/en/Moodle_Production_Server_with_GIT discussion regarding moodle as a mooc plateform * https://moodle.org/mod/forum/discuss.php?d=204799&buffer_share=28e35 ===== statitics ===== pour commencer l'article sur un apect visuel, voici ci-dessous quelques graphs de statistics en terme d'usage appplicatifs (cours moodle), systeme (serveur load et apache hits) , logiciel d'analyse de log apache => awstats ==== moodle ==== tous les acces {{:docpublic:systemes:moodle:mooc-concepts-telecom-all-1w.png?200|}} toutes les activités {{:docpublic:systemes:moodle:mooc-concepts-telecom-activities-1w.png?200|}} ==== system ==== apache hits {{:docpublic:systemes:moodle:mooc-concepts-telecom-cacti-hits-2013.png?200|}} system load {{:docpublic:systemes:moodle:mooc-concepts-telecom-cacti-load-2013.png?200|}} mysql requetes (1ere semaine) {{:docpublic:systemes:moodle:mooc-concepts-telecom-cacti-mysql-s-09-12-2013.png?200|}} ==== Awstats ==== le résumé awstats d'apache * Décembre 2013 {{:docpublic:systemes:moodle:mooc-concepts-telecom-awstats-resum12-2013.png?200|}} * Janvier 2014 {{:docpublic:systemes:moodle:2014-01-22-mooc-tsp-awstat-resume-janvier.jpg?200|}} ===== Moodle Mooc ===== reference sur l'installation de moodle 2.x * http://docs.moodle.org/2x/fr/Installation_rapide ==== database ==== création d'une base de donnée sur un serveur mysql mysql> CREATE DATABASE moodle_mooc; Query OK, 1 row affected (0.00 sec) mysql> GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP,INDEX,ALTER ON moodle_mooctsp.* to mooc-user@'mooctsp.int-evry.fr' IDENTIFIED by 'secret'; Query OK, 0 rows affected (0.00 sec) === statistiques === l'usage des statistiques dans moodle implique la possibilité à l'utilisateur propiétaire de la base de donnée de creer des tables temporaires, il faut donc ajouter cette aptitude à notre utilisateur [root@mysql /]# mysql -u root -p mysql> use mysql mysql> select * from db where User='mooc-user'; mysql> update db set Create_tmp_table_priv='Y' where User='mooc-user'; mysql> flush privileges; sans cette aptitude, la generation des statistiques moodle (reports) échoue. il est alors possible de lancer "manuellement" la generation des statistics en appelant le script cron_stats.php Server Time: Wed, 18 Dec 2013 15:37:02 +0100 Running daily statistics gathering, starting at 1383778800: ... started 15:37:03. Current memory use 26Mo. Temporary tables created Enrolments calculated 0:0 1:0 2:0 3:0 4:0 5:0 6:0 7:0 8:0 9:0 10:0 11:0 12:0 13:0 14:0 15:0 16:0 out:0 finished until 1383865200: vendredi 8 novembre 2013, 00:00 (in 0 s) ... ..stopping early, reached maximum number of 31 days (5 s) - will continue next time. ==== GIT moodle ==== Utilisation de GIT pour gerer plus finement notre instance moodle (mises à jours, versionning des modifications, plugins, logs etc ..) * http://docs.moodle.org/23/en/Moodle_Production_Server_with_GIT === variables d'environement GIT === [root@mooc ~]# mkdir git-moodle-mooc [root@mooc ~]# cd git-moodle-mooc/ [root@mooc git-moodle-mooc]# git config --global user.name "disi-sudparis" [root@mooc git-moodle-mooc]# git config --global user.email "admins@int-evry.fr" === repertoire de travail === [root@mooc git-moodle-mooc]# mkdir mooctsp [root@mooc git-moodle-mooc]# cd mooctsp/ === initialisation === initialisation du repertoire local et récuperation du code depuis la version de base MOODLE_25_STABLE sur le serveur git de moodle [root@mooc mooctsp]# git init Initialized empty Git repository in /root/git-moodle-mooc/mooctsp/.git/ [root@mooc mooctsp]# git remote add moodle git://git.moodle.org/moodle.git [root@mooc mooctsp]# git fetch moodle remote: Counting objects: 703676, done. remote: Compressing objects: 100% (164991/164991), done. remote: Total 703676 (delta 522649), reused 703676 (delta 522649) Receiving objects: 100% (703676/703676), 262.39 MiB | 9.71 MiB/s, done. Resolving deltas: 100% (522649/522649), done. From git://git.moodle.org/moodle * [new branch] MOODLE_13_STABLE -> moodle/MOODLE_13_STABLE ... * [new branch] master -> moodle/master ... From git://git.moodle.org/moodle * [new tag] v1.0.0 -> v1.0.0 ... * [new tag] v2.5.2 -> v2.5.2 * [new tag] v2.6.0-beta -> v2.6.0-beta Déclaration de suivi de la branche MOODLE_25_STABLE # git branch --track MOODLE_25_STABLE moodle/MOODLE_25_STABLE # git checkout MOODLE_25_STABLE ==== Repository mooc disi ===== Depuis la version moodle_stable2.5 on fork notre “version” maison (disi) du projet. [root@mooc mooctsp]# git checkout -b mooc_disi Switched to a new branch 'mooc_disi' A partir de là, nous allons gerer sur notyre propre serveur GIT, une version "remote" afin de disposer d'un serveur de distribution GIT de notre propre branche (pour d'eventuels clones et autres serveurs de failover ...) => declaration du remote disi # ssh-keygen # ssh-copy-id gituser@git.tem-tsp.eu # git remote add mooc ssh://gituser@git.tem-tsp.eu/~/moodle/mooc.git puis push vers le remote serveur (git.tem-tsp.eu) de notre branche mooc_disi # git push mooc mooc_disi:mooc_disi [root@mooc mooctsp]# git branch MOODLE_25_STABLE * mooc_disi === recapitulatif === etat des lieux GIT à ce niveau, liste de toutes les branches: [root@mooc mooctsp]# git branch -a MOODLE_25_STABLE * mooc_disi remotes/mooc/mooc_disi remotes/moodle/MOODLE_13_STABLE remotes/moodle/MOODLE_14_STABLE remotes/moodle/MOODLE_15_STABLE remotes/moodle/MOODLE_16_STABLE remotes/moodle/MOODLE_17_STABLE remotes/moodle/MOODLE_18_STABLE remotes/moodle/MOODLE_19_STABLE remotes/moodle/MOODLE_20_STABLE remotes/moodle/MOODLE_21_STABLE remotes/moodle/MOODLE_22_STABLE remotes/moodle/MOODLE_23_STABLE remotes/moodle/MOODLE_24_STABLE remotes/moodle/MOODLE_25_STABLE remotes/moodle/master D'apres http://www.techblogistech.com/2012/07/setting-a-default-upstream-branch-in-git/, nous devons indiquer a chaque commande git pull et git push depuis où retirer les modifications et vers où les envoyer. C'est fastidieux, nous allons donc fixer la branche remote par defaut. [root@mooc mooctsp]# git branch --set-upstream remotes/mooc/mooc_disi Branch remotes/mooc/mooc_disi set up to track local branch mooc_disi. ==== 1er mise en ligne via rsync ==== Nous mettons en ligne (dans une arborescence visible du serveur apache) notre repository d'instance maison moodle (mooctsp) [root@mooc mooctsp]# cd .. [root@mooc git-moodle-mooc]# rsync -a --delete --exclude=.htaccess --exclude=.git/ mooctsp /var/www/ ==== modification et ajout de fichiers ==== on veux gerer config.php via git donc on le retire de .gitignore [root@mooc mooctsp]# grep config.php .gitignore ##/config.php ajout et commit [root@mooc mooctsp]# cp config-dist.php config.php [root@mooc mooctsp]# vim config.php [root@mooc mooctsp]# git add config.php [root@mooc mooctsp]# git commit -a -m "add config.php and configured to DB mysql3" [mooc_disi 792f740] add config.php and configured to DB mysql3 1 files changed, 651 insertions(+), 0 deletions(-) create mode 100644 config.php ==== push serveur git local ==== on push nos modifications sur notre serveur git local [root@mooc mooctsp]# git push mooc mooc_disi:mooc_disi Counting objects: 8, done. Delta compression using up to 32 threads. Compressing objects: 100% (6/6), done. Writing objects: 100% (6/6), 11.24 KiB, done. Total 6 (delta 3), reused 0 (delta 0) To ssh://gituser@git.tem-tsp.eu/~/moodle/mooc.git c9ee1a7..792f740 mooc_disi -> mooc_disi ==== publication web ==== depuis notre répertoire de travail git (dans le homedir de root) nous allons pousser notre instance moodle dans une arborescence de visibilité web d'apache => "DocumentRoot" [root@mooc git-moodle-mooc]# rsync -av --delete --exclude=.htaccess --exclude=.git/ mooctsp /var/www/ sending incremental file list mooctsp/ mooctsp/.gitignore mooctsp/config.php sent 354720 bytes received 3558 bytes 238852.00 bytes/sec total size is 116222732 speedup is 324.39 ==== etat des lieux ==== [root@mooc mooctsp]# git remote -v mooc ssh://gituser@git.tem-tsp.eu/~/moodle/mooc.git (fetch) mooc ssh://gituser@git.tem-tsp.eu/~/moodle/mooc.git (push) moodle git://git.moodle.org/moodle.git (fetch) moodle git://git.moodle.org/moodle.git (push) [root@mooc mooctsp]# git remote show mooc * remote mooc Fetch URL: ssh://gituser@git.tem-tsp.eu/~/moodle/mooc.git Push URL: ssh://gituser@git.tem-tsp.eu/~/moodle/mooc.git HEAD branch: (unknown) Remote branches: mooc_disi tracked Local refs configured for 'git push': mooc_disi pushes to mooc_disi (up to date) ===== Apache ===== Définition d'un Virtual Host Apache pour heberger cette instance moodle-mooc => création d'un fichier de configuration spécifique dans conf.d d'apache. On notera l'usage d'une authentification SSO shibboleth pour la communauté education/recherche, qui ne sera pas detaillée ici, c'est un sujet à part entiere ... On gere aussi une instance en https avec les certificats qui vont bien. [root@mooc ~]# cat /etc/httpd/conf.d/mooc.conf #mooctsp ServerName mooc.telecom-sudparis.eu # ServerAlias mooc.* DocumentRoot /var/www/mooctsp ErrorLog logs/mooctsp-error_log CustomLog logs/mooctsp-access_log combined # Moodle private data - must NOT be publically accessible Order deny,allow Deny from all AuthType shibboleth ShibRequireSession On require valid-user ShibRequestSetting applicationId default #mooc https ServerName mooc.telecom-sudparis.eu # ServerAlias mooc.* DocumentRoot /var/www/mooctsp ErrorLog logs/ssl_mooctsp-error_log CustomLog logs/ssl_mooctsp-access_log combined LogLevel warn SSLEngine on SSLCipherSuite ALL:!ADH:!EXPORT:!SSLv2:RC4+RSA:+HIGH:+MEDIUM:+LOW SSLCertificateFile /etc/pki/tls/certs/cert-19020-mooc.telecom-sudparis.eu.pem SSLCertificateKeyFile /etc/pki/tls/private/mooc_telecom-sudparis_nop.key SSLCertificateChainFile /etc/pki/tls/certs/chain-19020-mooc.telecom-sudparis.eu.pem SSLCACertificateFile /etc/pki/tls/certs/add_trust_external_ca_root.pem Order deny,allow Deny from all AuthType shibboleth ShibRequireSession On require valid-user ShibRequestSetting applicationId default #ipv6 mooc # .... # desctivation de cette version IPv6 pour l'instant ... ==== moodledata ==== l'espace de stockage de data de moodle [root@mooc mooctsp]# mkdir /var/www/moodledata_mooctsp/ [root@mooc mooctsp]# chown -R apache /var/www/moodledata_mooctsp ===== installation web ==== Une fois le serveur apache parametré, on peux lancer l'installation interractive de moodle depuis l'interface web http://mooc.telecom-sudpris.eu/admin/index.php ====== Plateforme de stress applicatif Tsung====== Quand on met en ligne une application il est toujours intéréssant de pouvoir tester sa montée en charge. Une application fonctionnant très bien sous une faible charge peut s'avérer défaillante lors de la montée en charge. Pour cela nous allons utiliser [[wp>tsung]]. ==== installation ==== au plus simple, tsung etant packagé ! yum install tsung il s'installe avec toute une série de dépendance de packages "erlang-*" . ==== plateforme distribuée ==== Nous utiliserons plusieurs agents tsung, afin d'effectuer acces distribué sur 3 clients, le host principal (ici flow) et deux "slave" (wik.tem-tsp.eu et aude.tem-tsp.eu) ==== astuce de parametrage ==== pour que le coté distribué fonctione il faut plusieurs conditions, un bon fichier /etc/hosts, un bon partage de clés ssh, un bon hostname etc ... cf * http://tsung.erlang-projects.org/user_manual/faq.html#can-t-start-distributed-clients-timeout-error * http://lists.process-one.net/pipermail/tsung-users/2013-November/002744.html * http://lists.process-one.net/pipermail/tsung-users/2013-November/002758.html il faut aussi que le "master" tsung accept les packets des ces slave dans le firewall [root@flow .tsung]# grep /32 /etc/sysconfig/iptables -A RH-Firewall-1-INPUT -s 157.159.11.129/32 -m state --state NEW -m tcp -p tcp -j ACCEPT -A RH-Firewall-1-INPUT -s 157.159.211.18/32 -m state --state NEW -m tcp -p tcp -j ACCEPT test erl de base depuis le master flow vers le slave aude.tem-tsp.eu : [root@flow .tsung]# erl -rsh ssh -sname foo -setcookie mycookie Erlang R14B04 (erts-5.8.5) [source] [smp:32:24] [rq:32] [async-threads:0] [kernel-poll:false] Eshell V5.8.5 (abort with ^G) (foo@flow)1> slave:start(aude,bar,"-setcookie mycookie"). {ok,bar@aude} ==== senario moocZ ==== nous utilisons un clone de notre serveur mooc (moocZ) pour effectuer cette montée en charge [root@flowmon .tsung]# cat tsung-moocZ-scenario5.xml ==== Rapport tsung ==== on peux lancer un rapport sur la campagne de test tsung réalisée en lançant dans le repertoire de log correpondant la commande "/usr/lib/tsung/bin/tsung_stats.pl" [root@flow log]# cd 20140103-1439 [root@flow 20140103-1439]# /usr/lib/tsung/bin/tsung_stats.pl creating subdirectory data creating subdirectory gnuplot_scripts creating subdirectory images warn, last interval (7) not equal to the first, use the first one (10) No data for Bosh No data for Match No data for Async No data for Errors Cela génere des graphs gnuplot et une page report.html qui resume l'ensemble, en voici un apperçu: {{:docpublic:systemes:moodle:tsung-moocz-2014-01-03-16h-sc5.png?200|}} ===== Tunning openvz ===== La machine étant sous forme de VM / container openvz, des ajustements ont du etre mis en place pour repondre à la monté en charge une reference en français sur le sujet: * http://www.kogitae.fr/kafe-in-net-blogopenvz-les-ressources-systeme-dans-un-ve.html # vzctl set 10035 --numproc=800 --save # vzctl set 10035 --tcpsndbuf=5500000 --save # vzctl set 10035 --diskinodes 400000:500000 --save Running: /usr/sbin/vzquota stat 10035 -f Running: /usr/sbin/vzquota setlimit 10035 -i 400000 -I 500000 CT configuration saved to /etc/vz/conf/10035.conf UB limits were set successfully CT configuration saved to /etc/vz/conf/10035.conf # vzlist -o ctid,hostname,laverage,privvmpages,numproc,numtcpsock,tcpsndbuf,kmemsize,kmemsize.l -s laverage CTID HOSTNAME LAVERAGE PRIVVMP NPROC NTCPSOCK TCPSNDB KMEMSIZE KMEMSIZE.L 100041 muxt.tem-tsp.eu 0.00/0.00/0.00 215695 86 8 139520 752963645 9223372036854775807 100035 mooc.telecom-sudparis.eu 0.15/0.21/0.18 389644 105 12 404216 1171646505 9223372036854775807 [root@mooc ~]# cat /proc/user_beancounters Version: 2.5 uid resource held maxheld barrier limit failcnt 10035: kmemsize 1179549397 1182105600 9223372036854775807 9223372036854775807 0 lockedpages 0 0 4096 4096 0 privvmpages 420415 1351322 1024000 2048000 0 shmpages 270 1566 131072 131072 0 dummy 0 0 9223372036854775807 9223372036854775807 0 numproc 133 363 800 800 0 physpages 666304 956320 0 9223372036854775807 0 vmguarpages 0 0 2048000 9223372036854775807 0 oomguarpages 213170 473926 2048000 9223372036854775807 0 numtcpsock 8 205 500 500 0 numflock 4 34 200 220 0 numpty 1 2 64 64 0 numsiginfo 0 78 512 512 0 tcpsndbuf 139520 5486448 5365760 10485760 417584502 tcprcvbuf 131072 1323600 5365760 10485760 0 othersockbuf 197280 423808 1503232 4063232 0 dgramrcvbuf 0 13080 262144 262144 0 numothersock 243 337 500 500 0 dcachesize 1164468912 1164674029 9223372036854775807 9223372036854775807 0 numfile 1655 2445 8192 8192 0 dummy 0 0 9223372036854775807 9223372036854775807 0 dummy 0 0 9223372036854775807 9223372036854775807 0 dummy 0 0 9223372036854775807 9223372036854775807 0 numiptent 53 53 128 128 0 ===== Process Apache ===== configuration standard du package apache pour RedHat/centos, mode Prefork conservé par defaut, ==== MPM Prefork vs Worker ==== A propos de MPM prefork vs worker il y a bien des soucis avec php qui serait parfois "non thread-safe", donc problématique sur le model worker (threaded) d'apache from: http://stackoverflow.com/questions/1623914/what-is-thread-safe-or-non-thread-safe-in-php "Since with mod_php, PHP gets loaded right into Apache, if Apache is going to handle concurrency using its Worker MPM (that is, using Threads) then PHP must be able to operate within this same multi-threaded environment -- meaning, PHP has to be thread-safe to be able to play ball correctly with Apache! At this point, you should be thinking "Ok, so if I'm using a multi-threaded web server and I'm going to embed PHP right into it, then I must use the thread-safe version of PHP". And this would be correct thinking. However, as it happens, PHP's thread-safety is highly disputed. It's a use-if-you-really-really-know-what-you-are-doing ground." liste des extensions apache non thread-safe * http://php.net/manual/en/faq.obtaining.php#faq.obtaining.optional explications détaillées * http://www.trbailey.net/tech/mpm-worker.html on a les librairies GD et ldap sur moodle qui sont peut-etre douteuses sur le sujet!? Parametres prefork positionnés StartServers 8 MinSpareServers 5 MaxSpareServers 20 ServerLimit 256 MaxClients 256 MaxRequestsPerChild 4000 [root@mooc ~]# apachectl -V Server version: Apache/2.2.15 (Unix) Server built: Aug 13 2013 17:27:11 Server's Module Magic Number: 20051115:25 Server loaded: APR 1.3.9, APR-Util 1.3.9 Compiled using: APR 1.3.9, APR-Util 1.3.9 Architecture: 32-bit Server MPM: Prefork threaded: no forked: yes (variable process count) Server compiled with.... -D APACHE_MPM_DIR="server/mpm/prefork" -D APR_HAS_SENDFILE -D APR_HAS_MMAP -D APR_HAVE_IPV6 (IPv4-mapped addresses enabled) -D APR_USE_SYSVSEM_SERIALIZE -D APR_USE_PTHREAD_SERIALIZE -D SINGLE_LISTEN_UNSERIALIZED_ACCEPT -D APR_HAS_OTHER_CHILD -D AP_HAVE_RELIABLE_PIPED_LOGS -D DYNAMIC_MODULE_LIMIT=128 -D HTTPD_ROOT="/etc/httpd" -D SUEXEC_BIN="/usr/sbin/suexec" -D DEFAULT_PIDLOG="run/httpd.pid" -D DEFAULT_SCOREBOARD="logs/apache_runtime_status" -D DEFAULT_LOCKFILE="logs/accept.lock" -D DEFAULT_ERRORLOG="logs/error_log" -D AP_TYPES_CONFIG_FILE="conf/mime.types" -D SERVER_CONFIG_FILE="conf/httpd.conf" Process apache par defaut [root@mooc ~]# ps -elf | grep http | wc -l 22 stats $ curl -s 'http://mooc.telecom-sudparis.eu/server-status?auto' Total Accesses: 119166 Total kBytes: 2134616 CPULoad: 4.27854 Uptime: 312481 ReqPerSec: .381354 BytesPerSec: 6995.14 BytesPerReq: 18342.9 BusyWorkers: 11 IdleWorkers: 9 Scoreboard: R_R_.__RR_WW_W._._R_....RRR.....................................................................................................................................................................................................................................