13
4

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 5 years have passed since last update.

Serverless(2)Advent Calendar 2016

Day 6

普通のWebサイトをServerlessで作ってみた話

Posted at

Serverless(2)アドベントカレンダーの6日目の記事です。

なにげにQiita上には初投稿なのでお手柔らかにお願いします。
普段はQiita team使っているので、そっちと記事との共有ができれば良いのになーと小言を言ってみたり。。。

今回は、表題の通り、サーバーレスでWebサイト作った話です。

Webサイトの要件

  • ブログのようなサイト
  • 静的URLで配信したいが、動きとしては動的な部分もあり

実現してみた方法

API Gatewayでhtmlを返しただけ
※当初はコンテンツをAjaxで取ってくる形式にしてたのですが、クローラーさんの結果がうまく行かず、サーバーサイドレンダリングにしちゃいました

実装環境

  • Serverless Framework 0系
  • node.js 4.3
  • Typescript 1系

アーキテクチャ

スクリーンショット 2016-12-05 18.55.17.png

  • cloudfrontでパスを振り分け
    • 静的なコンテンツのみS3へ振り分け
    • 動的ページはAPI Gatewayに振り分けて、LambdaがRDSからデータ取得して、HTML形式に変換して返却

レスポンスの定義

下記のような設定でレスポンスでもってコントロール
※まだServerlessFramework 0系で実装しています。

s-function.json
"responses": {
        "400": {
          "statusCode": "400"
        },
        "503": {
          "selectionPattern": ".*Task timed out after .+ seconds",
          "statusCode": "503"
        },
        "404": {
          "selectionPattern": "(.|\\n)*\\\"status\\\"\\:\\s*\\n*\\s*\\\"notfound\\\"(.|\\n)*",
          "statusCode": "404"
        },
        "default": {
          "statusCode": "200",
          "responseParameters": {},
          "responseModels": {
            "text/html": "Empty"
          },
          "responseTemplates": {
            "text/html": "#set($inputRoot = $input.path('$'))$inputRoot.variableHTML"
          }
        }
      }

lambdaのコードの一部

lambdaのコードはtypescriptで実装しています。
vue-serverでレンダリングしてhtmlを返却しています。

handler.ts
var root = new Vue({
		template: htmlPage
	});

	root.$on('vueServer.htmlReady', function(html: string) {
		var htmlPretty = require('html');
		html = htmlPretty.prettyPrint(html, { indent_size: 2 , indent_caractor: '\t\t'});

		const $ = cheerio.load(html);

		$('title').text("ほげほげ");
		$('h1').text("ほげほげについて");

        var result = {
            variableHTML: $.html({decodeEntities: false})
        }   
        cb(null, <any>result);
	});

ハマりポイント

ENI作成処理によるタイムアウト
西谷さんが下記の記事で書いている通り、Lambda→RDSの通信で同じVPC内でもENI作成処理に数十秒かかる場合があるようで、
結構タイムアウトが頻発してました。
記事にもある通り、完全な解決策はないようですが、
5分ごとにポーリングする設定を入れたらほぼタイムアウトは出なくなりました。
http://qiita.com/Keisuke69/items/1d84684f0511a062e968

パフォーマンスが出ない
これはアーキテクチャに少し依存するのですが、cloudfrontとAPIGatewayを置いているので、デフォルトで数百ms × 2のレイテンシが発生しています。
※APIGatewayも内部的にCloudfront使っているため
ここの解決策は、今後キャッシュ戦略をどうとるのかにかかっているので課題です。

まとめ

突貫で記事書いたのでまとまりなくて申し訳ないです。
SEO条件なんだよーとか、前提条件をあまり書けてないですが、Serverlessを検討している方の参考になれば幸いです。

13
4
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
13
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?