hero_picture
Cover Image for CloudFrontが60秒でタイムアウトする件の検証

CloudFrontが60秒でタイムアウトする件の検証

こんにちは、システム開発事業部の加藤です
CloudFrontのデフォルト設定では60秒でタイムアウトするようになっています
この制限の挙動について検証しました

概要

CloudFrontのデフォルト設定では60秒でタイムアウトするようになっています
この制限の挙動について検証しました

検証で利用した構成

EC2とCloudFrontを構築

EC2

  • EC2(AL2023) + Apache + PHP-FPM + PHP
  • パブリックサブネットに配置
  • Apacheのタイムアウトを60秒以上に設定する
  • PHPのタイムアウトを60秒以上に設定する
  • PHPの出力バッファリングを無効(リアルタイムで出力する動きの再現のため)
1# php.iniを変更
2output_buffering = 0
  • Apacheでデータをすぐにクライアントにデータを返すように設定(php-fpmの利用の場合)
1# httpd.confを変更
2<Proxy unix:/run/php-fpm/www.sock|fcgi://localhost>
3    ProxySet flushpackets=on timeout=300
4</Proxy>

CloudFront

オリジンのタイムアウト時間の設定を最大値にする

検証シナリオ

CloudFront経由でEC2に接続した時にEC2から60秒以上レスポンスがない場合

結果

タイムアウトして接続できない
オリジンサーバー(EC2)からCloudFrontに対して60秒以上レスポンスがない場合はタイムアウトする

検証内容

実行したスクリプトは以下

1<?php
2// スクリプトが60秒以上の遅延
3sleep(65); // 65秒間スリープ
4echo "Response after 65 seconds";
5?>

EC2に直接アクセスして実行した場合

レスポンスが帰ってくることを確認

1$ curl http://ec2-52-199-123-36.ap-northeast-1.compute.amazonaws.com/cloudfront-test/no-response.php
2
3Response after 65 seconds

CloudFront経由でのアクセスの場合

タイムアウトする

1$ curl https://d1zg773tvuk57c.cloudfront.net/cloudfront-test/no-response.php
2
3<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
4<HTML><HEAD><META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
5<TITLE>ERROR: The request could not be satisfied</TITLE>
6</HEAD><BODY>
7<H1>504 ERROR</H1>
8<H2>The request could not be satisfied.</H2>
9<HR noshade size="1px">
10CloudFront attempted to establish a connection with the origin, but either the attempt failed or the origin closed the connection.
11We can't connect to the server for this app or website at this time. There might be too much traffic or a configuration error. Try again later, or contact the app or website owner.
12<BR clear="all">
13If you provide content to customers through CloudFront, you can find steps to troubleshoot and help prevent this error by reviewing the CloudFront documentation.
14<BR clear="all">
15<HR noshade size="1px">
16<PRE>
17Generated by cloudfront (CloudFront)
18Request ID: Il3-xdnBXHFOQ-95GmGm4Nyb5FpXRMiNqoVHIAaUFyYnlQWPK0ZcYg==
19</PRE>
20<ADDRESS>
21</ADDRESS>
22</BODY></HTML>% 

Cloudfront経由でEC2で ファイルをアップロードした時にアップロードに60秒以上時間がかかるとどうなるか (アップロードトラフィックが流れてる時にどうなるか)

結果

問題なし、アップロード可能

継続的にCloudFrontからオリジンサーバーに対して、リクエストデータが流れている状況では、タイムアウトを発生させずに処理を継続

検証した内容

実行したスクリプトは以下

1<?php
2// アップロードされたファイルを保存
3if ($_SERVER['REQUEST_METHOD'] == 'POST' && isset($_FILES['file'])) {
4    if ($_FILES['file']['error'] !== UPLOAD_ERR_OK) {
5        echo "Failed to upload file with error code: " . $_FILES['file']['error'];
6        exit;
7    }
8    
9    $uploadDir = '/var/www/html/uploads/';
10    $uploadFile = $uploadDir . basename($_FILES['file']['name']);
11    if (move_uploaded_file($_FILES['file']['tmp_name'], $uploadFile)) {
12        echo "Upload complete";
13    } else {
14        echo "Failed to move uploaded file";
15    }
16} else {
17    echo "No file upload";
18}
19?>

EC2に直接の場合

1$ curl --limit-rate 1m -w "Time: %{time_total}s\n" -X POST -F file=@/Users/ryota/Desktop/100MB.jpg http://ec2-52-199-123-36.ap-northeast-1.compute.amazonaws.com/cloudfront-test/upload-file-over-time.php
2
3Upload completedTime: 100.092001s

CloudFront経由の場合

