RareJob Tech Blog

レアジョブテクノロジーズのエンジニア・デザイナーによる技術ブログです

Composer対応していないパッケージをComposerで定義する

こんにちは。
厳しい寒さが続いておりますが、いかがお過ごしでしょうか。
サービス開発チームのすずきです。

みなさんComposerは使っていますか?(何をいまさら)
弊社の英会話システムはPHPで作られており、パッケージの依存管理にはComposerを利用しています。
新しいパッケージを追加したいときは

$ composer require monolog/monolog

みたいな感じでPackagistから取得することが多いと思うのですが、
今回やりたいこととしてはS3バケットに上がっているパッケージを追加し利用できるようにする ことです。

元々は、弊社オンプレのGitlab上に配置されており、以下の様にcomposer.jsonに記載することで利用しておりました。

{
    "repositories": [
        {
            "type": "vcs",
            "url": "git@bitbucket.org:vendor/my-private-repo.git"
        }
    ],
    "require": {
        "vendor/my-private-repo": "dev-master"
    }
}

上記のサンプルはこちらから拝借🙏

今回は、パッケージをZipしたものがS3にアップロードされている状態で、Composerを利用してパッケージ追加したいと思います。
そのためには自分でpackageを定義する必要があり、私たちの場合はpackageに対して、元々パッケージが定義していたcomposer.jsonの内容を記載することで対応しました。

パッケージが定義していたcomposer.json

{
    "name": "vendor/my-private-repo",
    "description": "this is a private package",
    "type": "library",
    "require": {
        "php": "^7.2.0",
        "ext-json": "*",
    },
    "require-dev": {
        "phpunit/phpunit": "< 7.2",
    },
    "autoload": {
        "psr-4": {
            "Vendor\\Private\\": "src/private"
        }
    }
}

パッケージを利用する側のcomposer.json

{
    "repositories": [
        {
            "type": "package",
            "package": {
                "name": "vendor/my-private-repo",
                "version": "3.1.7",
                "dist": {
                    "url": "https://path-to-aws-s3-bucket/my-private-repo-v.3.1.7.zip",
                    "type": "zip"
                },
                "require": {
                    "php": "^7.2.0",
                    "ext-json": "*",
                },
                "autoload": {
                    "psr-4": {
                        "Vendor\\Private\\": "src/private"
                    }
                }
            }
        }
    ],
    "require": {
        "vendor/my-private-repo": "3.1.*"
    }
}

パッケージが依存している他のパッケージをrequireに記載することでComposerが依存関係を解決してくれます。 また、パッケージを利用する側で不要なrequire-devは削除しています。

参考

getcomposer.org

寒い日が続きますが、来週には春の暖かさがくるようです🤗

Androidのダークテーマ

こんにちは、ネイティブアプリ開発を担当している杉山です。

今回は、Android 10 から利用可能となった「ダークテーマ」のお話です。

ダークテーマとは

Android 10 から利用可能となった黒基調の UI です。

ダークテーマのメリット

  • 電力消費を節約!
  • 視覚障がいのある方、明るい光が苦手な方にとって見やすさ向上!

ダークテーマを使う

1. アプリのテーマに DayNight Theme を継承させる

/res/values/styles.xml にて以下の設定を行う。

<style name="AppTheme" parent="Theme.AppCompat.DayNight">

MaterialComponents のダークテーマも利用可能です。

<style name="AppTheme" parent="Theme.MaterialComponents.DayNight">

2. リソースディレクトリを切り分ける

修飾子として、日中用には notnight を付け、夜間用には night を付けて、リソースを管理。( notnight が付いていない場合、通常の values からリソースを取り出す。)

- res
  - values-night
  - values-notnight
  - values
  - drawable-night
  - drawable

3. アプリ内に適用するモードを設定

アプリケーションクラスを継承させたクラスの中で以下の設定を行う。

AppCompatDelegate.setDefaultNightMode([設定するモード])

モード一覧

  • MODE_NIGHT_YES ... 常に夜間モードを使用。リソースはnight修飾子の付いたものを使用。

  • MODE_NIGHT_NO ... 夜間モードは使用しない。リソースはnotnight修飾子の付いたものを使用。

  • MODE_NIGHT_FOLLOW_SYSTEM ... システムの判断に従って判別

  • MODE_NIGHT_AUTO ... 自動で判別。リソースは日中の場合 notnight修飾子の付いたものを、夜間の場合は night修飾子の付いたものを使用。

