Fastly で 503 が出た場合の原因と対処

Fastly CDN の初期設定は [5分間でCDNを試してみる](http://qiita.com/ToshiAizawa/items/6a0d22f4f26eb0b1981f) の通り非常に簡単に行うことができます。ただ、設定を行っていざ使おうとアクセスすると下記のがような画面に遭遇し、出鼻をくじかれることがあります。このように 503 が発生する原因の多くは設定もしくはオリジンサーバによるものです。ここでは代表的な原因と対処について説明したいと思います。

![Screen_Shot_0028-11-29_at_20_53_07_mask.png](https://qiita-image-store.s3.amazonaws.com/0/149542/f0b19019-ece3-b164-2e1f-675c4b28e4ac.png)

503 の発生状況は Fastly Control Panel の STATS より確認することが可能です。

![STATS_503.png](https://qiita-image-store.s3.amazonaws.com/0/149542/13d9b0f5-ed6b-686c-e109-62275dff008a.png)

#Connection Timeout
##原因
文字通り、オリジンサーバへの接続のタイムアウトです。Fastly のエッジサーバとオリジンサーバの接続が設定値以内に行えなかった場合に発生します。デフォルトで Timeout は1秒に設定されています。通常、1秒は接続に十分な時間ですが、オリジンまでの回線やネットワーク機器の問題でそれ以上に時間を要することがあります。
##対策
まずはオリジンのネットワーク周りで問題がないかを調査してみてください。traceroute や mtr などで遅延をみることができます。その上で、1秒以上かかることが想定される場合には、タイムアウトを伸ばし、STATS のエラーの状況に変化があるかを調査してください。
タイムアウトの変更は CONFIGURE - ORIGINS を選択し、 Hosts より該当オリジンの![Screen Shot 0028-12-05 at 17.51.56.png](https://qiita-image-store.s3.amazonaws.com/0/149542/55531521-3d37-fcc1-f5c6-4c268d57abe0.png)を選択します。
設定の下の方に ADVANCED OPTIONS という項目があるので、その中の Connection timeout の値を変更し UPDATE します。

![ConnectionTO.png](https://qiita-image-store.s3.amazonaws.com/0/149542/3472ce8d-4e2e-090d-bcd3-986e7f386b1c.png)

また、オリジンへの接続は全世界の POP から来る可能性があります。オリジンが日本にあり、ブラジルのユーザがアクセスした場合には、Fastly のブラジルエッジから日本の接続を考慮する必要があります。こういったケースへの対策として、Shielding という機能を利用する方法があります。ここでは詳細を省きますが、エッジサーバの親サーバが定義されるようなイメージです。つまり、Shielding を日本に設定することにより、すべてのオリジンへのリクエストはオリジンに近い日本の Shielding キャッシュサーバを経由することになり、タイムアウトが発生するケースを減らすことになります。

#First Byte Timeout
##原因
オリジンサーバへの接続が完了したものの、一定時間データの受信がない場合に発生します。オリジン側でリクエストを受けたのちに多くの処理を行う必要があり、データの返信を始めるのに時間を要する場合に発生します。
##対策
オリジンでの処理時間が妥当であるかを確認してください。確認するにはオリジンに直接接続します。ブラウザもしくは curl コマンドでの接続が可能ですが、ヘッダを操作したりできる点で curl コマンドがおすすめです。例えば、下記のようなコマンドを実行すると、データが送信されるまでの時間を取得することもできます。この場合だと、データの受信が1秒程度で始まっているということになります。この値などが想定以上に大きいようだと、それが正常なのかをオリジン側で調べる必要があります。

```
$ curl -svo /dev/null -w "%{time_namelookup}\n %{time_connect}\n %{time_starttransfer}\n %{time_total}\n" <オリジンのURL>
...
> User-Agent: curl/7.43.0
...
< HTTP/1.1 200 OK
...
 0.520
 0.523
 1.001
 1.301
```
正常な範囲のレスポンスでもタイムアルトになる場合には、Connetion Timeout のときと同様にタイムアウトの値を伸ばします。設定場所はConnection timeout のすぐ下にあります。

#Backend Is Unhealthy
##原因
ヘルスチェックを設定している場合にヘルスチェックが失敗し、オリジンサーバに接続できない状態のときに発生します。
##対策
設定しているヘルスチェックの応答を確認してください。
<img width="670" alt="healthcheck_detail.png" src="https://qiita-image-store.s3.amazonaws.com/0/149542/2a48daed-7afc-a1b5-7f72-7559a066756c.png">
と設定されている場合、HEAD リクエストを該当オリジンのパス healthcheck.txt にホストヘッダ www.example.com で送った場合にレスポンスが 200 であることが期待されています。curl コマンドでは

```
$ curl -I http(s)://<オリジンのドメイン>/healthcheck.txt -H"Host:www.example.com"
```
が 200 で返って来れば OK です。ただ、`Backend Is Unhealthy` になっている場合には 200 にならないはずです。オリジン側で何らかの問題があるため、調査、対策を行って正常に応答するようにしてください。
また、 Fastly の設定でオリジンサーバの Failover を設定することも可能です。これにより、1台のオリジンが正常に応答できなくても、バックアップ用のオリジンサーバに接続しサービスを継続することができます。この設定に関しては別の記事で説明したいと思います。

#hostname doesn't match against certificate
##原因
Fastly と オリジンサーバの間が TLS/SSL で設定されていて、その接続に問題が発生しています。Fastly とオリジンサーバとの接続で証明書のホスト名が正しく設定されていない場合に発生します。例えば、オリジンの宛先を IP アドレスで設定し、Fastly の Certificate hostname を設定していない場合などです。

##対策
オリジン側でどのような証明書が配置されているかを確認します。その証明書の DNS Name を確認し、そこで設定されているドメイン名を Fastly の Certificate hostname に設定します。
openssl コマンドでは下記で確認ができます。
```
$ openssl s_client -showcerts -connect <接続先ドメイン>:443 < /dev/null 2>&1 | openssl x509 -text 2>&1|grep DNS
```
また、ブラウザ（下記は Chrome の例）では下記の DNS Name で確認が可能です。
<img width="457" alt="CertDNS.png" src="https://qiita-image-store.s3.amazonaws.com/0/149542/c26631ed-040d-bf0a-8d25-82849921bc89.png">

Certificate hostname の設定は ORIGINS の TLS Options から設定できます。

<img width="810" alt="TLSOptions.png" src="https://qiita-image-store.s3.amazonaws.com/0/149542/b0c40497-59d3-bb3b-6813-d8bd19845216.png">

#unable to get local issuer certificate
##原因
Fastly と オリジンサーバの間が TLS/SSL で設定されていて、その接続に問題が発生しています。オリジンサーバ側の証明書が自前証明書であったり、中間証明書が適切に設定されていない場合に発生します。

##対策
自前証明書を利用したい場合には、自前証明書の CA証明書を ORIGINS の TLS Options から `TLS CA certificate` に設定してください。
一般的な商用証明書を利用しているにも関わらず、本エラーが発生する場合には中間証明書をサーバ側に適切に設定しているかを確認してみてください。

#SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure
##原因
Fastly と オリジンサーバの間が TLS/SSL で設定されていて、その接続に問題が発生しています。メッセージから原因がわかりにくいですが、この場合は SNI 証明書が利用されていることが多く、Fastly 側の設定がされていない場合に発生します。

##対策
Fastly の SNI hostname を設定します。SNI hostname の設定は ORIGINS の TLS Options から設定できます。

503 が発生する原因はその他にもありますが、ここでは私自身がサポートしている中で問い合わせが多いと感じるものをあげてみました。[Common 503 errors](https://docs.fastly.com/guides/debugging/common-503-errors) にも記載があるので参考にしてみてください。