【聴講メモ】Developers Festa Sapporo 2017

2017年11月10日(金)に開催されたDevelopers Festa Sapporo 2017を聴講してきました。

JavaOne 2017 フィードバック~今後のJava開発・運用のために知っておくべき事総まとめ~

伊藤 敬(日本オラクル株式会社)


2017/10/1~2017/10/5までサンフランシスコで開催されたJavaOne 2017の内容についてのお話し。
こういうクラスができてとかいう技術的な話しはほとんどなく、リリースサイクルとかオープン化な話が多かった。
Javaから離れて結構久しいので、何か軽量化されるぐらいしか知らなかったんですが、半年後にはJava10がリリースされるとかいう話しは結構衝撃的。

Java SE 9

▼過去最多の機能追加

20(Java7)→55(Java8)→91(Java9)
リリースが延びたのも要因の1つだそう…

▼リリースモデルの転換

従来
・OpenJDKとOracleJDKに機能差分がある
 私、これ聞くまでOpenJDK自体知りませんでした…

・機能リリースは2年に1度(ただし目標)

・それぞれの機能リリースごとの長期サポート
 Java8まではおおむね8年サポートしてるんだそう

・更新リリースは3か月ごと
 セキュリティパッチに加えて限定的機能更新も含まれていたそう

これから
・OpenJDKとOracleJDKに機能差分をなくしていく
 すぐにではなく徐々に的な雰囲気

・機能リリースは6か月に1度(固定)
 リリース日は決めて、そこに間に合った機能を載せていくイメージ
 次出るバージョンはJava10→11→12のナンバリング
 18.3→18.9→19.3と西暦年+月の組み合わせにしてたのが最近方針転換されるらしい

・長期サポートはOracleJDKのみ
 ここの話が、最近Javaから離れている自分にはよく理解できなかった。
 長期サポート(LTS:Long Time Support)は、6か月ごとの機能リリースではなく、その中の特定のリリース(おおむね3年ごと)が対象となると認識しました。
 それのスタートが2018年9月で、次の長期サポートターゲットが201年9月ということらしい。
 商用利用で頻繁にバージョンアップをしたくない企業向けなんですかね…

・更新リリースは3か月ごと
 セキュリティパッチのみで機能更新は含まない

▼転換期故の弊害

公式アップデート終了はJava10より9の方が早い
Java8:2018.9
Java9:2018.3
Java10:2018.9

今Java8を使っている場合は、次のターゲットは10にした方が良い

▼その他

Java8から後継バージョンへの自動更新は行われない

Java SE9の32bit版バイナリの提供予定はない
官公庁への影響は大きいだろうとのこと(実際説明に行って叱責を受けることが多いそう…)

jlinkを利用したパッケージングとデプロイ
 クライアントに入っているJREに依存しないアプリを作れるんだそう
 (Developers Festaなんだから、こういう話しをもっと聞きたかったですね…)

Java EE 8

▼JavaEEが抱える問題点
・軽量でない
・業界トレンドとのギャップ

▼Eclipse Foundationへの移管

Oracleはもう関わらないというわけではなく、仕様策定の主管をEclipse Foundationへということ。

Eclipseでの開発プロジェクト名はEE4J(Eclipse Enterprise for Java)

Other

▼fn.project.io
Java対応のFaaS(Function as a Service)
いわゆる、Oracleのサーバレスプラットフォームのようです

蛇足

じゃんけんでTシャツいただきましたw
Mサイズで自分には若干小さかったので妻へのプレゼントとなりました。

image.png

The State of Serverless Computing

西谷 圭介(アマゾン ウェブ サービス ジャパン株式会社)


昨年に続いての聴講。
序盤でサーバレスとは?に簡単に触れ、後はアーキテクチャパターンについての実用的なお話しでした。
西谷さんが使っていた、スライドが暗くなって、指し示した一部分だけが明るくなるアイテムが気になって途中から話半分でしたw

サーバレスとは?

コンピューティングの進化の中、未だ残る制限
物理サーバー

仮想サーバー(オンプレ)

