XREA & CORESERVER の cron と WordPress の wp-cron

UNIX 系の OS には cron と呼ばれる、コマンドのスケジュール実行機能が備わっています。 基本的には UNIX のコマンドを指定された時期に呼ぶだけの機能なので、実行可否によって次の実行分岐をしたりするジョブスケジューラ的なことをするには不向きですが、簡単な定期実行くらいなら便利に使うことができます。

最近のレンタル Web サーバでは、この機能をユーザに提供しているところも多く、特にスクリプト系の Web アプリケーションのような、ユーザのアクセス契機でしか動作しないプログラムを補完する役割で cron が使われているようです。(RSS リーダの RSS 定期取得とか)

また、我らが WordPress には、この UNIX の cron とは別に、コアに wp-cron と呼ばれる(?)一連のファイルで、cron の擬似的な実装が含まれています。 ではとりあえず、WordPress の wp-cron のことから書いてみます。

WP-Cronは動いてるのか? « MMRT daily life

TB多重送信防止のため、Google XML Sitemapsをバックグラウンドで動かす設定にしたわけだが、今日確認すると投稿前日に生成されたままだ。よくわからないのだが、投稿ボタンをクリックしてから一体何秒後、何分後、何時間後に作動するのか? はたまた作動しているが失敗しているのか? 疑問は尽きない。

まずは、wp-cron の基本的な動作原理から。

一般的なスクリプト系の Web アプリケーションというのは、動作の契機がユーザによるブラウザアクセスにより始まります。 その動作は継続することはなく、ユーザのアクセス終了(画面描画)となれば、そのアプリケーションはメモリから消滅します。

てなわけで、プログラム動作が持続しないため、定刻動作などはできないわけなのですが、これをなんとか擬似的に再現したのが wp-cron です。

  • スケジュールしたい仕事があったら、とりあえず、いつ起動するのかとかなにを動かすのかとかを WordPress DB に登録。
  • ユーザからの WordPress へのアクセスがあったら、必ず上記 DB を参照して、いまやるべきことがないかを確認して、あるならサイト表示とついでにバックグラウンドで実行。

という動きです。

・・・お気づきかと思いますが、きっかけはユーザからのアクセス、ブラウザによる閲覧ですので、もし仮にそのサイトがその後1アクセスもなければ、いっくらスケジュールしておいてもなにも実行されません。 🙂

wp-cron は、遅延したスケジュールがあれば一気にそれを実行しようし、「遅刻はするけどいつかは実行してやっか」「まぁ1秒間に1回のアクセスはなくても、10分に一回くらいのアクセスならどこのサイトでもあるだろ」くらいの思想で実装されています。

ちなみに、wp-cron の時間の指定の仕方はいくつかありますが、Masayan さんが使われている Google XML Sitemap とか、ぼくのつくった wp-lwSitemap とか、コア標準のトラックバックの送信機能であるとかは、"次の誰かのアクセス" というスケジュールの仕方をしています。

また、cron の特徴とは違いますが wp-cron によるアクションの"実行"は、ちょっと特殊な方法がとられていて、ユーザの閲覧のプロセスとは別のバックグラウンドで動くようにつくられています。 要は閲覧する人の実行動作が重くなったりはしないようになっています。

