AWS CloudFrontとLambda勉強まとめ

CloudFront

CDN
– Contents Delivery Network
– エッジのキャパシティを利用して効率的かつ高速にコンテンツ配信
→ユーザに最も近いサーバに誘導して、配信を高速化
→エッジサーバではコンテンツのキャッシングを行い、オリジンに負荷をかけない

・最適なエッジへの誘導方法
①ドメイン名問い合わせ(クライアント→DNS)
②IPアドレス問い合わせ(DNS→CloudFrontDNS)
③最適なEdgeアドレス応答(CloudFrontDNS→DNS)
④最適なEdgeへアクセス(クライアントからEdge)
⑤キャッシュがある場合:コンテンツ配信
キャッシュがない場合:オリジンサーバから取得

・CloudFront特徴
– 84拠点のエッジサーバ
– 予測不可能なスパイクアクセスへの対応
– ビルトインのセキュリティ機能(WAF連携、DDoS対策)
– 充実したレポート

・動的コンテンツ:ELBでEC2に負荷分散。HTML
静的コンテンツ:S3などで保存

・84エッジロケーション→11リージョナルキャッシュ→オリジン
→オリジンに対するコンテンツ取得を削減

CloudFront Distribution
– ドメインごとに割り当てられるCloudFrontの設定
– 40Gbpsもしくは100,000RPSを超える場合上限申請必要
– HTTP/2対応
– IPv6対応
– CNAMEエイリアスを利用して独自ドメイン名の指定可能
→Route53と合わせたZone Apex(wwwがないもの)も利用可能

Gzip圧縮機能
エッジでコンテンツをGzip圧縮することでより高速にコンテンツ配信
※S3はGzip圧縮をサポートしていないので有効

キャッシュコントロール
– キャッシュヒット率の向上がCDNのポイント
→URLおよび有効化したパラメータ値の完全一致でキャッシュが再利用

キャッシュの無効化
コンテンツごとの無効化パス指定

ダイナミックコンテンツ機能
オリジンサーバに対して下記情報をフォワードすることで、動的なページの配信にも対応
– ヘッダー(必要最小限)
– Cookie(Cookie名と値をセットでCloudFrontがキャッシュ)
– クエリ文字列パラメータの値

ダイナミックキャッシング
リクエストパターンをもとにオリジンへのアクセスルールを個別指定可能

カスタムエラーページ
4xx系:クライアントエラー。オリジン側で対処
5xx系:サーバエラー。CloudFrontで対処
参考URL:https://goo.gl/NcUQiY

読み取りタイムアウト
CloudFrontがオリジンからの応答を待つ時間を指定
デフォルトは30秒

キープアライブタイムアウト
接続を閉じる前に、CloudFrontがオリジンとの接続を維持する最大時間
デフォルトは5秒

・セキュリティ
– HTTPS対応
– SSL証明書
→専用IPアドレスSSL証明書には申請必要
ビューワーSSLセキュリティポリシー
→クライアントとCloudFront間のSSL/TLSプロトコルとCipherの組み合わせを指定可能
– オリジン暗号化通信
– オリジンカスタムヘッダー
GEOリストリクション
→地域情報でアクセス判定。制御されたアクセスには403を応答
署名付きURL
→プライベートコンテンツ配信。
→署名付きURLを生成する認証サイトにクライアントから認証リクエスト
→認証サイトからEdgeにアクセス※署名付き出ない場合は、403を返す
-オリジンサーバーの保護
→Origin Access Identitiy(OAI)を利用
S3のバケットへのアクセスをCloudFrontからのみに制限
– AWS WAF連携
AWS ShieldによるDDoS攻撃対策
ブロック時は403応答
– AWS ShieldによるDDoS攻撃対策
デフォルトで有効

・CloudFrontレポート・アクセスログ機能
任意のS3バケットに出力可能

・CloudWatchアラームの活用
リアルタイム障害・異常検知

・S3オリジン自動キャッシュの無効化(Invalidation)
S3にアップロード→Lambdaファンクション呼び出し→CloudFront Invalidation APIの呼び出し→CloudFront上でキャッシュの無効化

Lambda

高度にパーソナライズされたウェブサイト
ビューワーリクエストに応じたレスポンス生成
URLの書き換え
エッジでのアクセスコントロール
リモートネットワークの呼び出し

参考URL:https://www.slideshare.net/AmazonWebServicesJapan/aws-blackbelt-online-seminar-2017-amazon-cloudfront-aws-lambdaedge

続きを読む

AWS S3勉強まとめ

ブロックストレージ
EBS, インスタンスストア
→EC2にマウントして活用
→Block番号で管理

オブジェクトストレージ
S3, Glacier
→安価かつ高い耐久性を持つオンラインストレージ
→オブジェクト、それに付随するメタデータ、そのオブジェクトにアクセスするためのユニークなIDで構成

ファイルストレージ
EFS
→EC2から同時マウントできる共有ストレージサービス
→ファイルシステム

・S3特徴
→容量無制限、安価なストレージ(1GB3円)、データ容量に依存しない性能(RAIDやサーバー台数を考える必要なし)

・S3用途
①コンテンツ配信、保管サーバ
②ログ&データハブストレージ
③バックアップやDR

