PR(記事内にアフィリエイト広告が含まれています)
スポンサーリンク
Nucleus

NP_Amazonでの画像が見れなくなる障害の改善

AmazonからXMLを取得して商品をページに表示する際、以下の2点で困ってました。
・初期表示時に503エラーになると、手動でデータを消す必要がある
・いつの間にか画像が見つからない状態になる
503エラーになること自体は回避できなかったのですが、今までよりは比較的マシになったので、備忘として書いておきます。



503エラーの件ですが、Amazonサーバーは一秒間に決まった数しか処理できないので、全世界からアクセスされる都合上、避けられないという印象です。
2018/05/16追記
仕様を完全に勘違いしてたんですが、AmazonのAPIは1秒間に1リクエストという制限があるそうです。なお売り上げに応じて最大10リクエストまで増えるようですが、リクエスト数を増やすためには返却値のDetailPageURLをそのまま使わないといけないようです(旧来の短いURLでもアソシエイトの収益は入るものの、リクエスト数増加の判定には使われない模様)。この件についてのさらなる改修は、記事最後の方に追記しました。

PHP上で、503エラーの場合は再度XML取得するように改修したかったのですが、未だにPHP4環境なので、Try Catchが使えず断念しました。
まぁ無限ループになったら怖いし、AmazonのXML取得の規約上やっていいのか判断つかなかったですし(再取得の秒数間違えると、スロットリング制限にかかって面倒くさい事になりそうでした)。

初期表示時に503エラーになったら、XML取得できずに空のデータのままなんですが、そのままDBへINSERTされてしまうのが困りものでした。こうなると手動でDELETEしないと、ずっと商品が表示できなくなります。
503エラーを直接検知する方法が分からなかったので、XMLのタイトルが空だったらエラーだろうということで、下記のように回避しました。

function newData($product) {
$this->getAmazonData(&$product, $mode = "new");
//2018.05.11-takehana-add-s
if($product[title] == ""){
return;
}
//2018.05.11-takehana-add-e

こうすれば、初期表示時に503エラーになっても、画面をリロードすればそのうち商品が表示されるようになるので、手動で対応する必要は無くなりました。

一度商品を表示できていても、いつの間にか画像がありません(No-image)状態になってしまうのも困ってました。てっきりAmazonが画像URLを随時変えてるのかと勘違いしていたのですが、ソースみたらAmazonの仕業ではなく自分の勘違いと分かりました。
記事表示が変になるデータを調べてみたら、nucleus_plugin_amazonテーブルの「similar」という項目の中身が文字化けしているのか「??」という文字が頻出していて、見ただけでまともに動きそうにない雰囲気でした。
不正なデータ件数を調べたら数千件あったので、手動でやるのは諦めてSQLで物理削除しました。このあとで記事を再表示すれば、初期表示と同じ状態になってるので、特に問題なく商品が表示されるようになりました。
なんで文字化けデータが入るのか悩んだんですが、情報キャッシュ期間をすぎたあとは、Amazonの規約に従い、ソース上で再度XMLを取得して一部分をUPDATEする仕組みになっているので、この時に運悪く503エラーなどが発生したら、文字化けした内容をそのままUPDATEしてる可能性があると思い、下記のようにプラグインを改修しました。

function updateData($product) {
$this->getAmazonData(&$product, $mode = "update");
//2018.05.11-takehana-add-s
if($product[title] == ""){
return;
}
//2018.05.11-takehana-add-e

すでに怪しいデータは全件削除済なので、上記改修の妥当性はまだ未検証なんですが、3ヶ月以上たった記事をアトランダムに表示しても、今のところ問題が無さそうだったので、ひとまず上記改修のまま様子見してみます。
2018/05/16追記
AmazonのAPIの503エラーは数年前に仕様変更になっていて、通常は同じIDだと1秒に1リクエストしか許可しない(503エラーにする)ということのようです。どうも誰か極端にAPIアクセスする割には売上が少ないといった事が続き、それが原因で仕様改定になったようですね。
NP_Amazonの作り的に1回で1リクエストしかAPIアクセスしないので、大量に新規の商品があったら503エラーになってもおかしくないんですが、体感的にはそうでない時も503になるといった印象でした。一度新規表示したらキャッシュしているし、そんなにアクセス数が無いから503エラーが連続するのもおかしい気がします。
とはいえBotとか過去記事にアクセスして、APIへ再取得かけにいってるタイミングとかにあたると503エラーになってもおかしくない気がしました。あと自作ヴィジットを置いてるのでIDが同一だから、誰か悪さしたらアクセス過多になる可能性もあります。
とりあえず自作ヴィジットは不要なものは削除しました。あとはAPIアクセス前に最終アクセス日を確認して、1秒以内だったら1秒待ってから、APIへアクセスするように改修してみました。
そのために以下のような内容の「checkTime.php」を用意して、NucleusプラグインのAmazonフォルダ内に格納しました(文字コードはプラグイン類と合わせておきましょう)。

<?php
// 対象ファイル名
$filename = '/var/www/home/*****/nucleus/plugins/amazon/checkTime.php';
// 最終更新日の取得
$mod = filemtime($filename);
// 現在日時を取得
$timestamp = time();
// 最終更新日から現在時刻の差を算出
$interval = $timestamp - $mod;
if( $interval < '1' ) {
// 1秒経っていないなら待機
sleep(1);
}
// 最終更新日を更新
touch($filename);
?>

あとはNP_Amazonにて、下記のような改修を行いました。

function getAmazonData($product, $mode) {
//2018.05.16-takehana-add-s
require_once('amazon/checkTime.php');
//2018.05.16-takehana-add-e

これでNP_AmazonからAPIへXML取得する前に、checkTime.phpの最終更新日時を確認して、1秒以内だったら1秒待機してから、XMLを取得するようになりました。
一度に大量の新規商品を記載することがあまりないので、効果の程は何とも言えないところですが、これで少しは503エラーが減ったんじゃないかと思います。

コメント

タイトルとURLをコピーしました