Smart Store リファレンスアーキテクチャ Deep Dive! / Smart Store Deep Dive

Ff7f1f76468f46a1c5c84b9238a4b162?s=47 miyake
April 27, 2019

Smart Store リファレンスアーキテクチャ Deep Dive! / Smart Store Deep Dive

Global Azure Bootcamp 2019@Tokyo での発表資料です

Ff7f1f76468f46a1c5c84b9238a4b162?s=128

miyake

April 27, 2019
Tweet

Transcript

  1. Smart Store リファレンスアーキテクチャ Deep Dive! @Tokyo, Japan

  2. About Me 三宅 和之 @kazuyukimiyake 株式会社ゼンアーキテクツ CTO Microsoft MVP Vue.js

    ⽇本ユーザーグループ運営メンバー PaaSがかりの部屋(Blog): https://k-miyake.github.io/blog/
  3. Smart Store ビジネスモデル ⽇本マイクロソフトが提唱する次世代店舗モデル 発表記事 リファレンスアーキテクチャ(OSS) リファレンスアーキテクチャに基づくサンプル実装をOSSで公開 https://github.com/intelligent-retail/smart-store サンプル実装「Smart Box」

  4. Smart Store について Special Guest: Yoshifumi Okada (Microsoft)

  5. アーキテクチャ全体像

  6. アーキテクチャの⽅向性・狙い マイクロサービス ユースケースによって使いたいサービスは異なるはず サーバーレス できるだけシンプルな基盤にしたい スケーラビリティを柔軟に調整しなければならない リアルタイム性の重視 情報の鮮度が重要なユースケースが多い

  7. Deep Dive - Agenda 1. モバイルデバイスへのプッシュ通知 2. サーバレスAPI と CQRS

    3. リアルタイムWebによる管理UI 4. マイクロサービスのデプロイ
  8. Deep Dive 1 - モバイルデバイスへのプッシュ通知 contributor: @masatoru

  9. モバイルデバイスへのプッシュ通知 モバイルアプリは、 Xamarin.Forms で実装 プッシュ通知のサービスに App Center を利⽤

  10. App Center + Firebase の設定 Just 7 Steps!!

  11. Xamarin.Forms での App Center Push の実装 「Azure Notificatoin Hubsに⽐べたら圧倒的に楽ちん」 by

    @masatoru
  12. #Xamarinはいいぞ

  13. Deep Dive 2 - サーバレスAPI と CQRS contributor: @shibayan

  14. サーバレスAPI と CQRS サーバレスによる在庫管理の実装 Azure Functions (V2) によるサーバレスAPI CQRS によるバックエンド

    (Cosmos DB Change Feed)
  15. Azure Functions による CQRS 実装 CQRS を実現するためには 3つのFunction が必要 コマンド:

    StockService.StockCommand/CommandFunction.cs 同期: StockService.StockProcessor/ChangeFeedFunction.cs クエリー: StockService.StockQuery/QueryFunction.cs 実装上のポイント Http Trigger のJSONモデルバインディングで⼀部問題があった(最終的に解消) Cosmos DB SDK は プレビューでも 3.x を使⽤した(すべき) Cosmos DB Trigger の leaseコレクション の扱い(要注意) Change Feed の同期を速くするために FeedPollDelay = 500 を追加で設定
  16. CQRS の性能検証 Visual Studio Load Test を使って、約1万req/分(秒間 196 req)まで負荷を上げた 適切なスループットがあれば劣化はしない(平均処理時間:

    397ms、中央値: 146ms)
  17. Application Insights による分散トレーシング マイクロサービスで実装する場合、分散トレーシングが必須となる 実装 起点となる Command で ActivityId をセット

    // 追跡⽤の ActivityId をセット document.ActivityId = Activity.Current?.Id; _telemetryClient.TrackTrace("Begin Stock Command", new Dictionary<string, string> { { "ActivityId", document.ActivityId } }); 同期処理を⾏う Processor は、コレクションでバインドされてくるため、カスタマイ ズが必要 // Application Insights に通知 foreach (var document in documents) { _telemetryClient.TrackTrace("End Stock Processor", new Dictionary<string, string> { { "ActivityId", document.ActivityId } }); }
  18. Deep Dive 3 - リアルタイムWebによる管理UI contributor: @shibayan, @kazuyukimiyake

  19. リアルタイムWebによる管理UI SignalR Service によるリアルタイム通知 Vue.js による画⾯実装

  20. SignalR Service のServerless Mode (Backend) 開発中に SignalR Service に Serverless

    Mode が登場! -> Hubの実装が不要に Azure Functions 側は SignalR Output Bind を使って更新を通知する var signalRMessages = binder.Bind<IAsyncCollector<SignalRMessage>>(new SignalRAttribute { ConnectionStringSetting = "SignalRConnection", HubName = "monitor" }); // 変更通知を SignalR で送信する foreach (var document in documents) { foreach (var item in document.Items) { await signalRMessages.AddAsync(new SignalRMessage { Target = "update", Arguments = new object[] { document.TerminalCode, item.ItemCode } }); } }
  21. SignalR Service のServerless Mode クライアント側は signalr.js を使って更新イベントを待ち受ける mounted: async function

    () { // 初回のデータを取得する this.init(); // SignalRとコネクションを確⽴する const conn = await axios.post(`${server.endPoint}/api/negotiate`, null, getAxiosConfig()); const info = conn.data; const options = { accessTokenFactory: () => info.accessToken }; const connection = new signalR.HubConnectionBuilder() .withUrl(info.url, options) .configureLogging(signalR.LogLevel.Information) .build(); // Azure Functions から update が呼ばれた時に画⾯を更新 connection.on('update', this.update); }
  22. Vue.js でのリアルタイム描画 SignalR と Vue.js のデータバインディングの相性はバッチリ js側は基本的にオブジェクトを更新するだけ 画⾯は、バインディングとCSSトランジションを書いておけばOK <div class="columns

    is-multiline"> <div class="column is-3" v-for="item in box.items"> <div class="box item-stock" v-if="item.itemName != null" :class="{ active: item.updated }"> <p class="title"> <span>{{item.quantity}}</span> <figure class="image is-4by3"> <img :src="item.imageUrls[0]"> </figure> </p> <p class="heading">{{item.itemName}}</p> </div> </div> </div>
  23. Deep Dive 4 - マイクロサービスのデプロイ contributor: @dz_

  24. マイクロサービスのデプロイ サーバーレスで実装したため、⼀貫性のあるデプロイを作り込む必要があった (コンテナオーケストレーターのような仕組みがないため) ARM Template 実装例

  25. ARM Template の開発 ポイント メンテナンス性を考慮し、Linked template を利⽤ マイクロサービス単位毎にテンプレートを分割 デプロイ実⾏時は、サービスの組み合わせをまとめた親テンプレートで実⾏ App

    Service デプロイ後に Run From Package を使って Function App も⾃動デプロ イ デプロイの実⾏コマンドは基本的にこれだけ(変数の設定などは除く) az group deployment create \ --resource-group ${RESOURCE_GROUP} \ --template-uri ${TEMPLATE_URL}/template.json \ --parameters ${TEMPLATE_URL}/parameters.json \ --parameters \ prefix=${PREFIX} \ stockServiceSqlServerAdminPassword=${STOCK_SERVICE_SQL_SERVER_ADMIN_PASSWORD}
  26. 今⽇お話したこと 1. モバイルデバイスへのプッシュ通知 2. サーバレスAPI と CQRS 3. リアルタイムWebによる管理UI 4.

    マイクロサービスのデプロイ
  27. https://github.com/intelligent-retail/smart-store

  28. ご清聴ありがとうございました︕