バケット
オブジェクトの保存場所。デフォルト100個/1アカウントまで作成可能。名前はグローバルでユニークな必要あり。
オブジェクト
データ本体。URLが付与される
キー
オブジェクトの格納URL
メタデータ
オブジェクトに付随する属性情報。システム定義メタデータ、ユーザ定義メタデータあり
リージョン
バケットを配置するAWSのロケーション
アクセスコントロールリスト(ACL)
バケットやオブジェクトのアクセス管理

・ストレージクラス
スタンダード
標準低頻度アクセスストレージ:スタンダードに比べて安価だが、データの読出し容量に対して課金
Glacier:最も低コスト。データの取り出しにコストと時間
低冗長化ストレージ:Glacierから取り出したデータの置き場所として利用

結果整合性(Eventual Consistency Readモデル)
「更新はそのうち全体に反映される」
読み取り一貫性
– あるトランザクションがデータを変更中のとき、ほかのトランザクションからは変更される前のデータを参照します。
– ほかのトランザクションからは変更前の確定されたデータを参照します。
– あるユーザーAが値をUPDATEしたとき、ユーザーBがそのデータを参照すると、戻ってくる値はUPDATE前の値となります。
– あるトランザクションで変更した確定前のデータをほかのトランザクションから参照することはできません。

・パソコンのファイルシステムやデータベースと同じようにロックやトランザクション処理は行われない
参考URL:https://dev.classmethod.jp/cloud/amazon-s3-eventually-consistent-and-consistent-read/

・アクセス管理
①ユーザポリシー
→IAMuserに対して権限設定
②バケットポリシー
→バケットごとに権限設定。クロスアカウントで使用する際など
③ACL
→バケット、オブジェクトごとに指定可能(オブジェクトACLが優先)

署名付きURL
AWS SDKで作成。S3のプライベートなオブジェクトに対して一定時間アクセスを許可

・Webサイトホスティング機能
静的なWebサイトをS3のみでホスティング可能
– バケット単位で指定
– 独自ドメインの設定→ドメイン名をバケット名として指定
– リダイレクト機能→任意のドメインにリダイレクト設定が可能
CloudFrontとの経由で配信することを推奨。バケットポリシーでHTTP/HTTPSリクエストのみを許可可能

VPCエンドポイント
プライベートサブネットからNATゲートウェイなどを経由せずに直接S3とセキュアに通信可能
同一リージョンのみ

S3 support for IPv6
追加費用なし
静的ウェブホスティングは使用不可

・暗号化
– サーバーサイド暗号化(サーバリソースを利用して格納データの暗号化)
– クライアントサイド暗号化(クライアント側で暗号化したデータをS3にアップロード)

クロスリージョンレプリケーション
異なるリージョン間のS3バケットオブジェクトのレプリケーションを実施
→オブジェクトに対する動作を非同期でレプリケーション
→対象元バケットはバージョニングの機能を有効にする必要あり
※リージョン間データ転送費用が発生

バージョン管理機能
誤操作による削除対策に有効
バケットに対して設定
任意のオブジェクトを参照可能
バージョニングのオブジェクト分も課金。保存期間も指定可能

ライプサイクル管理
バケット内のオブジェクトに対して、ストレージクラスの変更や、削除処理の自動化
データ登録→Standard保存(一定期間過ぎたら削除)→Standard-IA移動(一定期間過ぎたら削除)→Glacierにアーカイブ(一定期間過ぎたら削除)

・アーカイブ
S3上のデータを削除でGlacier側のデータも削除
S3には8KBのオブジェクト名とメタデータのみ保管

・復元
オブジェクトごと
一時的にS3の低冗長化ストレージに指定日数複製(Glacierと低冗長化ストレージ両方課金)
復元にかかる時間の選択肢は3つ
①Expedited:緊急のアクセス
②Standard:3-5時間。標準的
③Bulk:大量のデータ。5-12時間
それぞれによってコストが異なる

・オブジェクト移動
Standard⇔Standard-IA→Glacier
→Glacier

S3分析
Standard-IAとGlacierどちらにいつ移動すればいいだろうかという疑問に答える可視化ツール
→ライフサイクルポリシーの設定値の参考になる

S3インベントリ
S3のオブジェクトのリストを一気にcsvファイルで取得
スケジュールかも可能

・イベント通知
SNS:メール送信
SQS:キューメッセージの登録
Lambda:ファンクションの実行

・CloudWatchによる監視
ストレージメトリクス:バケット単位。1日単位でのレポート。追加費用なし
リクエストメトリクス:オブジェクト単位。通常のCloudWatch料金

CloudTrailによるAPI(操作ログ。Get, Delete, Putなど)管理
S3への操作ログを収集
監査対象とは別のS3バケットの用意推奨

Logging
バケットに対するアクセスログの出力設定可能

Tag管理
バケット/オブジェクトに対してタグの指定可能

・パフォーマンスの最適化
大きなサイズのファイルをアップロード、ダウンロード
RANGE GETを活用。マルチパートアップロード機能
大量のGETリクエストが発生する場合はCloudFrontを併用することを推奨

Transfer Acceleration(高速ファイル転送サービス)
AWSのエッジネットワークから最適化されたAWSのネットワークを経由する。
S3のデータ転送コストとは別に加算
※通常の転送より高速でない場合は、課金されない

コンテンツ配信サーバ
データをS3に配置、CloudFrontでキャッシュさせる
CloudFrontで静的コンテンツ配信。CloudFrontの料金はかからない
Webサーバーで動的コンテンツは処理

