4
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

EC2からAmazon SQSにメッセージを送り、RDSのDBに保存する方法

Last updated at Posted at 2023-10-25

内容

EC2からAmazon SQSを経由してRDSにデータを保存する方法をまとめます。
RDSのダウンタイム中にRDSに保存処理をしようとするとエラーになり、そのデータが失われます。
そのため、ダウンタイム中はSQSにメッセージをためておいて、RDSが起動したタイミングでデータを保存することにします。

こんな感じ
image.png

前回作成したものを使用します。

Amazon SQSでキューを作成する

Amazon SQSのダッシュボードから「キューの作成」をクリックします。
image.png

今回は「標準」を選択します。
FIFOとの違いは、FIFOがメッセージの順番を約束してくれるのに対し、標準は保証されません。
image.png

以上です。

SQSにメッセージを送信する

AWS SDK for PHPのインストール

前回作成したindex.phpからAmazon SQSにメッセージを送信する処理を追加します。
今回はAWS SDK for PHPを使用します。
EC2にsshし、/var/www/html/で↓を叩きます。

[ec2-user@ip-10-0-0-102 html]$ sudo composer require aws/aws-sdk-php
[ec2-user@ip-10-0-0-102 html]$ composer show -i
    →aws/aws-sdk-phpがあればOK

これでAWS SDK for PHPが使用可能になりました。

そして作成したSQSのキューのURLをコピーを確認します。
スクリーンショット 2023-10-29 8.13.21.png

/var/www/html/index.phpに↓を追記します。

<?php
require_once 'vendor/autoload.php';

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

// AWSの認証情報
$credentials = new Aws\Credentials\Credentials([アクセスキーID], [アクセスキー]);

$sqsClient = new SqsClient([
    'version' => 'latest',
    'region' => '[リージョンのコード]',
        'credentials' => $credentials,
]);

$queueUrl = [キューのURL];

...

if ($post_message) {
    // メッセージを送信する処理
    $result = $sqsClient->sendMessage([
        'QueueUrl' => $queueUrl,
        'MessageBody' => $post_message,
    ]);

    $query = "INSERT INTO post (post) VALUES ('" . $post_message  . "')";
    $stmt = $dbh->query($query);
}

...

アクセスキーIDとアクセスキーをベタ打ちしていますが、本当にセキュリティ上やばいのでやめましょう。
今回だけです。

アクセスキーIDとアクセスキーを取得するには、
AWSのダッシュボード→セキュリティ認証情報→アクセスキーを作成
です。

ではブラウザからアクセスしてメッセージを送信してみましょう

image.png

image.png
前回と同様に、送信したメッセージがDBに保存されました。

ではAmazon SQSも見てみましょう。
image.png

「利用可能なメッセージ」が1件あるのがわかります。
無事送信したメッセージがSQSに保存されていることがわかります。

SQSからメッセージを受信する

/var/www/html/にrecieve.phpを作成します。

<?php
require 'vendor/autoload.php';

use Aws\Sqs\SqsClient;

$dsn = "mysql:host=[エンドポイント];dbname=[データベース名]";
$username = "ユーザー名";
$password = "DBのパスワード";
$dbh = new PDO($dsn, $username, $password);

// AWS認証情報の設定
$credentials = new Aws\Credentials\Credentials('アクセスキーID', 'アクセスキー');

// SQSクライアントの作成
$sqsClient = new SqsClient([
    'version' => 'latest',
    'region' => '[リージョンコード]', 
    'credentials' => $credentials,
]);

// メッセージを受信
$queueUrl = 'amazon SQSのURL';

if ($_POST['fetch']) {
    $result = $sqsClient->receiveMessage([
        'QueueUrl' => $queueUrl,
    ]);
}

// 受信したメッセージを処理
if (!empty($result['Messages'])) {
    foreach ($result['Messages'] as $message) {
        $messageBody = $message['Body'];
        
	echo $messageBody . "を受信しました"  . PHP_EOL;

        $query = "INSERT INTO post (post) VALUES ('" . $messageBody  . "')";
        $stmt = $dbh->query($query);

        // メッセージを削除
        $sqsClient->deleteMessage([
            'QueueUrl' => $queueUrl,
            'ReceiptHandle' => $message['ReceiptHandle'],
        ]);
    }
} else {
    echo '受信したメッセージはありません。';
}
?>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>sqs</title>
</head>
<body>
    <form action="" method="post">
        <button name="fetch" value="1">メッセージを受信</button>
    </form>
</body>
</html>

何度も言いますが、アクセスキーなどをベタ打ちするのはやめましょう。

ではブラウザで実行してみましょう。
image.png

image.png
先ほど送信した「HELLO」というメッセージが取得できました。

ここでもDBに保存処理をしているので、index.phpを表示させると「HELLO」が2件保存されていることがわかります。
image.png

RDSのダウンタイム中に実行する

RDSのダウンタイムを想定してこの処理を実行してみます。
RDSのダウンタイム中はDBの接続情報をコメントアウトしておきましょう。

ブラウザで表示させると
image.png
(ダウンタイム中なのでDBのデータが取得できていません)

ではこの状態でメッセージを送信してみましょう。
「Good Morning」と入力して送信ボタンを押すと...
image.png
ダウンタイム中ですし、DBへの接続を切っているのでうんともすんともなりません...
image.png

「私のあいさつがこの世から消えてしまったのか...?」

そんな心配はご無用です。
SQSをのぞいてみると、きちんとメッセージが保存されています。
image.png

ここでRDSのダウンタイムが終わり、再起動しました。
DBへの接続情報のコメントアウトを外します。

recieve.phpからメッセージを受信してみましょう。

image.png
失ったと思われていた「Good Morning」が取得できました。
index.phpを確認すると、きちんとDBにも保存されていることがわかります。
image.png

という感じで、RDSのダウンタイム中の処理を止めない方法を作ってみました。
とはいえSELECTができないので、完璧ではないですね。
また何か方法があるか探ってみます。

4
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?