この記事はDMM.com #2 Advent Calendar 2017 - Qiitaの9日目です。
カレンダーはこちら
DMM.com #1 Advent Calendar 2017 - Qiita
DMM.com #2 Advent Calendar 2017 - Qiita
はじめに
こんにちは、@funa1gと申します。
社内で共通で利用されるAPIなどの開発をやっています。
技術選定のために、AWSについても色々と試しています。
今回は、その中でAWS LambdaとVPCをつないだ、アンチパターンについてです。
全体の構成
API Gateway + LambdaでAPIを作成する時、RDSにアクセスしたい場合があります。
しかもRDSとなるとやっぱりVPC内に置きたいです。
この組み合わせがアンチパターンなのは、すでに色々検証記事が出ていますが、
多少遅くても動くなら許せるかなと思って、検証してみました。
動作テスト
雑に動けばいいので、こんなエンドポイントにしました
レスポンスはDB内のデータです
METHOD: GET
URL: /LambdaTest
Response
[
{
"id": 1,
"name": "test1"
},
{
"id": 2,
"name": "test2"
}
]
Lambda側のコードも、DBにアクセスして、JSONを返すだけです
const { Client } = require('pg');
exports.handler = (event, context, callback) => {
// 接続先のPostgresサーバ情報
const client = new Client()
client.connect()
client.query("SELECT * FROM test", (err, res) => {
if (err) throw err
client.end()
callback(null, res.rows)
})
};
負荷テストにはGatlingを使いました。
利用したコードは以下です。
setUp(
scn.inject(
// 50人のアクセスを40秒間継続
constantUsersPerSec(50) during(40 seconds)
)
).protocols(httpConfig)
これでテストの準備は整いました。
あとは実行結果を待つだけです。
テスト結果
上記の設定でテストした結果が以下になります。
---- Global Information --------------------------------------------------------
> request count 2000 (OK=1839 KO=161 )
> min response time 0 (OK=144 KO=0 )
> max response time 57613 (OK=57613 KO=0 )
> mean response time 471 (OK=512 KO=0 )
> std deviation 2902 (OK=3023 KO=0 )
> response time 50th percentile 259 (OK=262 KO=0 )
> response time 75th percentile 279 (OK=281 KO=0 )
> response time 95th percentile 454 (OK=479 KO=0 )
> response time 99th percentile 1304 (OK=1410 KO=0 )
> mean requests/sec 20 (OK=18.39 KO=1.61 )
---- Response Time Distribution ------------------------------------------------
> t < 800 ms 1802 ( 90%)
> 800 ms < t < 1200 ms 1 ( 0%)
> t > 1200 ms 36 ( 2%)
> failed 161 ( 8%)
---- Errors --------------------------------------------------------------------
> j.u.c.TimeoutException: Request timeout to not-connected after 161 (100.0%)
60000 ms
================================================================================
いくつか問題がありますね。
- かなり遅いレスポンスが一部発生している
- タイムアウトが発生している
何度か試しましたが、1700前後のシナリオを実行したところで、処理ができなくなっていました。
実行側の問題なのか、AWS側の問題なのかまで確認できず。
そこの検証を続けていたんですが、わからないまま、日付が変わりそうなので(12/9 22:00)、一旦の結果を放流です。
寂しい結果になりましたが、検証だとこういうこともありますね。
引き続き調査は続けて、わかったら追記したいと思います。
二ヶ月ほど前に試した際には、300ユーザーのアクセスを60秒間ほどやることで、API GatewayとVPC間のENIを限界(300)まで到達させることができたのですが、そこまでたどり着きませんでした。
http://docs.aws.amazon.com/ja_jp/lambda/latest/dg/vpc.html
実際にそうなると、この記事の一番下のような現象が発生します。
ENIがこれ以上作成できないため、Lambdaの起動ができず、その分が全て失敗します。
しかも、CloudWatchにログが出ないので、かなり厳しいです。
やはりアンチパターンはアンチパターンですね。
最後に
さて、AWS側からアンチパターンということになっているのは、それなりの理由があることがわかりました。
今後もこの方法は取れないかというと、まだわからないかと思っています。
先日のre:InventでAPI Gateway VPC integrationが発表されました。
これはAPI GatewayからVPCのリソースにアクセスする手段を提供したものです。
アーキテクチャの問題上、Lambdaには明示的なエンドポイントがあるわけではないので、現状はアクセスできません。
しかし、VPCへのアクセス手段が用意されたということで、展開に希望が持てないかなと考えています。
今後の発表が楽しみなところです。