ログ&データハブストレージ
オンプレ:Direct Connectでログデータ収集
外部データソース;Kinesisで収集
AWS;S3に保管。Glacierにアーカイブ
分析:Redshift, EMR, Atenaなど

バックアップ、DR
クロスリージョンでデータの複製を保持
リージョン内でもDR設定

参考URL:https://www.slideshare.net/AmazonWebServicesJapan/aws-black-belt-online-seminar-2017-amazon-s3

続きを読む

AWS Auto Scaling勉強まとめ

・需要に応じて自動的にサーバーが増減し、コストカット

Auto Scaling Group
・設定した最小値~最大値に起動インスタンスを収める
・起動台数をAZ間でバランシング
・AZ障害時は他のAZでインスタンス起動

Launch Configuration
・AMIやインスタンスタイプ、IAMなどを設定して起動する

Scaling Plan
・どのようにインスタンスを起動するか
①Auto Scaling Planの維持
最小台数を維持する。
Auto Healing:インスタンスに障害発生時に自動的にサービスから切り離し、健全なインスタンスをサービスイン

②手動管理
インスタンスを手動で変更

③スケジュールベース
CLI/SDKで定義
スケーリング開始は最大2分遅れる場合があるので注意

④動的スケーリング
監視:CloudWatchに応じたインスタンスの増減

上記の複数のプランを組み合わせることも可能

ヘルスチェック
①EC2ヘルスチェック:インスタンスのステータスがrunning以外を以上と判断
②ELBヘルスチェック
・ヘルスチェックの猶予期間がある。インスタンス起動からヘルスチェック開始までの時間。アプリケーションデプロイを考慮
・異常と判断されたインスタンスは自動的に終了

クールダウン
スケーリングアクション実行後指定した時間は次にスケーリングアクションを実行しない仕組み
→インスタンス初期化中の無駄なスケーリングを回避するため
※シンプルスケーリングポリシーにのみ対応

ターミネーションポリシー
①OldestInstance/NewestInstance:起動時刻
②OldestLaunchConfiguration:最も古いLaunch Configuration
③ClosestToNextInstanceHour:課金のタイミングが近い
④Default:②③の順に適用。複数インスタンスが残ればランダム

インスタンス保護
任意のインスタンスを削除されないよう保護できる

・インスタンスのデタッチ、アタッチ、スタンバイ

ライフサイクルフック
Auto Scalingの起動/終了時に一定時間(デフォルトは1時間、最大48時間)待機させ、カスタムアクションを実行できる

・スケールアウト時の初期化処理
①設定済みのAMIを用いる
②user-dataで初期化スクリプトを実行(Bootstrap処理)
③ライフサイクルフックで初期化

・サーバーをステートレスにする
ステートレス:サーバーにセッション情報などがない。スケールアウトに向いている
ステートフル:サーバーにセッション情報あり。常にサーバー間で同期が必要なので、スケールアウトに向いていない

・突発的なスパイクには向いていない
→インスタンス作成~アプリ起動の時間がかかるため。
対応策としては、
①CloudFrontなど大きなキャパシティを持ったAWSサービスに処理をオフロードする
②スパイクを裁くのを諦め、スロットリング機能(処理性能の上限)を設ける
③一定以上の負荷を超えたら静的ページに切り替える

・ユースケース
①ELB配下のWebサーバーをAuto Scaling
→EC2は複数AZに分散し、高可用性
ELBのリクエスト数、EC2の平均CPU使用率などがトリガー

②SQSのジョブを処理するWorkerをAuto Scaling
キューのメッセージ数などがトリガー

③Blue/Green
Blue/Green
デプロイ時に、既存のインスタンスとは違うインスタンスを作成し、一気に/徐々に作成したインスタンスを使用するようにする。
移行方法は下記
・DNSのWeighted round robinを使用して、徐々にトラフィックを移行
→DNSのTTLを考慮する必要あり。
・ELBを利用して、移行する
→Elastic Container Service(ECS。Dockerコンテナを格納する場所)を利用して、新しいインスタンスを作成することも可能

In place
デプロイ時に既存のインスタンスを操作することで対応する

参考URL:http://aws.typepad.com/sajp/2015/12/what-is-blue-green-deployment.html

Elastic MapReduce(EMR)

<Hadoop(分散処理をしてくれるソフトウェア)を動かせる環境を提供してくれるサービス
参考URL:http://mgi.hatenablog.com/entry/2014/05/04/085148

参考URL:https://www.slideshare.net/AmazonWebServicesJapan/aws-black-belt-online-seminar-2017-auto-scaling

続きを読む

Rails + AWS でモバイルフレンドリーな動画配信サイト構築 – メドピア開発者ブログ

2018 – 01 – 18 Rails + AWS でモバイルフレンドリーな動画配信サイト構築 Rails HLS ElasticTranscoder S3 Cloudfront WAF Tweet Share on Tumblr あけましておめでとうございます。 メドピアのSRE @kenzo0107 です。 2018年もよろしくお願いします。 今回は昨年リニューアルした動画配信システムについ. 続きを読む

「Microservices Meetup vol.6」に行ってきた

2017/1/19のデイリーストックランキングにランクインしました。

【毎日自動更新】Qiitaのデイリーストックランキング!ウィークリーもあるよ_-_Qiita.png


