はじめに
AWS DynamoDBでphpのセッションを管理します。
マルチAZの場合、複数のEC2でセッション情報を同期する必要があります。
その場合、候補に上がるのが、 DynamoDBかElastiCacheになるはずです。
1. IAMポリシーの作成
EC2インスタンスにアタッチしているロールに、このポリシーを割り当てます。
php-sessions
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"dynamodb:GetItem",
"dynamodb:UpdateItem",
"dynamodb:DeleteItem",
"dynamodb:Scan",
"dynamodb:BatchWriteItem"
],
"Resource": "arn:aws:dynamodb:ap-northeast-1:{AWSのアカウントID}:table/{DynamoDBのテーブル名}"
}
]
}
2. DynamoDBの作成
DynamoDBを作成します。
項目 | 値 |
---|---|
テーブル名 | 任意 |
プライマリキー | id (文字列) |
テーブル作成後、「概要->TTLの管理」から、 TTLを有効化にします。
項目 | 値 |
---|---|
TTL属性 | expired (任意) |
3. EC2インスタンスにphpのSDKをインストールする
EC2インスタンスにcomposerを利用して、phpのSDKをインストールします。
:スクリプト
# composer設定
EXPECTED_SIGNATURE="$(wget -q -O - https://composer.github.io/installer.sig)"
php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
ACTUAL_SIGNATURE="$(php -r "echo hash_file('sha384', 'composer-setup.php');")"
if [ "$EXPECTED_SIGNATURE" != "$ACTUAL_SIGNATURE" ]
then
>&2 echo 'ERROR: Invalid installer signature'
rm composer-setup.php
exit 1
fi
php composer-setup.php --quiet
RESULT=$?
rm composer-setup.php
sudo mv composer.phar /usr/local/bin/composer
sudo yum install -y --enablerepo=remi,remi-php70 php-xml
sudo rm composer*
composer require aws/aws-sdk-php
4. phpからの利用方法
セッション管理用のクラスを作成します。
シングルトンパターンを利用します。
SessionDynamoDB.php
<?php
# 任意のディレクトリに配置したautoload.phpを呼び出す
require_once(dirname(__FILE__) . '/autoload.php');
use Aws\DynamoDb\DynamoDbClient;
use Aws\DynamoDb\SessionHandler;
use Aws\DynamoDb\Exception\DynamoDbException;
interface SessionDynamoDBInterface
{
//インスタンスを生成する。
public static function getInstance();
//ハンドラーを登録する。
public function start();
}
class SessionDynamoDB implements SessionDynamoDBInterface
{
private static $singleton;
private $client;
private $sessionHandler;
/**
* DynamoDBクライアント生成
*/
private function __construct()
{
try {
$this->client = DynamoDbClient::factory([
'region' => 'ap-northeast-1',
'version' => 'latest',
]);
$this->sessionHandler = SessionHandler::fromClient($this->client, [
'table_name' => '{DynamoDBのテーブル名}',
'hash_key' => 'id',
'session_lifetime' => 3600,
'consistent_read' => true,
'locking' => false,
'batch_config' => [],
'max_lock_wait_time' => 10,
'min_lock_retry_microtime' => 5000,
'max_lock_retry_microtime' => 50000,
]);
$this->sessionHandler->register();
// Start the session
session_start();
// // Close the session (optional, but recommended)
session_write_close();
} catch(DynamoDbException $e){
throw new DynamoDbException ($e->getMessage());
}
}
/**
* インスタンスを生成する。
*
* @return object self::$singleton
*/
public static function getInstance(): object
{
if (!isset(self::$singleton)) {
self::$singleton = new SessionDynamoDB();
}
return self::$singleton;
}
/**
* このインスタンスの複製を許可しないようにする
*
* @throws RuntimeException
*/
public final function __clone()
{
throw new RuntimeException ('Clone is not allowed against ' . get_class($this));
}
/**
* ハンドラーを登録する。
*
*/
public function start(): void
{
$this->sessionHandler->register();
// Start the session
session_start();
}
}
クラスからセッションを利用します。
php実行ファイル
# 任意のディレクトリに配置したSessionDynamoDB.phpを呼び出す
require_once(dirname(__FILE__) . '/SessionDynamoDB.php');
$session = SessionDynamoDB::getInstance();
$session->start();
# 冒頭に上記の記述をすれば、あとは普通に$_SESSIONを利用するだけです。
var_dump($_SESSION);