スクリーンショット_2019-05-15_0

Udemy で AWS を学んでみた(3)

(1) (2) (3) (4)

■受講したコース(現在は新規購入停止中)

■メモ

□コンテンツキャッシュ
・Web サーバがコンテンツを配信する際に、その前段に Content Delivery Network (CDN) を配置し、コンテンツをキャッシュすることで Web サーバの負荷を軽減させる仕組み
例)キャッシュなし:利用者 ⇄ CDN ⇄ Web サーバ
  キャッシュあり:利用者 ⇄ CDN   Web サーバ
・CloudFront
 ・フルマネージド型 CDN サービス
 ・世界中に100を超えるエッジロケーションが存在する

□CloudFront を使う際のポイント
1. キャッシュ TTL の設計
 ・短すぎる:CDN の意味がなくなる
 ・長すぎる:コンテンツの更新が反映されない
2. Popular Object Report を参考に、定期的に設定を見直す

□インメモリキャッシュ
・頻繁にアクセスするデータを、データベースではなくインメモリキャッシュに格納することで、データベースの負荷を軽減させる仕組み
例)Web サーバ → インメモリキャッシュ
          → データベース
 ・まずはキャッシュを確認し、キャッシュがなければデータベースににアクセス
 ・データの種類によって格納先を変える
 例)セッション情報はデータベースではなくインメモリキャッシュに持たせる
・ElastiCache
 ・フルマネージド型インメモリキャッシュサービス
 ・レプリケーションやバックアップが容易
 ・多様なノードタイプがあり、システム要件に合わせて選択可能
 ・Redis と Memcached をサポート
  ・Redis:シングルスレッドで動作、データを永続化可能
  ・Memcached:マルチスレッドで動作、データの永続化不可
 ・フレームワーク(以下参照)

□Amazon Simple Email Service (SES)
・フルマネージドなメール送受信サービス
・送信関連の特徴
 ・AWS SDK 経由でプログラムからメール送信を行うことが可能
 ・独自ドメインからメールが送信可能
 ・バウンス(送信エラー)の対応が必要
・受信関連の特徴
 ・独自ドメインを設定可能
 ・受信メール を S3 に保存可能
 ・受信をトリガに後続の処理を実施可能

□Amazon Simple Queue Service (SQS)
・フルマネージドなキューイングサービス
・Queueのメリット
 ・非同期処理ができる
 ・モジュール間を疎結合にできる
・機能
 ・一度に複数件のメッセージを登録、取得できる
 ・Long Polling:キューが空の場合はタイムアウトするまで待ち続ける
 ・Dead Letter Queue:いつまでも残るキューを、別のキューに移動する
 ・Delay Queue(Massage Timer):新しいメッセージを指定した時間見えなくする
・注意点
 ・順序は保証されない
 ・同じメッセージを複数回受信する可能性がある
 ⇒FIFO キュー

■実践メモ

□Web+DB+ALB+CloudFront

・CloudFront の作成
 ・Web ディストリビューションの選択
 ・オリジンサーバに ALB の DNS 名を指定
・CloudFront 上のキャッシュを参照しているかを確認

// キャッシュがある場合
$ curl -I http://<CloudFront の Domain Name>
HTTP/1.1 200 OK
・・・(略)・・・
X-Cache: Hit from cloudfront
・・・(略)・・・
// キャッシュがない場合
$ curl -I http://<CloudFront の Domain Name>
HTTP/1.1 200 OK
・・・(略)・・・
X-Cache: Miss from cloudfront
・・・(略)・・・

□ElastiCache の利用

・ElastiCache 用セキュリティグループの作成
・サブネットグループの作成
・パラメータグループの作成
 ・RDS と同様、デフォルトのパラメータグループは変更できないため、事前に作成が必要
・ElastiCache(Redis) の作成
 ・クラスターエンジンに Redis を選択
・クライアント側に Redis CLI を導入

$ sudo yum install -y redis --enablerepo=epel

・ElastiCache(Redis) にアクセス

$ redis-cli -h <Redis プライマリエンドポイント>

・動作確認

// データの格納
> set key value

// データの取得
> get key

// key の一覧取得
> keys *

□SES の利用(送信編)

・独自ドメインを登録
 ・Route53 に登録した独自ドメインを設定
 ・「Generate DKIM Settings」を有効化
 *独自ドメインの取得、Route53 への登録は(2)参照
・Route53 に紐付け
 ・独自ドメインを Route53 に登録しているため、「Verify a New Domain」表示されたレコードを Route53 に作成すれば、ドメインの検証が完了する
・送信先メールアドレスの事前登録
 *事前登録していないメールアドレスに送信するには、利用緩和申請が必要