いままでの。
「Microservices Meetup vol.2」行ってきたメモ。
「Microservices Meetup vol.4」に行ってきた

図らずして1回おきに参加してますね。

Connpassのイベントページ

少し間が空いてしまったがまた定期的に開催していきたいです。
登壇したいよーって人は直接リプ投げてください
by @qsona さん

Microservices on AWS by @Keisuke69 さん

Keisuke Nishitani @ AWS

Specialist Solutions Architect

サーバーレスアプリケーション開発ガイド 2月発売

マイクロサービスのポイント

  • 管理運用まで含めて分散型
  • 各コンポーネントが独立している
    • 単独で実行できないのは適切に設計されていない

独立して分散していると負荷の高い機能の単位でスケールさせられる=コスト効率が良い

  • 一つのことをうまくやる

    • 複雑化したら分割する
  • 多言語

    • チーム(機能)にはそれぞれの問題に対して適切なツールを選択する自由がある
    • OS、言語、各種ツールに至るまで最適なアプローチを目指せる
  • 検索:Elasticsearch / Solr

  • ソーシャル:グラフDB

  • ログデータ:Cassandra

  • セッション:Redis

†AWSでは:AWSには100ちょいのサービスがあって、その中で更にチームが分かれている。
各チームに社内標準の開発プロセスは存在しない。

  • ブラックボックス

    • 詳細は外部のコンポーネントに公開されない
  • DevOps
    • マイクロサービスにおける組織原理

†AWSでは:運用のみのチームはない。オンコールも開発チームが請け負う

  • 俊敏性

    • 狭い範囲のコンテキストで活動=サイクルタイムが短い
    • システムもシンプル
    • パラレルな開発とデプロイが可能
  • イノベーション

    • 選択に対する権限と責任を持つのでイノベーションを起こしやすい
    • DevとOpsの対立がないため、効率化やイノベーションが起こしやすい
  • 拡張性

    • 適切に非干渉化されてていることで水平方向に単独にスケールできる
  • 可用性

    • ヘルスチェック、キャッシング、隔壁、サーキットブレーカーと言った仕組みは全体の可用性を向上させる

課題

  • 分散型であることは難しい

    • システム数が増える
    • 協調動作の難しさ
    • コンポーネント間のコミュニケーションメッセージ増によるレイテンシ低下
    • ネットワークの信頼性は無限ではない、帯域も無限ではない
  • 移行が大変
    • モノリシックなシステムの分割は難しい
  • 組織
    • 組織体制の変更が必要になるが、それは大変なこと
  • アーキテクチャの難易度
    • 非同期通信
    • データ整合性
    • やっぱりココが一番の課題
    • サービスディスカバリ
    • 認証
  • 運用の複雑さ

アーキテクチャ

一番シンプルなパターン

CloudFront – ALB – ECS – datastore(ElastiCache, Dynamo, )
|
S3

  • バックエンドをRESTfulなAPIにしたSPA
  • 静的なコンテンツはS3とCloudFront
    • CDN通すことでレイテンシが上がることもある
    • キャッシュとの併用を検討
  • ECSとAutoScalingをALBとともに使うことが多い
    • ALB(L7LB)でアプリレベルの情報をルーティング
    • コンテナインスタンスにリクエストを分散
    • ECSのコンテナを負荷に応じてスケールアウト/インする

コンテナのメリット

  • Portable
  • Flexible
  • Fast
    • 軽量で早い
    • ポータビリティと関連して開発サイクルも早く
  • Efficient

  • 一貫性のある環境

  • バージョン管理出来る

Dockerの特徴

  • Package
  • Ship
  • Run

ECS

  • 複数のコンテナをEC2のクラスタ上で一元管理

    • まだTokyoにきてないけど、FargateでEC2の管理もいらなくなるよ
    • EKS(Kubernetes)も発表されています

データストア

  • インメモリ

    • Memcached, Redis
    • ElastiCache
    • DB負荷の軽減
  • RDBMS
    • 無限のスケーリングには向いていない
    • Amazon RDS
  • NoSQL
    • 水平スケーリングをサポートするものが多い
    • テーブル結合ができないのでロジックの実装が必要になる場合も
    • Amazon DynamoDb, KynamoDB Accelarator(DAX)

APIの実装

  • APIの設計、改善、デプロイ、モニタリング、保守派手間がかかる
  • 異なるバージョンが混在すると大変

Amazon API Gateway

  • 複数バージョンとステージ
  • Cognite User Poolsと連携して認証を追加
  • スロットリング、モニタリング
  • バックエンドとしてLamdbaが使える

サーバーレス

  • サーバーはないに越したことはない
  • スケーリングと高可用性の担保が大変
CloudFront - API Gateway - Lamdba - datastore
   |                            (ElastiCache, Dynamo)
   |
  S3

課題をAWSでどうするか

サービスディスカバリ

  • お互いの死活確認や発見
  • ハードコードするとスケールできない

    • メタデータをどこに置くか
  • ALBを利用したサービスディスカバリ

  • DNS(Route53)のサービスディスカバリ

    • VPC単位の振り分け
  • ECSイベントストリームを使用したサービスディスカバリ

    • CloudWatchイベントで拾ってキック
    • LamdbaでRoute53に登録
    • これが一番多いかも
  • DynamoDBを使用したサービスディスカバリ

    • DNSキャッシュの問題がない
    • 自由度が高い
    • 実装が大変
    • DynamoDBストリームを活用して他のサービスへステータス変更を反映
  • イベントベースのアーキテクチャ

    • イベントで処理する
    • いわゆる結果整合性とも関連
    • Dual Write Problem
    • Event Sourcing
      • 状態の記録ではなく状態の変更「イベント」を記録
      • Amazon Kinesis
      • kinesisにpublishして他サービスはsubscribe
      • S3にログを残す
      • トランザクションログの仕組み