仮想サーバー(クラウド)

と進化していく中で、サーバーの管理業務からは解放されていない

サーバーは管理しない方が簡単
ファンクションは短命
なので
・サーバレスはよりセキュア
・コストを抑えられる
 アイドル時の支払いなし
 ただし、実行回数の分は掛かる(コスト効率はいいが、何でもかんでも安くなるわけではない)

サーバレスは管理業務からの解放

アーキテクチャーパターン

・Web Application
・Backends
・Data Processing
 →一番使われるパターン(RealTime、MapReduce、Batch)
・Chatbots、Amazon Alexa
・IT Automation
 →一番ハードルが低い(CIなど)

ベストプラクティス

The Twelve-Factor App (日本語訳)

この中からいくつか出てきましたが、印象に残ったのは
・ステートレス
・開発/本番で一致した状態

この話の流れでLambdaについての技術的なお話し
・FUnctionのコンピューティングリソース設定
 メモリ設定の見極めが肝心

・コールドスタートとウォームスタート
 安定的にリクエストが来ていれば最初しかコールドスタートは発生しない
 コールドスタートのスピードを許容できないのであれば、Lambdaは正解ではない(使うな)

アンチパターン

▼AWS Lambda + RDBMS

・コネクション数の問題
・VPCコールドスタートの問題
・DynamoDBを使うべし

▼IP固定したがり問題

▼Serverless != Monitorless
・監視はちゃんとしよう

IoT 時代を生き抜くエンジニアに必要な技術とは

松下 享平(株式会社ソラコム)


こちらは別記事にまとめました。

以上

続きを読む

Serverless FrameworkでLambdaのコールドスタート対策を行う

この記事で扱うテーマ

AWS Lambdaで発生するコールドスタートを軽減させる為の対策を実施します。

前提条件

Serverless Framework でAWS Lambdaの開発を行っている事。

コールドスタート?

実業務でAWS Lambdaを使っている方なら分かると思いますが、AWS Lambdaにはコールドスタートという、Lambda関数のレイテンシが極端に悪化する現象が発生します。

コールドスタートは主に以下の原因で発生します。

  • 実行可能なコンテナが1つも存在しない時
  • 利用可能な数以上の同時リクエストが送信された時
  • コードや設定変更を行った時(デプロイを行った時)

このあたりに関しては既に詳しくまとめてある記事がありますので、リンクを共有させて頂きます。

対策

実行可能なコンテナが消えないように定期的にAWS Lambdaを実行する事でコールドスタートの可能性を軽減します。

自分で0から作っても良いのですが、 こちら で紹介されていた、serverless-plugin-warmup というPluginを利用すると楽なので、こちらを利用していきます。

導入方法

serverless-plugin-warmup の通りに進めていけば問題ありません。

はじめに npm install serverless-plugin-warmup --save-dev を実行してpackageのインストールを行います。

※ yarn を利用している場合は yarn add serverless-plugin-warmup --dev でインストールします。

pluginを読み込ませる設定を追加

serverless.yml に以下の設定を追加します。

serverless.yml
plugins:
  - serverless-plugin-warmup

IAM Roleの追加

以下の記述を追加します。

既に lambda:InvokeFunction の権限がある場合はこの手順は省略出来ます。

serverless.yml
iamRoleStatements:
  - Effect: 'Allow'
    Action:
      - 'lambda:InvokeFunction'
    Resource:
    - Fn::Join:
      - ':'
      - - arn:aws:lambda
        - Ref: AWS::Region
        - Ref: AWS::AccountId
        - function:${self:service}-${opt:stage, self:provider.stage}-*

定期実行の対象にしたい関数に warmup: true を指定

以下のように記述します。(helloを対象にする場合)

serverless.yml
functions:
  hello:
    warmup: true

これが基本ですが、他にも特定のstageの時だけ定期実行の対象にしたり、定期実行の時間間隔を調整(デフォルトは5分間隔で実行)したり出来ます。

詳しくは GitHub を見ると良いでしょう。

私の場合はデプロイ後に対象の関数を実行する prewarmtrue に設定しました。

