kun432's blog

Alexaなどスマートスピーカーの話題中心に、Voiceflowの日本語情報を発信してます。たまにAWSやkubernetesなど。

〜スマートスピーカーやVoiceflowの記事は右メニューのカテゴリからどうぞ。〜

HerokuでRedisを使う

f:id:kun432:20210704194211p:plain

前回の続き。

セッションストレージとして使うために、Redisを追加してみようと思います。

Redisアドオンの追加

前回のHello Worldアプリが動いている状態から進めます。

heroku addons:createでアドオンを作成します。Redisの場合は、heroku-redis:プランで指定します。hobby-devが無料のプランです。

$ heroku addons:create heroku-redis:hobby-dev
Creating heroku-redis:hobby-dev on ⬢ foo-bar-11111... free
Your add-on should be available in a few minutes.
! WARNING: Data stored in hobby plans on Heroku Redis are not persisted.
redis-foobar-22222 is being created in the background. The app will restart when complete...
Use heroku addons:info redis-foobar-22222 to check creation progress
Use heroku addons:docs heroku-redis to view documentation

これでRedisのデータベースが作成されます。作成中の進捗はheroku addons:infoで確認できます。

$ heroku addons:info redis-foobar-22222
=== redis-foobar-22222
Attachments:  foo-bar-11111::REDIS
Installed at: Mon Jul 19 2021 01:31:15 GMT+0900 (GMT+09:00)
Owning app:   foo-bar-11111
Plan:         heroku-redis:hobby-dev
Price:        free
State:        creating

State: creatingになっていて作成中なことがわかります。作成が完了すると以下のようにState: createdになります。

$ heroku addons:info redis-foobar-22222
=== redis-foobar-22222
Attachments:  foo-bar-11111::REDIS
Installed at: Mon Jul 19 2021 01:31:15 GMT+0900 (GMT+09:00)
Owning app:   foo-bar-11111
Plan:         heroku-redis:hobby-dev
Price:        free
State:        created

Herokuの管理画面でもRedisが上がっていることが確認できます。

f:id:kun432:20210719000134p:plain

作成されたRedisにアクセスするためのURLはheroku config:get REDIS_URLで確認。RedisはAWSに立つんですね。

アプリからRedisを参照する

Expressのセッションを管理する"express-session"で、セッションストレージにRedisを使ってみます。

ライブラリを追加します。

$ npm install --save express
$ npm install --save express-session
$ npm install --save redis
$ npm install --save connect-redis

コードを修正します。

const express = require('express');

const session = require("express-session");
const redis = require("redis");
const RedisStore = require("connect-redis")(session);

const app = express();

app.set('port', (process.env.PORT || 3000));

app.use(
    session({
        secret: 'secret',
        cookie: { maxAge: 3600 * 1000 },
        resave: false,
        saveUninitialized: false,
        store: new RedisStore({
            url: process.env.REDIS_URL,
            client: redis.createClient({
                url: process.env.REDIS_URL
            })
        })
    }),
);

app.get('/', function(request, response) {
  let session = request.session;
  console.log(JSON.stringify(session));
  if (!!session.count) {
    session.count += 1;
  } else {
    session.count = 1;
  }

  response.send(`Hello World! count: ${session.count}\n`);
});

app.listen(app.get('port'), function() {
  console.log("Node app is running at localhost:" + app.get('port'));
});

デプロイします。

git add .
git commit -m "add redis"
git push heroku master

アプリを開いてみましょう。

$ heroku open

カウントアップしていくのがわかります。

f:id:kun432:20210719015008p:plain

f:id:kun432:20210719015018p:plain

違うブラウザで試してみると、カウントが別になっているのがわかります。

f:id:kun432:20210719015057p:plain

Redisにアクセスする

Herokuの管理画面は、Redisのデータにアクセスするインタフェースを持っていません。管理画面からはパフォーマンス状況とRedisに接続するための認証情報を確認できます。

管理画面の"Installed add-ons"にある"Heroku Redis"をクリックします。

f:id:kun432:20210719015932p:plain

Overviewタブでパフォーマンス等のグラフが見れます。

f:id:kun432:20210719020039p:plain

Settingsタブでは、Redisに接続するための認証情報が確認できます。"View Credetials..."をクリックすると表示されます。

f:id:kun432:20210719020332p:plain

f:id:kun432:20210719020548p:plain

認証情報はHeroku CLIからも確認できます。

$ heroku config:get REDIS_URL
redis://:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX@ec2-XXX-XXX-XXX-XXX.compute-1.amazonaws.com:XXXX

スクリプトなどから接続する場合にはこの情報を使えばよさそうですね、知らんけど(やったことない)。

で、Heroku CLIを使えばかんたんに接続することができます。

$ heroku redis:cli
Connecting to redis-foobar-22222 (REDIS_TLS_URL, REDIS_URL):
ec2-XXX-XXX-XXX-XXX.compute-1.amazonaws.com:XXXXX>

試しに中身を見てみましょう。登録されているキーの一覧を見ます。

ec2-XXX-XXX-XXX-XXX.compute-1.amazonaws.com:XXXXX> keys *
1) sess:fjEX37i5mbXimKCdO3iL8xvyt1v8k6uX
2) sess:Yc4nUn37PbJ9SRVD7JKxIFc_w8SI_HI-
3) sess:TpIhPEM_b8JKJ_po6KCX9lgfEVlDzo9i
4) sess:l6CMK6hdnA2rECYoiO8rJXg9UB9KloTi
5) sess:hHrkwrg-a-IAzd0BCCNe2O8Cb7jgYmBo

いくつか入っていますね。個々のキーの中身を見てます。Redisではキーが保持している値の種類というか型によって参照の仕方がことなるみたいなので、typeを実行してます。

ec2-XXX-XXX-XXX-XXX.compute-1.amazonaws.com:XXXXX> type sess:fjEX37i5mbXimKCdO3iL8xvyt1v8k6uX
string
ec2-XXX-XXX-XXX-XXX.compute-1.amazonaws.com:XXXXX> get sess:fjEX37i5mbXimKCdO3iL8xvyt1v8k6uX
{"cookie":{"originalMaxAge":3600000,"expires":"2021-07-18T17:47:16.442Z","httpOnly":true,"path":"/"},"count":2}

カウンタらしき値が見えていますね。

おまけ

試しているときにInternal Server Errorとか出てて、ログみたいなーとか思ったら、これもHeroku CLIで見るみたい。-tはtailオプション。

$ heroku logs -t
2021-07-18T17:20:06.523883+00:00 heroku[router]: at=info method=GET path="/" host=foo-bar-11111.herokuapp.com request_id=8717856c-58c2-4b92-a407-a477ff497a9d fwd="XXX.XXX.XXX.XXX" dyno=web.1 connect=1ms service=44ms status=200 bytes=385 protocol=https
2021-07-18T17:20:06.496788+00:00 app[web.1]: {"cookie":{"originalMaxAge":3600000,"expires":"2021-07-18T17:48:22.464Z","httpOnly":true,"path":"/"},"count":1}
...

まとめ

とりあえずざっくり使い方がわかったので、次こそはVoiceflowSDKでセッション管理と、Heroku Buttonでadd-onまで設定できるようにしたい。

※参考