2012/11/11 のポッキーの日に「AWSで動かすWordPressとその高速化」セミナーに伺いまして、Amazon Web Service を堪能して参りました。 🙂
AWSで動かすWordPressとその高速化
アマゾン ウェブ サービス(AWS) にはウェブデザイナーにとっても魅力的なサービスがたくさんあります!
今回はAmazon Web Servicesのテクニカルエバンジェリストである堀内さんをお招きし、すぐにでも使えるサービスを実際に体験しながら(ハンズオンで学びならが)その魅力たっぷりのサービスについてを学びます。また、AWS上でWordPressを使えるようにし、さらに高速化する方法について、 株式会社デジタルキューブ の小賀さんをお招きし、実際に体験しながらその方法についてを学びます!
tenpura さんや小賀さんにも久しぶりにお会いできまして楽しいひとときでした。
仕事柄、仮想化基盤には慣れてはいるものの、超高速チューンされた WordPress である「AMI 網元」がほとんどワンクリックでデプロイされる様子や、ストレージのスナップショットバックアップはやはり魅力的なフューチャーでした。
WordPress AMI – 超高速 WordPress AMI 網元
EC2のMicro Instance(無償枠あり)を利用すれば、圧倒的にハイパフォーマンスなWordPress環境をコンパネ操作のみで誰でも簡単に構築できます。WordPressの高速化対策、スマートフォン対策に効果的です。
現在のクラウドと呼ばれるサービスの根幹をなしているのは間違いなく仮想化技術です。 そして WordPress を実用的にクラウドにのせる試みはすごく面白いものでした。:)
AMI 綱元も使える Amazon EC2 のマイクロインスタンス(アカウント登録から1年無料とのこと)。
EC2 は root がもらえる IaaS。
[tegaki]むふふ..(←脱線したようだ[/tegaki]
というわけで、Groovy と QuartzScheduler と commons-daemon を使って怪しい(?)デーモンを動かしてみることにしました。 😛
デーモンは処理(スレッド)の途中終了をつくるのが結構大変だったりしますが、QuartzScheduler にそのへんを任せると定期実行する常駐ものが簡単につくれます。
以下の例は 20秒おきにログをはくデーモンです。実際には CronScheduleBuilder.cronSchedule で時間を決め、QuartzJob::execute() に好きな処理を実装します。
QuartzDaemon.groovy
package net.maple4ever.daemon import org.apache.commons.daemon.* import org.quartz.* import org.quartz.impl.* import org.apache.log4j.Logger class QuartzDaemon implements Daemon { def static logger = Logger.getLogger(QuartzDaemon.class) def static daemon = new QuartzDaemon() def static sched = (new StdSchedulerFactory()).getScheduler(); @Override public void init(DaemonContext arg0) throws DaemonInitException, Exception { // every 20 seconds def job = JobBuilder.newJob(QuartzJob.class) .withIdentity("job1", "group1") .build(); def trigger = TriggerBuilder.newTrigger() .withIdentity("trigger1", "group1") .withSchedule( CronScheduleBuilder.cronSchedule("0/20 * * * * ?")) .build(); sched.scheduleJob(job, trigger); } @Override public void start() throws Exception { logger.info("START QuartzDaemon") sched.start() } @Override public void stop() throws Exception { logger.info("STOP QuartzDaemon") sched.shutdown(true) } @Override public void destroy() { logger.info("DESTROY QuartzDaemon") } static main(args) { daemon.init(null) daemon.start() System.in.withReader { print 'Hit any key to exit.' println it.readLine() } daemon.stop() } } class QuartzJob implements Job { def static logger = Logger.getLogger(QuartzJob.class) def QuartzJob() { } @Override public void execute(JobExecutionContext context) throws JobExecutionException { // execute job JobKey jobKey = context.getJobDetail().getKey() logger.info("QuartzJob says: " + jobKey + " executing at " + new Date()) } }
commons-daemon のインターフェースに従ってクラスを定義して、init で QuartzScheduler のジョブ定義。 commons-daemon からのの start、stop をそのままQuartzSchedulerにパスしてあげればOKです。
また、この例のように static main メソッドをつくっておくとデバッグ時にデーモンではなくそのまま実行できるので便利です。
できたら groovyc でコンパイルしたクラスファイルを、commons-daemon の jsvc を次のようなシェルから起動してあげます。
setenv.sh
#!/bin/sh SCRIPT_HOME=/opt/daemon JSVC_USER=hiromasa JAVA_HOME=/usr/lib/jvm/java GROOVY_LIB=/opt/groovy-2.0.5/embeddable/* LIB_HOME=$SCRIPT_HOME/lib LIB_PATH=$GROOVY_LIB:$LIB_HOME/commons-daemon/*:$LIB_HOME/log4j/*:$LIB_HOME/quartz/* LIB_PATH=$LIB_PATH:$SCRIPT_HOME/script LIB_PATH=$LIB_PATH:$LIB_HOME/twitter4j/*:$LIB_HOME/javamail/* #for command line(ex. $GG Foo.groovy) export GG="java -cp $LIB_PATH groovy.ui.GroovyMain"
# twitter4j とか javamail とかは必要ありません。(ぼくの別デーモンで使われています 🙂
export している $GG はスクリプト作成時の実行用で、シェルから . ./setenv.sh などとして環境をもってきた後に、$GG QuartzDaemon.groovy とするとコンパイルせずに static main から実行できるようなっています。(UNIX 上の vi などで直接 .groovy をかくときに便利です)
ディレクトリ構成と lib は以下のような感じです。
[hiromasa@]$ ls -laF 合計 28 drwxr-xr-x 7 hiromasa hiromasa 4096 11月 18 08:57 2012 ./ drwxr-xr-x 5 root root 4096 11月 18 09:38 2012 ../ drwxrwxr-x 2 hiromasa hiromasa 4096 11月 18 09:45 2012 bin/ drwxrwxr-x 7 hiromasa hiromasa 4096 11月 18 01:53 2012 lib/ drwxrwxr-x 2 hiromasa hiromasa 4096 11月 18 09:48 2012 log/ drwxrwxr-x 4 hiromasa hiromasa 4096 11月 18 10:56 2012 script/ drwxrwxr-x 2 hiromasa hiromasa 4096 11月 18 09:48 2012 tmp/ [hiromasa@]$ ls -laF lib/* lib/commons-daemon: 合計 32 drwxrwxr-x 2 hiromasa hiromasa 4096 11月 17 11:43 2012 ./ drwxrwxr-x 7 hiromasa hiromasa 4096 11月 18 01:53 2012 ../ -rw-rw-r-- 1 hiromasa hiromasa 24242 2月 23 23:22 2012 commons-daemon-1.0.10.jar lib/log4j: 合計 488 drwxrwxr-x 2 hiromasa hiromasa 4096 11月 17 12:01 2012 ./ drwxrwxr-x 7 hiromasa hiromasa 4096 11月 18 01:53 2012 ../ -rw-rw-r-- 1 hiromasa hiromasa 489883 5月 6 11:01 2012 log4j-1.2.17.jar lib/quartz: 合計 1212 drwxrwxr-x 2 hiromasa hiromasa 4096 11月 18 07:15 2012 ./ drwxrwxr-x 7 hiromasa hiromasa 4096 11月 18 01:53 2012 ../ -rw-r--r-- 1 hiromasa hiromasa 608376 5月 20 11:12 2011 c3p0-0.9.1.1.jar -rw-rw-r-- 1 hiromasa hiromasa 578548 8月 6 13:28 2012 quartz-all-2.1.6.jar -rw-r--r-- 1 hiromasa hiromasa 25496 5月 19 20:22 2011 slf4j-api-1.6.1.jar -rw-r--r-- 1 hiromasa hiromasa 9753 5月 19 21:02 2011 slf4j-log4j12-1.6.1.jar
quartz.sh
#/bin/sh # setup . /opt/daemon/bin/setenv.sh RUN=net.maple4ever.daemon.QuartzDaemon # check args if [ $# -ne 1 ] then echo "usage: quartz.sh [start|stop]" exit 1 fi ret=9 case $1 in start ) echo "starting daemon..." $SCRIPT_HOME/bin/jsvc \ -pidfile $SCRIPT_HOME/tmp/$RUN.pid \ -user $JSVC_USER \ -home $JAVA_HOME \ -cp $LIB_PATH \ $RUN ret=$? ;; stop ) echo "stoping daemon..." $SCRIPT_HOME/bin/jsvc \ -stop \ -pidfile $SCRIPT_HOME/tmp/$RUN.pid \ $RUN ret=$? ;; esac exit $ret
手抜きシェルですが、./quartz.sh start|stop でデーモンの常駐制御ができます。
hiromasa 24923 1 0 09:48 ? 00:00:00 jsvc.exec -pidfile /opt/daemon/tmp/net.maple4ever.daemon.QuartzDaemon.pid -user hiromasa -home /usr/lib/jvm/java -cp /opt/groovy-2.0.5/embeddable/*:/opt/daemon/lib/commons-daemon/*:/opt/daemon/lib/log4j/*:/opt/daemon/lib/quartz/*:/opt/daemon/script:/opt/daemon/lib/twitter4j/*:/opt/daemon/lib/javamail/* net.maple4ever.daemon.QuartzDaemon hiromasa 24924 24923 0 09:48 ? 00:00:06 jsvc.exec -pidfile /opt/daemon/tmp/net.maple4ever.daemon.QuartzDaemon.pid -user hiromasa -home /usr/lib/jvm/java -cp /opt/groovy-2.0.5/embeddable/*:/opt/daemon/lib/commons-daemon/*:/opt/daemon/lib/log4j/*:/opt/daemon/lib/quartz/*:/opt/daemon/script:/opt/daemon/lib/twitter4j/*:/opt/daemon/lib/javamail/* net.maple4ever.daemon.QuartzDaemon
このように jsvc プロセスが 2つできれば成功です。 🙂
commons-daemon と QuartzScheduler を使えば、cron などを使うのと違って簡単に無理なく状態遷移を制御できますので良いのではないかと思います。
さぁ、Amazon EC2 のマイクロインスタンスでどんなデーモン動かしましょう。 いろいろアイディアがでてきますが、ネットワークの中で生き続けるプログラムってやっぱり面白いですね。 😀