モードが切り替わったことをハンドリング

AndroidManifest.xml 内で以下の設定を行う。

<activity
    android:name=".Activity"
    android:configChanges="uiMode" />

onConfigurationChanged を用いて、設定されているテーマを確認する。

override fun onConfigurationChanged(newConfig: Configuration) {
    super.onConfigurationChanged(newConfig)

    val isDarkTheme = newConfig.uiMode and Configuration.UI_MODE_NIGHT_MASK
    when (isDarkTheme) {
        Configuration.UI_MODE_NIGHT_NO -> Log.d("Mode : ", "通常モード")
        Configuration.UI_MODE_NIGHT_YES -> Log.d("Mode : ", "ダークテーマ")
    }
}

おまけ

ダークテーマに対応しない

styles.xml で、DayNight Theme を継承しない

<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">

ダークテーマをレイアウトから確認

  1. レイアウトファイルを開き、Design タブに切り替える。

  2. 画像のようなアイコンが、左上にあるのでクリック。

  3. Night Mode をNightに設定。( Not Night = 日中、Night = 夜間 )

f:id:r_sugiyama:20200130123302p:plain

まとめ

ダークテーマの対応は意外と簡単にできますが、イメージなどのリソースを作る対応が入ると大変だなと感じました。

ER図 の自動作成を CI に組み込んだ話

塚田です。新人の頃からドキュメントの管理が大の苦手です。

ドキュメントの更新は滞り陳腐化してしまい、必要な時に見直すと使い物にならなかったりします。誰もが経験あるのではないでしょうか。

少しでもその呪縛から解放されるのであれば全力を注ぎたくなる性分なので、 ER図 を自動作成してくれる SchemaSpy を社内で使っている GitLab CI に組み込みました。

今回は SchemaSpy の紹介と、CI に組み込んだ話をしたいと思います。

SchemaSpy とは

DBに接続してテーブル構成などをスキャンして、html としてアウトプットしてくれる機能を持っています。 MySQLPostgreSQL などをサポートしています。

http://schemaspy.org/

CI への組み込み

弊社のCIのパイプラインでは、GitLab に push すると、自動でテストなどが動くような作りになっています。 そのテストの一環で、DBにスキーマ情報を migration する動きが既にありました。 そこに処理を追加し、CI で作られる DB へ SchemaSpy を繋げるようにしました。

SchemaSpy によって作られる成果物を S3 へ copy、 S3では Static website hosting を有効化にして、静的コンテンツを動かす Webサーバ のように使い、社内IPからのみ繋がるようにしました。

設定内容

.gitlab-ci.yml に追加したのは以下の部分