問題なし

1$ curl --limit-rate 1m -w "Time: %{time_total}s\n" -X POST -F file=@/Users/ryota/Desktop/100MB.jpg https://d1zg773tvuk57c.cloudfront.net/cloudfront-test/upload-file-over-time.php
2
3Upload completedTime: 100.009124s

CloudFront経由でEC2で 接続した時にEC2から30秒ごとレスポンスがある場合

結果

問題なし

オリジンサーバーから、CloudFrontに対してレスポンスデータが流れている状況では、タイムアウトを発生させずに処理を継続

最後のレスポンスから60秒以上レスポンスがない場合はタイムアウトする

検証内容

実行したスクリプトは以下

1<?php
2// 無限ループで30秒ごとにレスポンス
3// 2分経ったらタイムアウト
4$time = 0;
5while (true) {
6    echo "response at " . date("H:i:s") . "\n";
7    ob_flush();
8    flush();
9    sleep(30);
10    $time += 30;
11    if ($time > 120) {
12        break;
13    }
14}
15?>

EC2に直接アクセス

1$ curl http://ec2-52-199-123-36.ap-northeast-1.compute.amazonaws.com/cloudfront-test/response-every-30sec.php
2
3response at 0 seconds
4response at 30 seconds
5response at 60 seconds
6response at 90 seconds
7response at 120 seconds

CloudFront経由の場合

問題なし

1 $ curl https://d1zg773tvuk57c.cloudfront.net/cloudfront-test/response-every-30sec.php
2 
3response at 0 seconds
4response at 30 seconds
5response at 60 seconds
6response at 90 seconds
7response at 120 seconds

2分経ったら60秒以上の遅延を挟むように変更

1<?php
2// 無限ループで30秒ごとにレスポンス
3// 2分経ったら、61秒間の遅延を挟んで終了
4$time = 0;
5while (true) {
6    echo "response at " . $time . " seconds\n";
7    ob_flush();
8    flush();
9    sleep(30);
10    $time += 30;
11    if ($time === 120) {
12        sleep(61);
13        echo "Response after 61 seconds";
14        break;
15    }
16}
17?>

EC2に直接

最後のレスポンスまで出力

1$ curl http://ec2-52-199-123-36.ap-northeast-1.compute.amazonaws.com/cloudfront-test/response-every-30sec.php
2
3response at 0 seconds
4response at 30 seconds
5response at 60 seconds
6response at 90 seconds
7Response after 61 seconds

CloudFront経由の場合

最後のレスポンスから60秒以上レスポンスがない場合は切られる

1 $ curl https://d1zg773tvuk57c.cloudfront.net/cloudfront-test/response-every-30sec.php
2 
3response at 0 seconds
4response at 30 seconds
5response at 60 seconds
6response at 90 seconds
7

CloudFront経由でEC2で 60秒以上時間がかかるファイルダウンロードの場合

結果

問題なし、ダウンロードできる

検証内容

実行したスクリプトは以下

1<?php
2$filePath = "/var/www/html/uploads/100MB.jpg";
3
4if (!file_exists($filePath)) {
5    die('File not found.');
6}
7
8$fileSize = filesize($filePath);
9
10header('Content-Type: image/jpeg');
11header('Content-Length: ' . $fileSize);
12
13// 1秒ごとに1MBずつ出力
14$handle = fopen($filePath, 'rb');
15$chunkSize = 1024 * 1024;
16while (!feof($handle)) {
17    echo fread($handle, $chunkSize);
18    flush();
19    sleep(1); // 1秒遅延
20}
21
22fclose($handle);
23exit;
24?>
25
26

EC2から直接

1$ curl http://ec2-52-199-123-36.ap-northeast-1.compute.amazonaws.com/cloudfront-test/download-file-over-time.php -o 100MB.jpg
2  
3  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
4                                 Dload  Upload   Total   Spent    Left  Speed
5100  100M    0  100M    0     0   799k      0 --:--:--  0:02:08 --:--:-- 79286

CloudFront経由

1分以上かかっているが、ダウンロードできている、問題なし

1$ curl https://d1zg773tvuk57c.cloudfront.net/cloudfront-test/download-file-over-time.php -o 100MB.jpg
2
3  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
4                                 Dload  Upload   Total   Spent    Left  Speed
5100  100M    0  100M    0     0   993k      0 --:--:--  0:01:43 --:--:--  762k

まとめ

オリジンサーバーとCloudFront間で60秒間以内にデータが流れている場合は、タイムアウトしないことが確認できました


👉️ AWS Graviton のことなら acCloud にお任せください!
👉️ AWS Graviton のことなら acCloud にお任せください!