モニタリング

  • CloudWatch

    • ログファイルの一元化
    • CloudWatch LogsかS3に保存可能
    • ECSはCloudWatch Logsに一元化できる

分散トレース

  • AWS X-Ray
  • 複数サービスに分散したリクエスト処理を透過的に追える

LogWatchの先に Kinesis FireHorse – ほにゃほにゃ

スロットリング

  • 大事だよ

リトライ

  • 多くのエラーはリトライでカバーできるものが多い
  • リトライ多発で過負荷になることがある
    • Exponential back offもしくはフィボナッチ数列を利用したリトライ感覚の調整
    • 更に乱数でゆらぎを付けて重ならないように

LT:クラウド型医療系業務システムと Microservices への歩み by @hashedhyphen さん

https://speakerdeck.com/hashedhyphen/kuraudoxing-dian-zi-karutesisutemuto-microservices-hefalsebu-mi

クラウド型電子カルテシステムの話

  • メインロジックをRails
  • 常時接続をNode.js
  • バックエンドをScala
  • 基盤はAWS

ここに至る道のり

ファーストリリース前

  • レコメンドは大量のデータが必要

  • メインロジックで実現させようとすると厳しかった

    • Threadとか試したけど……
    • 別アプリケーションとして分離
    • JVM上でScala + Skinnyでスレッドアプリケーションンを実装
    • Microservicesちっくな構成へ
  • 障害検知時

    • メインロジック内のプロトタイプ版が動く!

会計機能リリース前

  • お金を扱う機能は安定性が欲しい
  • Scala + Cats による実装を別エンドポイントとして実装
  • マイクロサービスっぽい作りになっていたから自由度のある技術選択が出来た

まとめ

  • ちょっとマイクロサービス化したことで自由度が上がった
  • 原理主義的にならなくても恩恵がある
  • エンジニアの伸びしろ!

FrontEndからみるmicroserviceとBackendからみるmicroservice by @taka_ft さん

Takahiro Fujii @ Rakuten Travel

楽天内でも採用アーキテクチャはサービスによって異なる。

サービスとしては

  • コンシューマ向け
  • Extranet
  • In-house
  • other
    • ここまではWEBとモバイルがあって、100以上のAPIを利用する
  • API(内部APIを直接利用)

Phase 1

  • 大きなモノリシックなアプリだった
  • 機能がどんどん増えていく
    • 機能別で複数のモノリシックなアプリに分割
    • その後フロントエンドとバックエンドに分割

Phase 2

  • ドメインモデルを整理
  • なるべくRESTfulで作るようになっていった
  • 大きなAPIから小さなAPIに分離
  • I/Fの決定に時間がかかるようになった
  • API呼び出しが大変になった
  • Microservicesっぽくなってきた 2014年くらい

  • 国内予約、海外予約で多言語化だけではない商習慣に根ざしたドメインの差異による重複ロジックの増殖が起きた

  • Microservicesっぽくなってきたが、どんどん品質が下がっていった

Phase 3

(ちょうど前日にプレスリリース)サイト前面刷新に向けての取り組み

  • FrontendsはJavaScriptに刷新
  • API GatewayにKong

組織

  • フロントエンドチームが2人から始まって半年でReactエンジニアを集めて20人以上に

    • 日本人は2, 3人

UI Component

  • SpringからJavaScriptでSPAに変更
  • zeplinのデザインモックからUI Componentを実装するようになった
  • Storyboardを使ってUI Coponentを管理
  • ドメインを含むUI Componentはドメインと結び付きが強いことが多い=専用のオーケストレーションAPIを用意してUI Componentないで処理を閉じることが出来る
  • レスポンシビリティを明示的に定義

    • どこまでフロントエンドでやるか、どこからAPIからもらうか
  • フロントエンドの「使いやすいレスポンス」の要求

  • バックエンドの「汎用的でシンプルなレスポンス」の希望

    • これらのバランスを取る
  • API Gatewayはフロントエンド(UI)チームの管轄

    • ただし状況によってはバックエンド側に持っていくことも検討するつもり

LT: “マイクロサービスはもう十分”か? by @qsona さん

https://speakerdeck.com/qsona/enough-with-the-microservices

POSTDに投稿していた翻訳記事。

スタートアップ企業のほとんどはマイクロサービスをさいようすべきではない

銀の弾丸はない。

「チーム間の依存性」の解決にマイクロサービスというアプローチは違う。疎結合と分散は別。

組織が大きくなると、複数チームが1つのコードベースを触るようになる。そしてマイクロサービス化したくなる。

しかし、モノリスの分割で十分。

チームとは何か

  • 自律的に動けるべき

    • チームが増えるとコミュニケーションコストや、しがらみ
  • チームの分割は目的にそった分割を行う

  • 悪い分割の例: Dev / Ops

  • 依存度が低いほど自律的に動ける

  • High Output という本

  • 使命型組織/技術型組織

    • Micorservicesは使命型組織
    • 組織間が密ならサービス間も密になる