schemaspy:
  <<: *go_setup
  <<: *tags
  stage: schemaspy
  services:
    - mysql:5.7
  script:
    - make ci-migrate
    - apt-get update
    - apt-get install -y openjdk-11-jre/stable unzip busybox build-essential graphviz
    - wget https://dev.mysql.com/get/Downloads/Connector-J/mysql-connector-java-5.1.48.zip -qO - | busybox unzip -
    - wget https://github.com/schemaspy/schemaspy/releases/download/v6.0.0-rc2/schemaspy-6.0.0-rc2.jar -O schemaspy.jar
    - java -jar schemaspy.jar -configFile ./ci/schemaspy.properties -vizjs
    - mkdir -p ${ARTIFACTS_DIR}/${CI_PIPELINE_ID}/schemaspy
    - mv output/* ${ARTIFACTS_DIR}/${CI_PIPELINE_ID}/schemaspy/.
  artifacts:
    paths:
      - ${ARTIFACTS_DIR}/${CI_PIPELINE_ID}/schemaspy
    expire_in: 3 days
  only:  
    - master
    - development

ER図の作成は全ての branch で動かす必要もないので 現在は限られた branch のみ、SchemaSpy を動かすようにしています。

DBの接続情報は schemaspy.properties に書いています。

# type of database. Run with -dbhelp for details
schemaspy.t=mysql
# optional path to alternative jdbc drivers.
schemaspy.dp=mysql-connector-java-5.1.48/mysql-connector-java-5.1.48-bin.jar
# database properties: host, port number, name user, password
schemaspy.host=mysql
schemaspy.port=3306
schemaspy.db=database
schemaspy.u=root
schemaspy.p=password
# output dir to save generated files
schemaspy.o=output
# db scheme for which generate diagrams
schemaspy.s=public

その後、AWS S3 への push は以下のように定義して、gitlab runner が動くインスタンス自体に適切な権限を付与しています。

document:
  <<: *awscli_definition
  <<: *tags
  stage: document
  before_script:
    - export REF_NAME=`echo ${CI_COMMIT_REF_NAME} | sed -e 's%/%_%g' -e 's%-%_%g'`
  script:
    - aws s3 cp ${ARTIFACTS_DIR}/${CI_PIPELINE_ID}/schemaspy s3://${s3-backet}/schemaspy/${repository}/${REF_NAME}/ --recursive
  only:  
    - master
    - development

S3 ではパブリックアクセスを拒否しております f:id:sumito1984:20200123114004p:plain

バケットポリシーで社内の IP のみアクセスできるよう設定を入れています。

{
    "Version": "2012-10-17",
    "Id": "document from designated SourceIP",
    "Statement": [
        {
            "Sid": "document from designated SourceIP",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:*",
            "Resource": "arn:aws:s3:::xxxx-document/*",
            "Condition": {
                "IpAddress": {
                    "aws:SourceIp": "xxx.xxx.xx.xx/32"
                }
            }
        }
    ]
}

パイプライン が pass することを確認すると

f:id:sumito1984:20200123015435p:plain

S3 にファイルが置かれています。 ブラウザ で以下のような スキーマ情報 を見ることができます。

テーブル情報 f:id:sumito1984:20200123020019p:plain

自動生成されたER図 f:id:sumito1984:20200123020012p:plain

これで DB に関係するドキュメント、特に ER図 のメンテナンスから解放されそうです。

ちなみに、mysqldump から読み込ませるやり方はこちらに記載していますので、必要であればご覧いただけますと幸いです。

SchemaSpy で SQLファイル からスキーマ情報を出せるようにした - Tech Tips

それでは!

デザインスプリントを行った話

どうも!デザイナーの渡辺です!

みなさん新年が明け、お仕事が始まってから2週間程立ちましたが

いかがお過ごしでしょうか?(゚∀゚)
私は今年からジムに通い始めて
筋肉痛の毎日を過ごしておりますヽ(=´▽`=)ノイタイイタイ

さて、今回は昨年末にデザインチームで行った
デザインスプリントについてお話していきたいと思います!

デザインスプリントとは?

そもそもデザインスプリントって?という方もいらっしゃるかと思います。

デザインスプリントはGoogleが開発した
【5日間で価値のあるプロダクトを開発するフレームワーク
なんだか凄そうですよね( ´∀`)bグッ!

それなら入れない理由はない!ということで
我らデザインチームが新しいプロジェクトで取り入れてみました!
(新しいこと取り入れるのが好きなチームなので(ノω・)ヘヘ)

5日間の流れ

デザインスプリントでは、5日間でやることが毎日変わってきます。
具体的には下記の流れで行っていきます。

1日目:理解 2日目:発散 3日目:決定 4日目:試作 5日目:検証

デザインチームで実際にやってみました

1日目

理解

こちらでは、問題点を洗い出し、課題の決定をしていきます。
理解というくらいですので、これでもかっ!というくらいに
知ってる情報を出し認識を深めて行き
課題の決定をしていきます。
ここでは、デザイナーだけでなくフロントエンジニアの方も交え
システム側の課題点も合わせて行いました!
複数人で行うので自身だけでは見えていなかった物が見え
「へー!そんな事あったんだ!」「確かに。それも課題だね」
という声が結構上がります(^^)/

2日目

発散

1日目で見えてきた課題に対し、それを解決する案をひたすら出していきます!

案を出す際に行うのはスケッチ!
こちらはツールではなく、
ひたすら紙に手書きで書いていくことを言います(^^)
黙々とワイヤー案を書いていきます!
これが結構楽しいんですよね(´ω`)

3日目

決定

それぞれがスケッチしてきた紙を出し合い
全員でブレストをしていき、
どの案で進めるかを決めていきます!
ここではやることの決定ですので、予算であったり、
スケジュール等の観点が入ってくることもあります。

今回私達のデザインスプリントでは
POにも参加してもらい決定していきました!

4日目

試作

ここでは3日目に決定したスケッチを元に
プロトタイプを作成していきます。
我々がプロトタイプ作成に使用したのは【Figma】です!

以前、Figmaに関しても少し記事を書きましたので
ご興味ある方はこちらもご覧ください(*´∀`)

【レアジョブのデザインチームがFigmaを導入したお話】 https://appeal.rarejob.co.jp/2019/08/06/6116/

5日目

検証

最終日!【検証】です!
5日間の集大成をお披露目する場面ですね!

実際のユーザーを招待して行うこともありますが
今回は社内のプロジェクトに関わる方に実際に見ていただき
FigmaでFBをいただくという形を取りました(*゚∀゚)

1〜3日目までの間に情報を出し切り、
その上で案を出していることでブラッシュアップされ

1人で作業するときよりも
FBの数は少なくなっているように感じます。

頂いたFBを元に今後の動き、修正するのかなどを決めていきます。

実際にやってみて

デザイナー全員の時間を使ってしまうので
他に並行している作業があると
時間の調整が難しいという難点がありますが
プロジェクトが大きければ大きいほど
5日間という短い時間の中で
認識のずれを軽減でき、質の高いプロトタイプを
生み出せるフレームワークだなと思いました!

ただし、逆を言えば小さいプロジェクトだと使う機会が少ないため
自社で行う際のルール作りなどは
精査できるまで時間がかかるのかなという印象です。

5日間がっつりコミュニケーションを取るので
常に黙々と作業しているというチームには
コミュニケーションを図る良い
機会にもなるのかなと思います(๑•̀ㅂ•́)و✧

また個人的には、「みんなで1つものを作っているんだ!」というのが
実感できるフレームワークだったので
やっていてモチベーションアップに繋がっているなと感じました!

中規模、大規模のプロジェクトを行う際には
ぜひデザインスプリントを
試してみてはいかがでしょうか?ヽ(=´▽`=)ノ

それではノシ

Kinesis Video Streams (WebRTC)の話をしよう

AKEOME。ジャンボです。 今日はKinesisの話をして優勝していこうと思います。細かいWebRTCに関する説明は飛ばします。

Kinesis Video Streams とは

Amazon Kinesis Video Streams を使用すると、分析、機械学習 (ML)、再生、およびその他の処理のために、接続されたデバイスから AWS へ動画を簡単かつ安全にストリーミングできるようになります。

要するにストリーミングコンテンツを解析する仕組みです。IoT の文脈で監視カメラの映像で不審者の検出や工場の不整製品検知などがユースケースとして想定されます。これまでは映像を受け入れて解析することがサービスの主体でしたが、AWS re:Invent 2019 にてWebRTCのサポートが発表になりました。

今回のリリースでできるようになったこと

Kinesis Video Streams がサポートするオープンソースプロジェクトの WebRTC は、リアルタイムのメディアストリーミング、ウェブブラウザ間のインタラクション、モバイルアプリケーション、シンプルな API によるコネクテッドデバイスを可能にします。 用途としては、ビデオチャットやピアツーピアのメディアストリーミングが一般的です。

この記述のところですね。少し既存のユースケースとは実は違くて、Kinesisが拡張したというより、「WebRTCを使うための基礎的な仕組みを一部AWSが提供し始めた」というのが正しいかと思いました。

具体的に提供されるもの

  • シグナリングのためのマネージド型エンドポイント
  • STUN/TURNのマネージド型エンドポイント
  • 各種SDK

これらはすでに他社製の既存のWebRTCプラットフォームでも提供されており、ここにAmazonが乗り出した感じですね〜気になる流れ 👀

コスト

従量課金製で使用量にコストがかかる形です。WebRTCはシチュエーションによったり、ユースケースで通信料が大きく変わるので見積もりが結構難しかったりするんですが、比較的安価に見えます。具体例を見ている限り基本的には

  • 時間
  • クライアント数

が大きな変数となります。

試してみる

*ちなみにAWSの無料範囲外なので気をつけて下さい。

labからサンプルが公開されており、設定さえすればすぐに使えるようになっています。

言葉にすると簡単なんですが、

  1. 以下のようにチャンネルを作成
  2. 必要なtoken/userを作成して値をSDKに渡す
  3. アプリケーションをつくる

f:id:jumbos5:20200109181855p:plain

これだけ。WebRTCの闇は運用してからなのでこの辺が簡単なのはもはや当たり前な時代・・・

webコンソールにこんな機能があり、作成したチャネルのパフォーマンスをモニターできるのはいいなと思いました。

f:id:jumbos5:20200109184616p:plain

サンプルコードとSDKの実装、APIのドキュメントから何ができるかを見ていきましょう。

サンプルコード・SDK

READMEにほぼ概要はありますが、気になる箇所をピックアップしてみてみましょう。

// SDKからオブジェクトのイニシャライズ
const kinesisVideoClient = new AWS.KinesisVideo({
        region: formValues.region,
        accessKeyId: formValues.accessKeyId,
        secretAccessKey: formValues.secretAccessKey,
        sessionToken: formValues.sessionToken,
        endpoint: formValues.endpoint,
    });

// 自分で作ったチャネルを指定してここから配信する
const getSignalingChannelEndpointResponse = await kinesisVideoClient
    .getSignalingChannelEndpoint({
        ChannelARN: channelARN,
        SingleMasterChannelEndpointConfiguration: {
            Protocols: ['WSS', 'HTTPS'],
            Role: KVSWebRTC.Role.VIEWER,
        },
    })
    .promise();
const endpointsByProtocol = getSignalingChannelEndpointResponse.ResourceEndpointList.reduce((endpoints, endpoint) => {
    endpoints[endpoint.Protocol] = endpoint.ResourceEndpoint;
    return endpoints;
}, {});
// にあるようにWebRTCの基本通信概念であるICEを自身でハンドリングする必要がある
signalingClient.on('open', async () => {
...
signalingClient.on('sdpAnswer', async answer => {
...

ここから読み取れるのは

  • 配信はチャネルごとで基本的な話者(PeerIDなど)を指定するような概念はない
  • role {Role} "MASTER" or "VIEWER" があり、双方向配信はこれが前提
  • ICEを自分で裁く必要がある
  • IE以外はサポートしている
  • 実装はちゃんとWebRTCの知識がいる(よりコアに触れそう:小並感)

API Doc

絶対読みましょう。結構大事な制約とかが書いてあります。

  • Currently, a signaling channel can only have one master
  • A signaling channel can have up to 10 connected viewers

WebRTC Technology ConceptsとかはWebRTCに必要なことをシンプルな文章で登場人物とかをまとめてくれているので勉強になります。一方でこの記述を明記することは「フルマネージドなのはサーバの運用だけでICEをはじめとしたクライアント側の技術はラップしない、ちゃんと理解しろよ」っいうAmazonの優しさと切なさと心強さなので座して読みましょう。

サンプルコードではwebのコンソールからチャネルを作成していますが、リファレンスをみる限りhttpのエンドポイントも提供されており自身で増減させることが可能のようです。

テレビ会議システムで言えば作成されるルームごとにこのハンドリングをするようなイメージなので、webのコンソールだけだとかなりユースケース限られるなと思っていたのでさっと目を通すと良いです。

まとめ

全体的にWebRTCのコア機能に対して基本的なサーバサイドのマネージドサービスとそれを利用するための抽象度低いSDKとインターフェースを提供しています。 現状はまだ多機能とはいきませんが、AWS CloudTrailとの連携などクライアントのイベント管理と解析をできたり、単純にcloudwatchと連携できるのですでにインフラ基盤がAWSなら連携できるメリットがありますね。

ただユースケースとしてライブ配信や解析をベースとしたインターフェースになっているのとSDKの抽象度的に結構余力がないと導入できないと感じました。

ユースケース次第ではハマりますね。

それではハッピーフライデー。🍺

今更わかるPostman〜便利なAPI開発補助ツール〜

みなさん、今日も元気にAPI開発していますか?
最近社内勉強会で改めてPostmanについて説明したら
意外と機能を知らない人が多かったので
API開発で色々便利な機能満載のPostmanを
API Clientとしての機能をメインに紹介しようと思います。

Postman is 何?

Postman, Inc.が開発しているAPI開発コラボレーションツールです。
API Client機能やチーム開発の共有、MockServerの作成機能、自動テスト機能などがあります。
弊社ではローカルでの開発の振る舞いテストで主に使用しています。

インストール方法

mac(Homebrew-cask)

Homebrew-caskでインストール可能です。

$ brew cask install postman

mac & windows

www.getpostman.com

こちらのリンク先のDownload the Appをクリックしてダウンロードしてインストールしてください。

新規設定

f:id:dedekopon:20191213160428p:plain 画面左上の[New]をクリックして新規の設定を行う

f:id:dedekopon:20191213161311p:plain BUILDING BLOCKS

Request:新規でリクエストを作成する。
Collection:リクエストのフォルダを作成する。
Environment:Postman上の環境変数の設定を行う。

ADVANCED(ログイン後の機能)

API Documentation:ドキュメントを作成する。ログイン後のページで共有される。 Mock Server:リクエストのモックを作成する。
Monitor:自動テストの設定、パフォーマンスチェックを行う。

メイン画面

f:id:dedekopon:20191213163133p:plainAPI
APIの説明
APIのメソッド・URL
④リクエストの設定
⑤リクエストの設定詳細項目
環境変数設定
APIのリクエスト例
⑧クッキーの設定・別媒体でのリクエストサンプル

リクエストの設定

Params

APIのqueryパラメータとpathパラメータを設定する。
f:id:dedekopon:20191213164104p:plain pathパラメータはURL中に:param_nameで設定、queryパラメータは通常のGETパラメータなので?param_name=valueの形で定義する。
例えばhttp://example.com/test/:test_id/?param=testの場合は図のようになる。

Authorization

APIを使用する際に認証が必要な場合などに設定する。

Headers

リクエストのヘッダーの設定を行う。Authorizationにauthorizeヘッダーを設定している場合はこちらには不要です。

Body

リクエストのボディの設定を行う。

pre-request script & tests

f:id:dedekopon:20191213164914p:plain Intro to scripts | Postman Learning Center
リクエスト送信時に前処理、後処理を簡易的ですが実装できます。
以下にちょっとした一例を書いておきます。

  • 環境変数から保持しているトークンの有効期限を確認して、エラーを出すpre-request script
// 環境変数から値を取得する
var ttl = pm.environment.get("TOKEN_TTL")
var now = Date.now()
if (now > ttl) {
    // throw new Errorされた場合、処理はそこで止まります
    throw new Error("No available token set. Please set environment TOKEN and TOKEN_TTL")
}
var refresh = false
// レスポンスのステータスコードが200かチェックする
pm.test("Status code is 200", function () {
    pm.response.to.have.status(200);
    refresh = true
});

if (refresh) {
    // 環境変数のトークンを更新する
    console.log('token refresh')
    pm.environment.set("TOKEN", pm.response.json().token);
    pm.environment.set("TOKEN_TTL", Date.now() + (3600 * 1000));    
}

環境変数設定

f:id:dedekopon:20191213170830p:plain 環境変数の切り替えを行うことができます。
こちらで設定した値はpre-request script,tests

pm.environment.get("VALUE_NAME") // 取得
pm.environment.set("VALUE_NAME", "value") // 更新

のような形で操作できる他
{{URL}}/test/のようにURLやパラメータ中に{{VALUE_NAME}}の形で埋め込むことができます。

APIのリクエスト例

f:id:dedekopon:20191213171745p:plain APIのリクエスト例を保存することができ、簡単に呼び出すことができます。

別媒体でのリクエストサンプル

f:id:dedekopon:20191213172118p:plain CodeをクリックすることでPHP,Ruby,Goでの実装サンプルが確認することができます。
別の環境で確認するときなどにとても重宝します。

エクスポート

これらの設定は全てインポート・エクスポートすることが可能です。
弊社ではAPIのサンプルの共有用リポジトリを用意し、Git上で管理しています。

まとめ

  • Postmanは優秀なAPI開発補助ツール
  • ただリクエストを送るだけだと勿体無いので色々設定して使おう
  • ログインして使う場合はさらに便利機能が色々使えるよ

RDS Proxyでサーバレス捗りそうだと思いました

f:id:shino8383:20191205183647j:plain

おはようございます。レアジョブのHUNTER×HUNTER芸人こと、DevOpsチームのshinoです。 (前回の記事: EC2 Auto Scalingを導入する際のポイント - RareJob Tech Blog)

HUNTER×HUNTERAWSの知識をインプットするのが日課になっています。

今まさにAWS re:Inventが開催中です。来年は行きます。

この時期はAWSに関する大量の新サービス・アップデート情報が流れてくるのでキャッチアップが大変です。

今回はAWS re:Inventの中で発表があった情報の中で、個人的に熱いと思ったRDS Proxyについて触れたいと思います。

RDS Proxyとは

f:id:shino8383:20191205184022p:plain

RDS Proxyとは名前の通りRDSへの接続をプロキシするお方です。

RDS Proxyの主なメリットは以下のようになります。

  • RDSへの接続にコネクションプールを利用できる
  • RDS Proxyの利用にはSecrets ManagerかIAM認証を用いて接続するので、よりセキュアな認証を強制できる(推奨はIAM認証)

また、RDS Proxy自体は可用性を持ったマネージドなプロキシサービスなのでプロキシサーバの管理コストはこちらが持つ必要がありません。 移行コストについては、従来利用していたRDSエンドポイントをRDS Proxyが提供するエンドポイントに差し替えるだけで利用可能です。

クライアント側でコネクションプールを実装しなくていいってだけでも嬉しいです。

このようなサービスのRDS Proxyですが、私が初見で感じた感想は

「サーバレス捗りそう(小並感)」

でした。

LambdaとRDS(RDB)の話

話は変わりますが、LambdaとRDS(RDB)は相性が悪く、アンチパターンと言えます。

なぜ相性が悪いのでしょうか?

一般的にRDBは大量の接続要求をさばくのが苦手だからです

RDBがクエリを処理する際にかかるコストに比べ、TCP接続を確立するコストやDB側でコネクションを生成するコストが比較的高いため、 高負荷なワークロードでは"接続"にかかるコストでCPUやメモリを食いつぶしてしまうことが多いです。

そのため、アプリケーション規模が大きくなってきてRDBが悲鳴を上げ始めたらコネクションプーリングなどを用いて、DBへの接続にかかるコストを低くするなどの対処が取られるケースが多いかと思います。 ただし、コネクションをプールして利用するのにもメモリやCPUを使いますし、レスポンスタイムも遅くなることが多いのでRDBへの負荷が小さいうちは割に合わないと思います。

(RDBじゃないですがRedisでもコネクションプールを使わずにCPUリソースを食いつぶしてしまったことがあります。)

これがどうLambdaと関係あるかと言うと、

簡単にスケールしてしまうLambdaはコネクションプールを使うことができず、 Lambda->RDSを利用しようと思うと大量の接続要求を行ってしまいRDSが悲鳴をあげる、

という図です。 夜間のバッチ処理とかなら使えるとは思いますが、用法用量を守る覚悟が必要です。

また、RDS側がリソース的に耐えられたとしてもDBへの最大接続数の制限に引っかかってエラーとかも全然あります。

なので、サーバレスやろうぜってなってもRDS(RDB)をデータソースの候補にあげることができず、DynamoさんやElastiCache For Redisさんなどが使われる事例が多いと思います。

今回、RDS Proxyさんが降臨なさったのでLambdaからRDS使えるぞ!というのが

「サーバレス捗りそう(小並感)」

に繋がります。

終わりに

RDS Proxyの登場で、RDBMSの種類問わずにRDSをデータソースとしたアーキテクチャをサーバレスで構築することが可能になります。 控えめに言って熱いです。

現在はまだPreview版なのでMySQLとAuroraしか使えないですが、東京リージョンでもお試し頂けます。

隙あらば利用していきたいと思います。

そういう訳で我々は一緒に働く仲間を大募集しております。

少しでも興味のある方は以下からどうぞ!

👏採用/求人情報 | アピール | 未来の教育を作る人のマガジン インフラエンジニア(AWS)