前回までのあらすじ
少し前になりますが、下記のような記事を書きました。
上記方法の問題は、リクエストを発行したclientに最も近いPOPのhealth状態しか取得できないことでした。
では全拠点POPでのbackendのhealth状態をまとめて取得・監視する方法は無いのでしょうか?
Fastlyの /content/edge_check
APIを使う
Fastlyには色んなAPIがありますが、あまり知られていないAPIの1つに、/content/edge_check
があります。
これは、Fastlyの管理画面でも使える Check cache
と同じですが、APIの方が確認できる情報量が少し多いです。
このAPIが何をしてくれるかと言うと、通常は引数にURLを渡すことで全てのPOPに対してそのURLがキャッシュされているかどうかをチェックし、その結果をJSONで返してくれます。
例えば、APIの出力は下記のようになります。下記はサンプルなので1POP分だけの出力を切り取っていますが、POPの数だけこれが続きます。
[
{
"hash": "a6fa75cf5b77f61527421aaaa4ddcd50",
"pop": "fjr-ae",
"response_time": 0.399193,
"server": "cache-fjr7922",
"request": {
"headers": {
"User-Agent": "Fastly/cache-check",
"Fastly-Debug": 1,
"Host": "<name>.global.ssl.fastly.net"
},
"method": null,
"url": null
},
"response": {
"headers": {
"Server": "Varnish",
"Retry-After": "0",
"Content-Length": "191",
"Content-Type": "application/json",
"Accept-Ranges": "bytes",
"Date": "Wed, 21 Feb 2018 07:51:53 GMT",
"Via": "1.1 varnish",
"Connection": "close",
"Fastly-Debug-Path": "(D cache-fjr7922-FJR 1519199513)",
"Fastly-Debug-TTL": "(M cache-fjr7922-FJR - - -)",
"Fastly-Debug-Digest": "96be48cccb522690d0b6bb55e427bf366e7160213ef4c953ae240b66d1a5d100",
"X-Served-By": "cache-fjr7922-FJR",
"X-Cache": "MISS",
"X-Cache-Hits": "0"
},
"status": 200
}
},
#↑の配列がPOPの数だけこの後に続きます。
ポイントは、このAPIで確認できるのはそのURLにリクエストを投げた時のレスポンスヘッダ
とステータスコード
だけで、bodyの内容は確認できないということです。
つまり、前回作ったsynthetic
レスポンスによるJSONはこれでは確認できません。
synthetic
レスポンスを工夫する
ではどうするか、おそらく一番簡単なのは、JSONにも出力していたreq.backend.healthy
をレスポンスヘッダに含める方法です。そうすることで、このAPIのレスポンスヘッダにhealth
状態を出力させることができます。
前回の記事を前提にお話すると、vcl_error
のコードに1行だけ付け加えればOKです。vcl_recv
のコードは前回のままで問題ありません。
vcl_error
if (obj.status == 610) {
synthetic "{" LF
{" "timestamp": ""} now {"","} LF
{" "req.backend": ""} req.backend {"","} LF
{" "req.backend.healthy": "} req.backend.healthy LF
"}"
;
set obj.status = 200;
set obj.response = "OK";
# ヘッダにbodyへのJSON同様に `req.backend.healthy` を出力する
set obj.http.X-Backend-Healthy = req.backend.healthy;
set obj.http.Content-Type = "application/json";
return (deliver);
}
APIへリクエストを投げる
${hostname}
: Fastlyのサービスに登録しているドメイン
${backend_name}
: backend名
${your_fastly_token}
: API token
$ curl https://api.fastly.com/content/edge_check?url=${hostname}/api/status?backend=${backend_name} -H 'Fastly-Key: ${your_fastly_token}'
これを叩くとJSONがババーっと返ってくると思います。
[
{
"hash": "a6fa75cf5b77f61527421aaaa4ddcd50",
"pop": "fjr-ae",
"response_time": 0.399193,
"server": "cache-fjr7922",
"request": {
"headers": {
"User-Agent": "Fastly/cache-check",
"Fastly-Debug": 1,
"Host": "<name>.global.ssl.fastly.net"
},
"method": null,
"url": null
},
"response": {
"headers": {
"Server": "Varnish",
"Retry-After": "0",
"Content-Length": "191",
#↓これ↓
"X-Backend-Healthy": "1",
"Content-Type": "application/json",
"Accept-Ranges": "bytes",
"Date": "Wed, 21 Feb 2018 07:51:53 GMT",
"Via": "1.1 varnish",
"Connection": "close",
"Fastly-Debug-Path": "(D cache-fjr7922-FJR 1519199513)",
"Fastly-Debug-TTL": "(M cache-fjr7922-FJR - - -)",
"Fastly-Debug-Digest": "96be48cccb522690d0b6bb55e427bf366e7160213ef4c953ae240b66d1a5d100",
"X-Served-By": "cache-fjr7922-FJR",
"X-Cache": "MISS",
"X-Cache-Hits": "0"
},
"status": 200
}
},
#↑の配列がPOPの数だけこの後に続きます。
出力は上記のようになるはずです。
"X-Backend-Healthy": "1",
という部分が今回追加したレスポンスヘッダです。0=unhealthy, 1=healthy です。
これを頑張ってパースしてPOPごとのヘッダに切り分ければ、各POPでのbackendのhealth状態をこのAPIによって取得することができます。