話戻して

  • スタートアップは組織をキレイに分割することが難しい
  • 分割しても密になってしまう

  • 大きなモノリスになるとやはり分割は難しい

    • ドメインの意識は必要
  • マイクロサービス設計しなくても「マイクロサービス精神」で開発すると効果的なのではないか

FiNCが初期からマイクロサービスでやってた理由

  • 単独の事業にできるような一つ一つのサービスを組み合わせて提供してきたから

あとで読み返して修正します。
資料パスの追加とかも。

続きを読む

Rails + AWS でモバイルフレンドリーな動画配信サイト構築

あけましておめでとうございます。 メドピアのSRE @kenzo0107 です。 2018年もよろしくお願いします。 今回は昨年リニューアルした動画配信システムについてです。 経緯 これまでのメドピアの動画配信は CloudFront 経由で S3 上の mp4 を video タグで参照し配信してました。 この配信方… 続きを読む

【AWS】サーバーレスで問い合わせフォーム (s3,Lambda,SES)

はじめに

AWSome Day(awsのセミナー)に参加しまして、
学習意欲が湧いたので、早速、サーバーレスで
お問い合わせフォーム有りのウェブサイト製作をしてみました。

Amazon Web Service初めて使ってみました。
備忘録としてまとめます。

やりたいこと洗い出し

  • 静的なWebサイトホスティング
  • お問い合わせ機能
  • 問い合わせの通知 ⇨ 私 & 担当者
  • SSL化

使ったサービス

  • Route53
  • Cloudfront
  • ACM (AWS Certificate Manager)
  • s3 (Simple Strage Service)
  • Cognito
  • Lambda
  • SES (Simple Email Service)

それぞれのサービスの説明は、
こちらの記事が簡潔で分かりやすいです!
「AWS is 何」を3行でまとめてみるよ

構成図

aws_Diagram_.png

進め方

正直、初めてAWSを触るということもあり、
どこから手をつければ良いのか分かりませんでした..
なんとなく機能を分割して手をつけていきました。

  • 0. 静的サイト制作
  • 1. s3からs3にput、Cognito認証
  • 2. Lambda、SES
  • 3. Route 53
  • 4. CloudFront,ACMの設定

こちらの記事、大変参考にさせて頂きました。
初心者にも分かりやすく、助かりました。

詳細

メモレベルですが、やったことを残しておきます。

① s3 / Cognito

aws_Diagram (3) (2).png

上記サイトのjsを参照し、s3からs3にputできるようにしました。

やったこと
  • s3 バケット作成、html,css,img,js配置
  • Cognito IAM独自のポリシーを作成を作成し、アタッチ。Acctionでputを追加し、s3バケット名を指定するだけで大丈夫です。
  • ACLのデフォルトは”public-read”なので、明示的に”authenticated-read”とかに設定する必要があります。
  • CROS設定で、alloworiginを設定する必要があったのですが、Route53の設定をまだしてなかったので、後回しにしました。

② SES / Lambda

aws_Diagram (_3).png

まず、SESのメール認証を行います。

  • SES ⇨ Email Addresses ⇨ Verify a New Email Address
    自分のメールアドレスを入力し、申請するとメールが届くのでリンクを押せば完了です。

  • ①でs3からs3にput出来るようになったので、そのイベントをトリガーにLambdaの設定を行います。
    こちらのサイトのjsをほぼそのまま使わせて頂きました。

  • IAMロールは、AmazonSESFullAccessを付与します。

③ Route53

お名前.comで既にドメイン購入済みでした。
AWSで発行したNSレコードを、お名前.comの方に追加する必要がありました。手順をこちらにまとめたので参考にして頂ければ幸いです。
【Route 53】【お名前.com】【Amazon S3】Webサイト作成

④ CloudFront / ACM

大変参考にさせて頂きました。

ACM

  • 2017年10月より、DNS認証が追加され、設定が簡単になりました。またワイルドカード証明書も無料で発行できるので、CloudFront使う際は使っておきたいですね。
  • 適応されたらCloudFront側で、http to https設定を行います。

  • 設定完了後、s3のCROS設定に、下記を追加します。
    <alloworigin>https://www.ドメイン.com</alloworigin>

まとめ / 反省点

設定項目が多すぎて、何をどこまで設定するべきなのか難しい。使った分だけ課金されてしまうこともあり、ちゃんと把握しておきたい。

続きを読む

AWSとAzureとGCPを比較してみる – FaaS編

FaaSについてAWSとAzureとGCPを比較してみました。

注)

1. FaaS比較表

AWS Azure GCP
Lambda Functions Cloud Functions***
言語 Python,
node.js,
java,
C#,
go
ランタイムバージョン1.X
C#,
JavaScript,
F#,
Python*,
PHP*,
TypeScript*,
バッチ (.cmd、.bat)*,
Bash*,
PowerShell*