serverless.yml
custom:
  warmup:
    prewarm: true

デプロイ

設定が終わったら serverless deploy を実行します。

デプロイ完了後、マネジメントコンソールでLambda関数の一覧を見ると、 [サービス名]-[stage]-warmup-plugin という関数が生成されている事が確認出来ます。

warmup-plugin
"use strict";

/** Generated by Serverless WarmUP Plugin at 2017-11-09T01:54:08.198Z */
const aws = require("aws-sdk");
aws.config.region = "ap-northeast-1";
const lambda = new aws.Lambda();
const functionNames = "[サービス名]-[stage]-[関数名]".split(",");
module.exports.warmUp = (event, context, callback) => {
  let invokes = [];
  let errors = 0;
  console.log("Warm Up Start");
  functionNames.forEach((functionName) => {
    const params = {
      FunctionName: functionName,
      InvocationType: "RequestResponse",
      LogType: "None",
      Qualifier: process.env.SERVERLESS_ALIAS || "$LATEST",
      Payload: JSON.stringify({ source: "serverless-plugin-warmup" })
    };
    invokes.push(lambda.invoke(params).promise().then((data) => {
      console.log("Warm Up Invoke Success: " + functionName, data);
    }, (error) => {
      errors++;
      console.log("Warm Up Invoke Error: " + functionName, error);
    }));
  });
  Promise.all(invokes).then(() => {
    console.log("Warm Up Finished with " + errors + " invoke errors");
    callback();
  });
}

serverless logs コマンド等で見てみると定期実行されている事が確認出来るかと思います。

まとめ

以上が serverless-plugin-warmup を利用したコールドスタート軽減対策でした。

これから正式に導入しようと考えているので、また知見が溜まったら何かで共有させて頂きます。

最後まで読んで頂きありがとうございました。

続きを読む

Serverless Tech Challengeに参加した

完全に個人の参加報告&感想となります。

Serverless Tech Challengeとは

サーバレス界隈としては国内最大級のイベントとなる Serverlessconf Tokyo 2017 の1日目に行われたワークショップの内のひとつです。
このワークショップでは参加者同士で1~3名のチームを割り振られ、そのメンバーで協力して出された課題に取り組むワークショップとなっています。

http://tokyo.serverlessconf.io/workshops.html

課題内容

ルール

  • 制限時間は17:00まで(開始は10:30ぐらい)
  • 原則としてAWSサービスのみで構築すること
  • 出された4テーマから1つ選んで構築すること
  • 下記の要素を必ず含むと
    • 認証機能(サインアップ/サインイン)
    • GUI(デザインは問いません)
    • 画像ファイルの取扱が可能(添付、共有など)

成果物として求められるもの

  • アーキテクチャ図
  • デモ
  • プレゼンテーション資料(工夫した点など)

表彰

  • AWS のソリューションアーキテクト(7名が当日来ていました)が独断でイケていると思ったチームを1チーム選出
  • 選出の観点は以下
    • アーキテクチャ
    • ライフサイクル管理(ロギング、モニタリング、CI/CD)
    • コスト
    • 耐障害性
  • 賞品は10万円分のAmazonギフトカード(チームに進呈)

選択するテーマ

下記から1つ選択して実装する
– 電子掲示板 (いわゆる電子掲示板、StackOverflowなどのスレッドがあるものをイメージ)
– SNS(Twitter、Facebook等のSNS)
– マッチングアプリ
– Chat(Slack等のチャットアプリ)

私のチーム

チームメンバー&選択テーマ

私は全13チームの中で#12のチームとして、2名1チームの1人として取り組みました。
#12のもうひと方は、インフラエンジニアの方で、普段はオンプレミスからAWSへの
移行作業を順次行っているメンバーとのことでした。
役割分担として相方にフロントエンドの構築(HTML/JavaScript/CSSは書けるとのこと)、私がバックエンドの
構築(API設計/DB設計/サーバサイドコード(Lambda)/CI&CDパイプライン/サーバサイドリソースのデプロイ)といった
役割分担をして進めました。