・マネジメントコンソールから送信
 ・DomainsーSend a Test Email
 *「To」には事前登録したメールアドレスを設定
・SDK for PHP で送信

// 事前準備
$ aws configure

$ curl -sS https://getcomposer.org/installer | php
$ php composer.phar require aws/aws-sdk-php

$ git clone https://github.com/ketancho/udemy-aws-14days.git
$ mkdir src
$ cd src
$ cp -r ../udemy-aws-14days/Day12/* .


// メールの送信
$ php SendEmail.php

□SQS の利用

・キューの作成
・マネジメントコンソールからメッセージを送受信
 ・送信:キュー操作ーメッセージの送信 
 ・受信:キュー操作ーメッセージの表示/削除ーメッセージのポーリングを開始
・SDK for PHP でメッセージを送受信

// メッセージの送信
$ php SendQueue.php

// メッセージの受信
$ php ReceiveQueue.php

□SES+SQS

・メール送信依頼のメッセージをSQSに登録

$ php SendEmailMessage.php
========== SendEmailMessage.php ==========
<?php
require '../vendor/autoload.php';

use Aws\Sqs\SqsClient;
use Aws\Exception\AwsException;

date_default_timezone_set('Asia/Tokyo');

$client = new SqsClient([
    'region' => 'ap-northeast-1',
    'version' => '2012-11-05'
]);

$params = [
    'MessageAttributes' => [
        "Sender" => [
            'DataType' => "String",
            'StringValue' => "<送信元メールアドレス>"
        ],
        "Destination" => [
            'DataType' => "String",
            'StringValue' => "<事前登録した送信先メールアドレス>"
        ],
        "Subject" => [
            'DataType' => "String",
            'StringValue' => "<件名>"
        ],
        "Body" => [
            'DataType' => "String",
            'StringValue' => "<本文>"
        ]
    ],
    'MessageBody' => date('YmdHis'),
    'QueueUrl' => '<作成した Queue URL>'
];

try {
    $result = $client->sendMessage($params);
    var_dump($result);
} catch (AwsException $e) {
    error_log($e->getMessage());
}

・SQS に登録されたメッセージを受信してメール送信

$ php ReceiveEmailMassage.php 
========== ReceiveEmailMassage.php ==========
<?php
require '../vendor/autoload.php';

use Aws\Sqs\SqsClient;
use Aws\Ses\SesClient;
use Aws\Exception\AwsException;

$queueUrl = "<作成した Queue URL>";

$client = new SqsClient([
    'region' => 'ap-northeast-1',
    'version' => '2012-11-05'
]);

try {
    $result = $client->receiveMessage(array(
        'AttributeNames' => ['SentTimestamp'],
        'MaxNumberOfMessages' => 1,
        'MessageAttributeNames' => ['All'],
        'QueueUrl' => $queueUrl, // REQUIRED
        'WaitTimeSeconds' => 0,
    ));
    if (count($result->get('Messages')) > 0) {
        $messageAttribute = $result->get('Messages')[0]['MessageAttributes'];
        $sender = $messageAttribute['Sender']['StringValue'];
        $destination = $messageAttribute['Destination']['StringValue'];
        $subject = $messageAttribute['Subject']['StringValue'];
        $body = $messageAttribute['Body']['StringValue'];
        
        sendEmail($sender, $destination, $subject, $body);

        $result = $client->deleteMessage([
            'QueueUrl' => $queueUrl, // REQUIRED
            'ReceiptHandle' => $result->get('Messages')[0]['ReceiptHandle'] // REQUIRED
        ]);
    } else {
        echo "No messages in queue. \n";
    }
} catch (AwsException $e) {
    // output error message if fails
    error_log($e->getMessage());
}


function sendEmail($sender, $destination, $subject, $body) {

$ses = SesClient::factory(array(
  'version'=> 'latest',
  'region' => 'us-east-1',
));

try {
  $result = $ses->sendEmail([
    'Source' => $sender,
    'Destination' => [
      'ToAddresses' => [
        $destination,
      ],
    ],
    'Message' => [
      'Subject' => [
        'Charset' => 'UTF-8',
        'Data' => $subject,
      ],
      'Body' => [
        'Text' => [
          'Charset' => 'UTF-8',
          'Data' => $body,
        ],
      ],
    ],
  ]);

  $messageId = $result->get('MessageId');
  echo("Email sent! Message ID: $messageId"."\n");

} catch (SesException $error) {
  echo("The email was not sent. Error message: ".$error->getAwsErrorMessage()."\n");
}
}

・参考


この記事が気に入ったらサポートをしてみませんか?