ランタイムバージョン2.X
C#**,
JavaScript**,
Java**
node.js***
最大実行時間 5分 10分 (従量課金プラン)
無制限 (App Serviceプラン)
9分
直接HTTPアクセスを受け付けるか 受け付けない(API Gatewayと連携必要) 受け付ける 受け付ける
トリガー Amazon S3,
Amazon DynamoDB,
Amazon Kinesis Data Streams,
Amazon Simple Notification Service,
Amazon Simple Email Service,
Amazon Cognito,
AWS CloudFormation,
Amazon CloudWatch Logs,
Amazon CloudWatch Events,
AWS CodeCommit,
スケジュールされたイベント (Amazon CloudWatch Events を使用),
AWS Config,
Amazon Alexa,
Amazon Lex,
Amazon API Gateway,
AWS IoT ボタン,
Amazon CloudFront,
Amazon Kinesis Data
Blob Storage,
Cosmos DB,
Event Hubs,
HTTP,
Microsoft Graph Events(2.Xのみ),
Queue storage,
Service Bus,
Timer,
Webhooks(1.Xのみ)
HTTP,
Cloud Storage,
Cloud Pub/Sub

*試験段階
**プレビュー
***ベータ

2. 対応言語の比較

言語の種類は試験段階とプレビューを含めればAzureが一番多いのですが、正式リリースされたものに限定すればAWSの方が種類が多いです。
一方GCPは機能自体がベータリリースなので、まだこれからといった感じでしょうか。

AzureはBashにも対応しているのが特徴です。運用系のシェルスクリプトをFaaS化すれば、スクリプト用のサーバが不要になりますね。

3. 最大実行時間

最大実行時間はAzureの10分(要host.jsonのfunctionTimeoutプロパティ変更)、GCPの9分に対しAWS Lamdbaは5分と約半分です。実際にAWS Lambdaを利用していると5分の壁を結構感じます。この点は他クラウドが羨ましいですね。
2017年のRe:InventでAWSはFargateというコンテナのサービスをリリースしましたが、このサービスがlambdaが5分以上実行できないことに対するAWSからの回答のように感じます。

4. 直接HTTPアクセスを受け付けるか

AWS lambdaだけ直接HTTPアクセスを受け付けることができません。HTTPアクセスを受け付けるには、API Gatewayと連携する必要がありますが、多機能な分やや設定が面倒な印象です。(但しAPI経由でLambdaを起動することは可能)

まとめ

AWS Lambdaのリリース後、Azure・GCP・Bluemix(現IBM Cloud)は超特急で追従しました。AWS LambdaがIT業界に与えたインパクトはとても大きかったと思います。
現在は「FaaS無ければばクラウドにあらず」といったところでしょうか。

また、AWS GreengrassやAzure IoT Edge**というエッジにデプロイするサービスも出てきています。
将来AWS LambdaがiPhoneやApple Watchにデプロイできるようにならないかなーと妄想中です。

**プレビュー

続きを読む

AWS初心者がLambdaでLINE BOTを作る

LINE BOTでオウム返しのBOTを作ります。
正直AWSを触ったことが無いので、よく分からず困ったので同じように困る人が出ないように
記事にすることにしました。

言語・ツール選定

私はRaspberry pi & PHPでLine botを作ったことが有る。
内容としては位置情報を渡すと近くのコンビニを教えてくれるものだ。
しかし、Raspberry piでLine botを作ると、常にRaspberry piを起動しておく必要があり電力的に優しくなく、
サーバの構築や認証鍵の設定が面倒だった。
そこでサーバレスのLine Botを作ろうと思いました。
私が選択したのはLambda+Node.js。
選択肢としてGAS(Google App Script)もあったけれど今後の拡張性を考えた時、
ES6が簡単に使えない(変換すれば使えるが面倒な)のが嫌だと思ったのでやめました。

環境構築

LINE Developers
https://developers.line.me/ja/
↑LineBotを作るためにアカウント取得する
【公式】クラウドならアマゾン ウェブ サービス (AWS)
https://aws.amazon.com/jp/
↑AWSの登録する(日本アカウントだと駄目?)

おわり

使用するAWS

初心者なのでLambdaだけで作れると思ってました。
すると、そういう訳じゃなくいくつかサービスを利用しないといけないことが分かりました。

Lambda
サーバレス、コンピューティングサービス。
サーバ構築しなくてもイベントやトリガーで実行出来るサービス。
使用できる言語はNode.js、Java、C#、Python。
無料枠は
月1,000,000リクエスト
秒400GB 月間400,000GB
有料枠は
1,000,000リクエストごとに0.20USD(約22.6円)
他のサービスは別料金

API Gateway
API の作成、配布、保守、監視、保護が出来る。
Lambdaの関数を動作させる(キックする)ために使う。
料金はデータ送出量で変わる、使用する地域ごとに料金が違う。
無料期間が終わったら有料。

IAM (これはサービスではなく仕組み)
アクセスを安全に制御するための仕組み。権限(role)の設定をする。
Lambdaでログを取ったりするときに設定が必要。

CloudWatch Logs
ログを取るために使う。
無料枠Amazon CloudWatch でのメトリックス 10 個、アラーム 10 個、API リクエスト 1,000,000 件
まぁ、サービスがうまく稼働したら止めると思うので有料枠は気にしない。

api Gatewayの設定

+APIの作成からAPI名とエンドポイントタイプを決める。

エンドポイントとは?
ゲートウェイ VPC エンドポイント??