選択したテーマは「Chat」です。
短時間で構築するためには一番想像がしやすく、比較的現実的な感じがしたという理由です。
とはいえ、賞味7時間(昼休憩もその中で)でこれを作り上げるのはかなり過酷です。

構築の進め方

下記のような流れで進めていきました。
ポイントとしては、時間がかなり限られた中で取り組むため、
出来る限りインクリメンタルにアジャイル開発的に進めていこうというものです。

  1. 私のアカウントにIAMユーザを追加
  2. Cognito User Pool&Cognito Identity Pool(仮)をAWSコンソールから作成
  3. Webページ配置用S3バケット(仮)をAWSコンソールから作成
  4. フロントエンドからユーザ登録・認証フローを構築する
  5. CI/CDパイプラインを構築
  6. Cognito User Pool & Cognito Identity PoolをCloudFormationテンプレートで記述しCI/CDパイプラインに乗せてデプロイ
  7. 6で作成したCognitoに向け直す
  8. SwaggerにてAPI設計を行い、APIのデプロイを行う(もちろんCI/CDにて)
  9. モックを応答するLambdaをデプロイ
  10. メッセージ表示、投稿用のDynamoDBのデプロイとDynamoDBとのインテグレーションをするLambdaに修正
  11. APIを使ってチャット画面を表示、投稿する機能を構築
  12. 画像保存用S3バケットのデプロイ
  13. APIを画像投稿に対応するよう修正しLambdaも修正
  14. 画像投稿をできるようにUIを修正

ここまででタイムアップ
ちなみに、まだ時間があれば進めようとしていた流れは下記の通り、

  1. メッセージ画面に画像表示
  2. ルーム一覧を取得するためのAPIを追加
  3. ルーム作成APIを追加
  4. ルーム一覧を表示する
  5. ルーム作成画面を追加
  6. ルームに参加可能なユーザの制限等を行う

などです。

プレゼンテーション

プレゼンテーションは各チーム3分間で行います。
プレゼンテーション中は公正を期すために全員クローズドデスクトップとして発表を聞くこと
私のチームは所々の関係上最後の発表となりました。

発表時に使用した資料は下記
http://k1nakayama-docs.s3.amazonaws.com/ChatApp12.pdf

画像の投稿機能を実装中にタイムアップとなってしまったため、投稿機能自体がうまく動かないままとなってしまいました。

結果発表

各チームのプレゼンテーションが終了し、20分間の休憩の間にAWSのSAによる審査が行われました。
その後、結果発表です。

なんと画面には #12 と表示され私達のチームの優勝が決まりました!
これはめちゃくちゃ嬉しかったです。

優勝賞品としてチームに10万円分のAmazonギフト券が渡され、2人のチームだったので、
仲良く5万円分ずつ分けました。
IMG_0618.jpg

評価としては、

  • アーキテクチャとしては至ってオーソドックスではある
  • 課題として出された条件を全て網羅している
  • 完成度が平均的によい
  • 全チームの中で唯一DynamoDBオートスケーリングなどを取り入れており、キャパシティマネジメントなどの点も考慮されている
  • SAによる評価の全会一致で選出された

ということでした。

感想&印象に残ったもの

今回のワークショップは、AWSではたまに見かけるGame Dayと似たような取り組みでしたが、
Game Dayも参加したことなかったため、とっても新鮮でした。
そして、普段からサーバレスに触れているものの、色々な発見がありとても参加した甲斐があったと思います。
(賞味7時間で死に物狂いで取り組めば、一応これぐらいはできるのかという気づきにもなりました(^_^;))

まず、すごく気付かされたものは、チームワークというか、構成メンバーって本当に大事で、
今回の場合、私のチームは2人だったものの、ほぼほぼ経験の多い分野が分かれていたのもあり、
それぞれが取り組むべきところを自分で考えて取り組むことも出来たので、時間短縮に繋がったと思います。
また、この手の開発はやはりとにかく小さな目標を積み重ね、インクリメンタルに成果を積み上げていくことが良いということも再確認出来ました。

