ステージングと本番系に分けた構成のWordpressサイトの同期手段としてwordmoveを使用していますが、しばらく運用していたところ、Webアクセスとは無関係にサーバ負荷が異常上昇する現象が発生しました。wordmoveの設定についてはこちらを参照。
accsess_logやtopコマンドで確認したところ、同期を実行してから間もなくしてサーバ自身からのHEADメソッドによるローカルリクエスト起きていることが判明し、その数なんと23万件以上ありました。ロードアベレージも20を超えサーバがパンクする事態となりまして、原因が分かるまでは対処療法として負荷を監視してhttpdを自動的に再起動するなどの応急処置でしのいでいました。
現象がpingバック機能に似ていたことからWP Total Hacksを始めいくつかのプラグインを試して禁止するように設定しましたが効果はありませんでした。
お手上げです。。
そこで、一時的にすべてのクエリーログを吐き出すように設定して調査したところ、負荷上昇時に気になるSQLが発行されていることが分かりました。それが以下のSQLです。
accsess_logやtopコマンドで確認したところ、同期を実行してから間もなくしてサーバ自身からのHEADメソッドによるローカルリクエスト起きていることが判明し、その数なんと23万件以上ありました。ロードアベレージも20を超えサーバがパンクする事態となりまして、原因が分かるまでは対処療法として負荷を監視してhttpdを自動的に再起動するなどの応急処置でしのいでいました。
現象がpingバック機能に似ていたことからWP Total Hacksを始めいくつかのプラグインを試して禁止するように設定しましたが効果はありませんでした。
お手上げです。。
そこで、一時的にすべてのクエリーログを吐き出すように設定して調査したところ、負荷上昇時に気になるSQLが発行されていることが分かりました。それが以下のSQLです。
SELECT ID, post_content, meta_id FROM wp_posts, wp_postmeta WHERE wp_posts.ID = wp_postmeta.post_id AND wp_postmeta.meta_key = '_pingme' LIMIT 1詳しくは分析していませんが、pingバックを禁止しているにも関わらずページ内のリンクをすべてパースして何か処理を行っているようです。そしてついにこの処理を行っていると思われるコードを発見しました。それがdo_all_pings()という関数です。この関数はwp-cron.phpという疑似バッチのトリガーから呼び出されるwp-include/default-filters.phpにてadd_actionでフックされています。同期の実行からしばらく経過してから異常が発生する現象ともつじつまが合います。
SELECT * FROM wp_postmeta WHERE meta_id = 22663
DELETE FROM `wp_postmeta` WHERE `meta_id` = 22663
SELECT pinged FROM wp_posts WHERE ID = 874
SELECT wp_posts.* FROM wp_posts WHERE 1=1 AND wp_posts.post_name = 'gaobijo-title_fuku-png' AND wp_posts.post_type = 'post' ORDER BY wp_posts.post_date DESC
SELECT wp_posts.* FROM wp_posts WHERE 1=1 AND wp_posts.post_name = 'gaobijo-title_fuku-png' AND wp_posts.post_type = 'post' ORDER BY wp_posts.post_date DESC
SELECT wp_posts.* FROM wp_posts WHERE 1=1 AND wp_posts.post_name = 'kumaayaka04-png' AND wp_posts.post_type = 'post' ORDER BY wp_posts.post_date DESC
add_action( 'do_pings', 'do_all_pings', 10, 1 );
この部分をコメントアウトすることでやっと不可解な自ホストに対してのHEAD呼出し現象が止まりました。なおdefault-filters.phpはパッケージのアップデートなどにより更新されてしまうので、add_actionを無効化するスクリプトをプラグイン化して設置する方が良いそうです。以下サンプルphpです。
<?php
/*
Plugin Name: No Do Pings
Plugin URI:
Description: Remove Actions and Filters
Author: Makoto Fujimoto
Version: 1.00
Author URI:
*/
remove_action( 'do_pings', 'do_all_pings' );
?>
この様なPHPプログラムをwp-content/plugins/以下に設置して管理画面で有効化してください。
コメント