Amazon API Gateway で、REST API およびカスタムドメインの作成時に 2 種類の API エンドポイントから選択できるようになりました。
リージョンの API エンドポイントは、REST API をデプロイするのと同じ AWS リージョンからアクセスできる新しいタイプのエンドポイントです。
これにより、API リクエストが REST API と同じリージョンから発信される場合に、リクエストのレイテンシーを減らすことができます。
さらに、独自の Amazon CloudFront ディストリビューションとリージョンの API エンドポイントの関連付けを選択できるようになりました。
API エンドポイントの 2 つ目のタイプは、エッジ最適化 API です。
エッジ最適化 API は、API ゲートウェイによって作成および管理される CloudFront ディストリビューション経由でアクセスするエンドポイントです。
以前は、エッジ最適化 API は、API ゲートウェイを使用して API を作成する際のデフォルトオプションでした。

つまり、どーいうことだ?
何か、ドメイン関係というのは分かった、
エンドポイントとは?
https://qiita.com/NagaokaKenichi/items/6298eb8960570c7ad2e9

なるほど。
URIの設定のことね。
んで、エンドポイントタイプの違いって具体的に何?

Regional:リージョン(地域が一緒なら早い)
Edge Optimized:エッジ最適化(経由して最適化する)
って感じかな?
今回はAPI GatewayもLambdaも同じハイオワにしたので、リージョンで良さそう。

API 名を決めないと何故かエラーが出る模様。訳が分からない。泣いた。
http://kubotti.hatenablog.com/entry/2017/01/13/161022

リソースで、ポストが出来るように設定しLumbdaの関数が完成したらAPIのデプロイをする。
image.png

設定で、ARNの設定をする。
image.png
Lumbdaへのアクセスできる設定とログが取れるようアクセスを許す設定した物を割り当てる。
あ、後クライアント証明書も作った。

Lamubdaの設定

image.png
実行ロールの設定でログ監視とAPIGatewayからのアクセスが可能なアカウントを設定する。

コードはこんな感じ

index.js
'use strict';

const https = require('https');
const querystring = require('querystring');

exports.myHandler = (event, context, callback) => {
    console.log('EVENT:', event);
    var event_data = JSON.parse(event.body);
    console.log('EVENT:', JSON.stringify(event_data));
    const messageData = event_data.events && event_data.events[0];
    console.log("TEST:" + JSON.stringify(messageData.message.text));
    var id = messageData.source.userId;
    if(messageData.source.groupId != null && messageData.source.groupId.length > 0){ //グループからのメッセージ
        id = messageData.source.groupId;
    }

    if(!check(messageData.message.text)){
        callback(null, 'Success!');
        return;
    }
    var postData = JSON.stringify(
    {
        "messages": [{
            "type": "text",
            "text": getResponseMessage(messageData.message.text)
        }],
        "to": id
    });
        // @TODO KMSで管理
    var ChannelAccessToken = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'; //チャンネル設定

    //リクエストヘッダ
    var options = {
        hostname: 'api.line.me',
        path: '/v2/bot/message/push',
        headers: {
            'Content-Type': 'application/json; charset=utf-8',
            'Content-Length': Buffer.byteLength(postData),
            'Authorization': 'Bearer ' + ChannelAccessToken
            },
        method: 'POST',
    };
    console.log(JSON.stringify(options));
    //APIリクエスト
    var req = https.request(options,  function(res){
        res.setEncoding('utf8');
        res.on('data', function (body) {
            console.log(body);
            context.succeed('handler complete');
        });
    }).on('error', function(e) {
        context.done('error', e);
        console.log(e);
    });

    req.on('error', function(e) {
        var message = "通知に失敗しました. LINEから次のエラーが返りました: " + e.message;
        console.error(message);
        context.fail(message);
    });

    req.write(postData);
    req.on('data', function (body) {
            console.log(body);
     });
    req.end();
    console.log("TEST:" + postData);
    callback(null, 'Success!');
};

var getResponseMessage = function(message) {
    message = message.toLowerCase();
    message = message.replace('@bot ', '');
    switch (message) {
        default:
            return message;
    }
};

var check = function(message) {
    message = message.toLowerCase();
    var pattern = '@bot ';
    return message.indexOf(pattern) === 0;
};

・↑ではセキュリティガバガバなので、Lineからのアクセスかどうか検証するためにChannel SecretのIDを見るプログラムと、ChannelAccessTokenは管理するものを入れたほうが良いと思います。
・replyでも良いんですが、処理に時間がかかると処理されないらしいので今後重い処理を入れることを考えてpushにしました。
(参照:https://developers.line.me/ja/docs/messaging-api/reference/)
・グループに突っ込んだ時に関係なく反応するのがうざかったので、@botと頭につくと返すようにしました。

image.png
LINE DevelopersのChannelAccessTokenはここのやつをコピペ。

image.png
上のような形で登録する。(念のため443はつけたほうが良い)

image.png
↑のエラーが出ますが問題なく動きます。

結果

image.png
出来た。

まとめ

AWSのいい勉強になった。
私のセキュリティ意識が低いことが分かった。
よくわからないところからAPIリクエストが飛んで来ていたので気をつけたい。
LineBotはちょっと前とはAPIの書き方が変わっていた&単純にNode.jsに慣れていないというのもあって、ちょっと苦戦した。
今後は、飲み会幹事BOTなどにしていきたい。
たのしかった。

参考

https://qiita.com/akihito_nagai/items/f284ef495da380f368cc
https://qiita.com/ykyk1218/items/232437bc92f13d02a8a2
https://qiita.com/daikiojm/items/c05882bedb82d7ed664e

続きを読む