これは閲覧プロセス(PHP)から、 cron ジョブ実行プロセスを司るファイルにたいして、"socket を一瞬つないで"、あたかも PHP をブラウザと同様にアクセスしてきた別ユーザのように偽装して動作しています。 PHP くんがいくら待たされても、だれもいらいらしないってことですね。(レンタルサーバ管理者はいらいらする?(笑)

また、このようにすると閲覧プロセスと cron ジョブが平行して動作をするため、閲覧 + cron ジョブと続けて実行するよりも、メモリ等のリソースを各プロセスがサーバから多く取ることができるという特徴もあります。(なので多くのエントリを持つサイトで Google XML Sitemap をバックグラウンド設定するとうまく動作するときがある。 これは昔の Google sitemaps のひろまさハックの動作と同様)

このように wp-cron は若干 hackish。 本家 UNIX cron が使えるのならば、時と場合によってそちらを使ったほうがいい場合もあります。

じゃーってことで、XREA & CORESERVER における 本家 cron の設定の仕方を紹介してみます。 他のレンサバでも同じような物だと思います。

WP-Cronは動いてるのか? « MMRT daily life

しかし、XreaはCRONが使えるじゃろ?と言われるだろうが、CRONジョブの設定ってどうするのさ? 相対パスで入力するところに例のURLをそのまま入れても使えないんじゃね?と思ったから。知ってる人がいたら教えて欲しいなぁ。

普通の UNIX のコマンドの cron の定期実行ってのはわりといろんなところに書かれているので、ここでは Masayan さんのやりたいような PHP などの Web アプリの定期実行の方法を書いてみます。

まず cron が実行できるのは、UNIX でいうところの実行ファイルです。 Windows でいえば、 .exe ファイルですが、UNIX 的には実行権限のついたファイル。 FTP でおなじみの、 700 とか 707 とか 7 が付いたファイル。(というと語弊があるかもしれないが、そんな感じです)

じゃー、実行したいのが .php のファイルなのでそれに 707 つけて指定してあげればいいかというと、これは残念ながらダメです。 .php のファイルを解釈できるのは、PHP のインタープリタだけだからです。 cron に指定するのは、UNIX が解釈できる実行ファイルでないとだめであります。

PHP のインタープリタって何?って話ですが、これは簡単で、php ってコマンド。

php -f hogehoge.php

ってうつと、hogehoge.php が実行されます。 cron の場合は、フルパスで指定しなければならないので、 /usr/bin/php とかになるんかな。 で、その後ろの hogehoge.php もフルパスにすればいけるはず。。

[tegaki]めんどくせ![/tegaki]

おまけにこれは動作確認しずらいので、ここでは別な方法を書いてみます。

UNIX の実行できる(cron に登録できる)ファイルにシェルというのがあります。 これをまずサーバ上におきます。 ワンクッションおきこのシェルに動作手順を書いて、cron に実行してもらいましょう。

これは、ユーザに閲覧される必要がないファイルなので、public_html より上のディレクトリにおきましょう。 たとえば、cron ってディレクトリをつくる。

Image2

で、その中に以下のようなファイルをつくります。 ファイル名は何でもよく、拡張子は一般的には .sh。 必ずアスキーモードで FTP 転送し、権限を 700 に指定。

fetch.sh (実際のファイルに行番号はいりません)

   1: #!/bin/sh
   2:  
   3: cd /virtual/[ユーザ名]/cron/
   4: wget http://[実行したい.phpのURL] -O result

[ユーザ名]と[URL]は適宜変更のことです。

wget というのは、コマンドラインの http クライアントです。 .php はブラウザでアクセスされると動くので、UNIX のコマンドラインブラウザ(?)で定期閲覧してあげるわけです。(上で書いた php -f でもいけるかと思いますが、UNIX パスより wget の http 表記のほうが分かりやすいかと思いこうしています)

でもって、レンタルサーバの cron 設定画面で、この .sh をフルパスで指定。

Image5

cron/fetch.sh

時間はお好みで設定してください。 上の例は毎時 0 分に実行。これで、 http://[実行したい.php のURL] のスクリプトが定期実行されます。

また、実行結果がメール通知され、 cron/ ディレクトリには毎回 result とかってファイルができるはずです。(この辺は各自調整してください)

これで cron の設定ができるようになりました。 cron が使えるようになると、 MySQL の定期バックアップとかもできるようになるので、興味があればやってみてください。 🙂

うわ、なげー。。 以上、wp-cron と cron の説明でした。(オチはない

WordPress プラグイン bsuite でカウントがされない場合

なんだか、いじってない WordPress ナンバーワンサイトみたいだった ここ hiromasa.another ですが、さすがにちょっといじることに。 なにを隠そう、先日までスパム対策もノーガード戦法にしていたので、とあるエントリには 100くらいのスパムが付いていたり・・・。 🙂

まぁまぁ、なんでもスモールスタートが好みなんです。

でサイドバーに本日人気の記事、 todays popular をだしたかったので、bsuite を入れてみることにしました。

» bSuite

bSuite includes a set of tools (some in seperate plugins) that improve WordPress’ tag management and CMS capabilities, make it easier to build dynamic pages, and leverage WP as an application platform. Plugins that can be activated seperately include one for stats tracking (bSuite bStat), a tag importer, and an example plugin that illustrates how to leverage one of the features bSuite adds to WordPress.

日本語系の情報は、Masayan さんのところが詳しいです。

bsuite « MMRT daily life

bsuite タグのアーカイブ

はたして、せっかくなので最新版などいれてみるも、?。 なんか変わった。。 いろいろな機能をまとめて bsuite になっているようですね。 とりあえず、bsuite と bstat を有効化。 これで、todays popular はできるはず・・・。

ローカルでちょいちょいためして、、あれ、管理画面がなくなった? などと思いつつ。

<?php bstat_todaypop(6, '<li>', '</li>'); ?>

と todays popular なタグをテーマに挿入。 あれ、自分のクリックもカウントされちゃうな、、ってことでいんちきハックを追加。 昔は設定があったような・・・。 考えるより産むが易し。

bstat.php: 74 行目くらい

function hitit(&$content){
 
    // nonce this
    if($this->ktnxbye)
        return($content);
    // ログインしてたらカウントしない
    if(!empty($_COOKIE[USER_COOKIE]))
        return($content);

ローカルで動作確認して、 .another で動かしてみる。

[tegaki]表示されね~[/tegaki]

DB をみると、カウント自体はされていて、 bsuite のテンプレートタグがうまく条件を拾ってきてくれないために、null が返る様子。。 ローカルで動いていたのに、なぜ。

ってことで、疑うわ MySQL のバージョン。

ローカル: サーバのバージョン: 5.0.37

コアサバ: サーバのバージョン: 5.1.20-beta

なぜ bate!! ってのはおいておくとして、マイナーバージョンが 1 違うようなので、おそらくこの辺が原因。

プログラムを追っていくと、悪の根源っぽいものを発見。 SQL をくずして抜粋。

SELECT
    post_id, SUM(hit_count) AS hit_count
FROM
    $this->hits_table
WHERE
    1=1 AND
    post_id <> 0 AND
    hit_date = NOW()
GROUP BY
    post_id
ORDER BY
    hit_count DESC;

NOW()、今!。

hit_date = NOW()

今といえば、今一瞬しかないのでは。。 テーブルの日付桁みて動くのだろうか。。 たしかに、カラム自体は yyyymmdd までしかないようだ。 NOW() ってやったらミリ秒くらいまではいくような。

まー MySQL が詳しくないぼくはふかく追求せず、

 248: $args = wp_parse_args( $args, $defaults );
 249:  
 250: $nownow = date("Y-m-d", mktime(0, 0, 0, date("m")  , date("d") , date("Y")));
 251: $date = "AND hit_date = '$nownow'";

$nownow とかいいかげんなのは気にしない。 今日の日付を yyyy-mm-dd 形式で検索条件にすることで、期待する動作になりました。

めでたしめでたし。 🙂

追記。 テンプレートタグの limit 引数が効かない。 以下の修正でよいと思われる。

 288: $limit = 'LIMIT '. (0 + $args['limit']);

以上、bSuite bStat 3.02 で確認でした。

Web で楽しく遊ぶための知識(3) – TCP/IPネットワークアプリケーションとブラウザ

てなわけで、3回目です。

前回は、

hiromasa.another :o) » Blog Archive » Web で楽しく遊ぶための知識(2) – IPアドレスとDNSとバーチャルホストと

ここのサーバの URL は、 https://another.maple4ever.net/。 これをブラウザの URL 欄にうちこむと、日本のどこかにあるデータセンターに接続されて、html が表示されます。

という話でした。

インターネット上の通信は、TCP/IP というプロトコルを使い、インターネット上ユニークなIPアドレスを元に、世界中に配置されているホストに接続する。 Web に関して言えば、接続先の Web サーバには httpd と呼ばれるサーバソフトウェアが動作して、ブラウザからの要求に応える。 httpd にはバーチャルホストという考え方があり、1つの IP アドレス(機械)で複数のホスト名をホスティングできる。

てなわけでしたが、今回は TCP/IP についてもうちょっとだけ。

自分で書いていてあれなのですが言葉に混乱が見られるので、まずひとつ。 インターネット上に存在するコンピュータ(PC、サーバ等々)を以下、"ホスト" と呼称することにします。 サーバとかクライアントとかって名称は、このホストに対する使い方、という扱いになります。 ホスト名といえば、 another.maple4ever.net 、とかです。

さて、ここからホスト同士の通信を、たとえばゼロから自分で実装しようと考えてみます。

まぁ手元にあるパソコン2台をなんとかつなげたいとして・・・。 最初は、AパソコンでボタンをおしたらBパソコンの画面になにかでるとか・・・。

当たり前ですが、信号のやりとりをするためになにか通信線が必要になります。 最近のパソコンには付いてないですが、こーいうのはプリンタポートを借りて実装するのが楽だったりするんですが、プリンタポート同士でパソコンを接続。 でもって、ソフトを書いて、プリンタポートの入出力を監視して、なんか信号きたら、画面に映すとか、ボタンが押されたら信号を出力するとか・・・。 2台ならいいけど3台にしたらどうしよう。。

[tegaki]やってらんね~(笑)[/tegaki]

投げ出すこと請け合い。 というわけで、こういった接続方式を決めてくれている規格の一つが TCP/IP で、多くのコンピュータが標準で採用しそれを実装しています。

ネットワークの規格というのは、いくつかの層で構成されていることが多く、TCP/IP も4層のレイアから成り立っています。

インターネット・プロトコル・スイート – Wikipedia

IP群はプロトコルとサービスをカプセル化する事によって抽象化する。 通常、より上位層のプロトコルはその目的の達成に役立てるために、より下位層のプロトコルを用いる。 これまでIETFはインターネット・プロトコル・スタックをRFC 1122で定義された4層から変更した事はない。 IETFは7層からなるOSI参照モデルに従うような試みはせず、また標準化過程(Standards Track)にあるプロトコル仕様やその他の構造上の文書をOSI参照モデルに対して参照する事もしない。

Wikipedia のリンク先に4層の解説があるのですが、 "Web で楽しく遊ぶ" 的には、注目点は最上位「アプリケーション層」

4. アプリケーション

DNS, TFTP, TLS/SSL, FTP, Gopher, HTTP, IMAP, IRC, NNTP, POP3, SIP, SMTP, SNMP, SSH, TELNET, ECHO, RTP, PNRP, rlogin, ENRP

みたことのある名前が並んでいます。 くだけて言えば、4 層未満の階層はホスト同士の"接続"するまでの手順の既定です。 接続した後に何をするのかってのがアプリケーション層になります。

インターネットで動くアプリケーションをつくる人間は、アプリケーション層未満のことはそのインターフェース以外考えなくて済むようになっています。 接続経路に海底ケーブルつかっていようが、無線LAN があろうが、ネットワーク経路がどうなっていようが、アプリケーションは意識しません。 ただひたすら、"つなげ" と命令すれば、自分でなにもせずとも 3層以下がなんとかして接続してくれます。 プリンタポートで通信しようとしている世界から見れば雲泥の差です。 🙂

じゃー、ここでいうインターネットで動くアプリケーションってなんだっていえば、Firefox などの Web ブラウザ。 Thunderbird などのメールクライアントがそれにあたります。 メッセンジャーとかもそうですね。

TCP/IP 的に言えば、Firefox はアプリケーション層 HTTP 、SSL、FTP、Gopher、SOCKS に対応した通信アプリケーション、ということになります。

これらアプリケーション層アプリケーション(?) は、みんなが使えるようにしたほうが便利なものについては、その仕様が RFC という文書で規定されています。

Request for Comments – Wikipedia

Request for Comments(略称:RFC)はIETF(Internet Engineering Task Force)による技術仕様の保存、公開形式である。内容には特に制限はないが、プロトコルファイルフォーマットが主に扱われる。RFCは日本語では「コメント募集」の意味であり、もともとは技術仕様を公開し、それについての意見を広く募集してより良いものにしていく観点から始められたようである。全てのRFCはインターネット上で公開されており、誰でも閲覧することができる。

もちろん、自分でアプリケーションを設計して動作させることもできます。 たとえば、ネットワークゲームであるとか、メッセンジャーサービスであるとかは、いろいろな会社が独自のアプリケーション層に設計したプロトコルです。

このアプリケーション層ですが実はつくりは非常に簡単で、基本的には文字列のやりとりだけの取り決めのものが多いです。 じゃー我らが Web。 HTTP というプロトコルはどんな風に実装されているかというと・・・

(サーバへリクエスト送信)
GET / HTTP/1.0
Connection: close
Host: wp.mmrt-jp.net
Referer: http://wp.mmrt-jp.net/
Accept: */*

(サーバからのレスポンス)
HTTP/1.1 200 OK
Date: Tue, 15 Jan 2008 08:20:50 GMT
Server: Apache
X-Pingback: http://wp.mmrt-jp.net/xmlrpc.php
Connection: close
Content-Type: text/html; charset=UTF-8

こういった文字列のやりとりをホスト間でしているだけです。 Firefox はこの会話ができるアプリケーションのひとつです。

HTTP/1.1 200 OK

200 OK。 200 とか、403 とか 500 とか・・・。 よくみる例のアレですね。

てなわけで HTTP 編に、続く。

# ネットワーク系はぼく詳しくないので、早々にすっとばすのであった。。