他のチームのアーキテクチャとして印象に残ったものは、
同じチャットアプリに取り組んでいたチームが、
メッセージ投稿のアーキテクチャについてAPI Gatewayを使わず、
JavaScript(フロントエンド)→ SNS → Lambda → S3
というものをベースに作っていました。
ある意味一昔前のアーキテクチャだと思いますが、ユニークな発想でこういう発想も普段から持っておくと
柔軟に取り組めるかもなぁと思いました。

その他、マッチングアプリのチームは、ほぼ必須でAmazon Rekognitionを使用して画像の中の写真に対する
プロパティによるマッチングを考えていました。
世の中本当にAIの時代だなぁと考えさせられました。
このあたりのAI系サービスはあまり知見が少ないので、今後はこのようなサービスも積極的に使っていきたいなぁと思います。

続きを読む

Serverless FrameworkでExpressを動かす(serverless-httpを使用)

Serverless Frameworkの公式ブログで Deploy a REST API using Serverless, Express and Node.jsという記事を見つけたので、この記事で紹介されているserverless-httpとういミドルウェアを使って、Serverless上でExpressを動かしてみました。

環境

 $ sw_vers
ProductName:    Mac OS X
ProductVersion: 10.12.6
BuildVersion:   16G29
$ node -v && npm -v
v8.8.1
5.4.2

手順

AWS CLIの事前設定とserverlessのインストール

AWS CLIをインストールし、認証情報を登録しておきます。
AWS – Credentials を参考に、使用するAWSアカウントの情報をDefaultプロファイルに設定します。

serverlessをグローバルにインストールしておきます。

$ npm install serverless -g

ココらへんは、以前書いた記事 (serverlessでLambdaのローカル開発環境を整える)でも紹介していますので、こちらを参照してください。

プロジェクトを作成

$ mkdir serverless-express-sample
$ cd serverless-express-sample
$ npm init -f

必要なパッケージのインストール

今回は、次のnpmパッケージを使用します。
* express
* serverless-http

serverless-httpはLambdaでexpressのようなhttpをルーティングするソフトウェアを使用できるようにするミドルウェアです。

$ npm i -S express serverless-http

サンプルAPIの作成

//hogeにアクセスすると、それぞれ違った文字列をjsonで返す簡単なAPIを作成してみます。

まずは、serverlessコマンド(エイリアス: sls)でnodejsベースのプロジェクトを作成します。

$ sls create --template aws-nodejs --name serverless-express-sample 

次に、追加されたhandler.jsを次のように変更します。
Expressを使ったことがあれば、見慣れた内容だと思います。

handler.js
'use strict';

const serverless = require('serverless-http');
const express = require('express');
const app = express();

app.get('/', function (req, res) {
  res.json({ message: 'Hello World!' });
});

app.get('/hoge', function (req, res) {
  res.json({ message: 'Hello Hoge!' });
});

module.exports.main = serverless(app);

serverless.ymlは次のように変更します。

eventsには、全てのpath、全てのhttpリクエストをAPI Gatewayの機能のLambda Proxy IntegrationでExpress側に渡すための設定を記述しています。

serverless.yml
service: serverless-express-sample

provider:
  name: aws
  runtime: nodejs6.10
  stage: dev
  region: ap-northeast-1

functions:
  app:
    handler: handler.main
    events:
      - http:
          method: ANY
          path: '/'
      - http:
          method: ANY
          path: '{proxy+}'

デプロイ

作成したサンプルAPIをデプロイします。

$ sls deploy

動作確認

デプロイ結果のendpoints:に表示されているエンドポイントにブラウザからアクセスしてみると…
次のように、Expressからjsonレスポンスが返ってくることが確認できるかと思います。

スクリーンショット 2017-10-29 17.26.06.png

スクリーンショット 2017-10-29 17.26.10.png

また、WappalyzerというChrome Extensionで確認してみると、Expressが動いていることが確認出ます。

スクリーンショット 2017-10-29 17.26.35.png

参考

https://serverless.com/blog/serverless-express-rest-api/

続きを読む