【開催レポ】BANK engineer night #02 〜狂ったようなことをしよう〜

こんにちは。BANK広報の磯田です。

2018年10月11日に『BANK engineer night #02 〜狂ったようなことをしよう〜』を開催いたしました。BANKではBANK engineer nightを通してBANKのメンバーが、普段どのようにスピリットを持ちながらサービスを開発しているのかを、 多くの人に知ってもらいたい、という想いから今回のイベントを企画いたしました。 f:id:bankinc:20181030102342j:plain

現在BANKは、『CASH』と『TRAVEL Now』の2つのサービスの開発・運営を行なっています。 今回のイベントでは、2つのサービスを世に出し、育てていく上で、いかに狂ったように振り切ってきたのかをエンジニア4名がLTでお話しました。

眼の前のアイテムが一瞬でキャッシュに変わる『CASH』 https://cash.jp/ f:id:bankinc:20181030105011p:plain

あと払い専門の旅行代理店アプリ『TRAVEL Now』 https://travel.app/ f:id:bankinc:20181030105014p:plain

発表プログラム

CEO光本からご挨拶

はじめに、CEO光本からみなさんにご挨拶です。会社紹介と、運営している2つの事業についてお話させていただきました。 『エンジニアがうらやましい。まだ世の中に無いサービスを作り出すことができるから。』という話をしていて、みなさん深く頷かれていました。 f:id:bankinc:20181030102258j:plain

魅力品質をアゲて見たことないサービスを認知してもらう

iOSエンジニアの高橋からは、今回初めて開発秘話が話される「TRAVEL Now」のお話でした。 f:id:bankinc:20181030102447j:plain

speakerdeck.com

ユーザーの心をつかむ「魅力品質」と絶対に必要な「当たり前品質」の両方を落とさずに、新規事業の開発についてお話しました! 今までにないサービスを世の中に出すことは、受け入れられるのか怖いけど、だめならブラッシュアップして直せば良いという気持ちで開発に臨んでいたそうです。

スピード狂エンジニアたちの開発速度を保つインフラとは

サーバーサイド兼インフラエンジニアの高橋からは、スピードのお話。 f:id:bankinc:20181030102453j:plain

speakerdeck.com

入社してからどんどんメンバーが増えていく中で、数人規模で開発していたときのスピード感を落とさずに開発できる環境を整えたお話でした。 「インフラはあくまで裏方」という言葉が印象的でした!

なぜBANKは名刺でお金をばらまくのか

Androidエンジニアの遠藤より、名刺でお金をバラまいたお話をさせていただきました。 f:id:bankinc:20181030102323j:plain

speakerdeck.com

なぜ名刺なのか。おもしろさと有用性の伝え方を開発者目線からお話しました。 遊び心を忘れないバンクのエンジニアらしいアイデアですね。

Knativeで限界突破 〜Push通知をバラ撒くために〜

サーバーサイド(Ruby)エンジニアのうなすけからもバラまきのお話。こちらは「Push通知」をバラまいたようです。 f:id:bankinc:20181030102321j:plain

speakerdeck.com

CASHのユーザーに数十万件単位で送ったプッシュ通知についてお話しました。 実際に会場で、デモをして盛り上がりました!

懇親会

バンクの他のメンバーも応援に来ていたので、参加者のみなさまとお話することができました!スペースがいっぱいになるくらいの人に来ていただき、懇親会もとても盛り上がりました。 f:id:bankinc:20181030102311j:plain

おわりに

今回のイベントでは、『CASH』と『TRAVEL Now』の開発秘話についてご紹介いたしました。 BANKメンバーがどんなことにこだわり抜いて、狂ったようにサービスを育てているのか伝わるイベントになっていたら幸いです! BANKでは、サービス改善や新規事業に向けて日々取り組んでいるところですが、実現したいことに対して、まだまだ力が足りていません。そこで、一緒に新しいことをやっていただけるメンバーを探しています。

bank.co.jp

f:id:bankinc:20181030102318j:plain

https://bank.co.jp/recruit/

bank.connpass.com

今後のイベント情報についてはConnpassページについて随時更新予定です!イベント更新情報にご興味がある方は、ぜひメンバー登録をポチっとお願いします!

Google Cloud NEXT'18 in Tokyoで登壇しました

f:id:yu_suke1994:20180920144234j:plain

こんにちは。発表では早口になりがちなうなすけ (id:yu_suke1994) です。

さて、以前の記事でも告知していましたように、弊社高橋 (id:takutakahashi)、Google Cloud カスタマーエンジニアであるSokoPさんと共に弊社におけるGCPの活用事例について Google Cloud NEXT'18 in Tokyo で発表してきました。

当日お越し頂いた皆様、本当にありがとうございました。

発表内容

発表スライド、録画は以下になります。

発表については、大きく3つのテーマに分けて話しました。詳しくは資料、もしくは録画を参照していただくとして、簡単に発表した内容についてまとめます。

インフラについて

インフラについては、「開発スピードを最大化させるインフラ」を目指しています。 検証環境を複数立ち上げる、そしてそれを可能な限り早く行なうために ingress-gce をやめて nghttpx ingress controller を採用したり、CI上での docker build とテストを並列実行させたりという、様々な取り組みについて話しました。

アプリケーションについて

様々な「実験」を行なうときに、どのようにGCPのリソースを活用して素早く結果を得られるようにしたか、また開発を進めていくと生じる障害や不整合に対してどのように対処するか、などについて話しました。

開発体制について

成長していく開発組織の足止めを最小限に抑え、新メンバーが素早く開発に参加していけるようにどのようなことを行っているのかについて話しました。

発表してどうだったか

こちらから応募したとはいえ、このような規模のイベントで話す機会はこれまでになく、とても緊張しました。

規模の大きなイベントなので、6月中旬から準備が始まっています。プロフィール提出やスライド作成のための打合せ、実際のスライド作成と通しでの読み合わせなど、いい発表をしたいという思いで結構なリソースを割いて準備しました。発表後、SNSでの反応を見ていると、結構好印象だったのでとても嬉しく、苦労が報われる思いでした。

これから

発表した内容でもっと詳しく「やってやったぞ!」を伝えていきたい内容、とくにインフラに関しては今後ブログに投稿していきたいと思っています。

また、来年のGoogle Cloud NEXTでも採択されるような発表ができるよう、日々切磋琢磨していきたいですね。やっていくぞ!!

f:id:yu_suke1994:20180920152029j:plain

我々はそんなやっていく気持ちがあるエンジニアを募集しています。興味がありましたら、是非お気軽にご応募ください。

bank.co.jp

TRAVEL Now Androidアプリがリリースされました!

f:id:YousukeTezuka:20180927145006p:plain

こんにちは、BANKでAndroidエンジニアをしている手塚です。

Androidユーザのみなさんお待たせしました!昨日TRAVEL NowのAndroidアプリがリリースされました!
これから紅葉など季節の移ろいがたくさん感じられる季節になりますね!ぜひTRAVEL Nowを使って旅行へ行ってみてください!

さて本記事では、TRAVEL Now Androidアプリではどんな技術を採用して開発してきたのか一部ですが紹介していきたいと思います!

言語 & 開発環境

100%Kotlinで書かれています。もうJavaを書けない体になってしまいました。
coroutineなどはまだ使えていないため、適切な場面があれば積極的に使っていきたいです。

IDEはアプリをリリースするころにはさすがにStableになってるだろうと 判断して 高を括って、約3ヶ月前に開発を開始した時点からAndorid Studio 3.2を使って進めました。
結局リリースまでにStableにならなかったなと思いながらテストしていましたが、まさかリリース前日にStableになるとは...。

アーキテクチャ

これまで開発してきたアプリではMVVMで書くことが多かったのですが、ViewModelがややfatになってしまうのが悩みで今回はFluxを採用してみました。
現段階では各コンポーネントの責務がより細かく明確でデータフローも単方向になり見通しがよくなった一方、当然ですがクラス数コード数がやや増えたかなといった印象です。
一長一短といった感じで自分の中でもまだまだ試行錯誤中なので、もう少し知見が溜まったらまた発信したいと思います。

デザイン

Material Components

まだまだ対応していないComponentも多いですが、導入するとぐっとMaterial Design感が出せるのでオススメです!

f:id:YousukeTezuka:20180925180823g:plain

Constraint Layout & Motion Layout

本アプリでは随所に細かなアニメーションを付けています。よりリッチなアニメーションを実現するためにアルファ版ではありますがConstraint Layout 2.0を採用しMotion Layoutを活用しています。

これまでデザイナーから「こういう動きってできますか?」と提案されてもなかなか実現できずに心苦しい場面がしばしばありました。
Motion Layoutによってそれに応えられるようになり、触っていて気持ちいい動きをつけられるようになったように思います。

f:id:YousukeTezuka:20180925181905g:plain

さいごに

一部ではありますがTRAVEL Now Androidアプリで採用した技術を紹介させていただきました!

これからも自動テストやCIの整備、Slicesの対応などまだまだやらなければいけないこと、やっていきたいことが山積みです。
BANKではそんな課題をひとつひとつ一緒に超えていける仲間を募集しています。
少しでも興味を持っていただけましたら、ぜひお気軽にオフィスに遊びに来てみてください!

bank.co.jp

大量のPush通知をCloud Functions経由で送信する

実験の様子

こんにちは。ふぁぼ通知が好きなうなすけです。

モバイルアプリでは、Push通知によってユーザーに情報を伝えたり、行動を促したりすることが日常的に行われています。

その通知を送る対象のユーザーが数十人程度の規模なら、愚直に一通一通送信すればいいでしょうが、一気に万単位のユーザーにPush通知を送信したい場合、愚直に送信すると完了までに数時間かかることも往々にしてあります。

CASHでの大量Push通知事例

pull req

以前、ある施策のために42万件のPush通知を送る必要がありました。CASHではFirebase Cloud Messaging(以下FCM)をPush通知の送信に使用しているのですが、このとき、通知1件ごとにAPIを叩いていく方式だと送信完了に1日かかってしまうという事態になりました。

FCM Topic Messaging

そのような場合に使用できるのが、Topicを用いた通知の送信です。Topicを使用すると、そのTopicを購読している端末に一度にPush通知を送ることができます。実際、42万件のPush通知は最終的にTopicによって送信しました。

Topicの利点と欠点

Topicを使用する場合、あらかじめユーザー(というよりはデバイストークン)をTopicに対して登録させなければなりません。Firebaseのドキュメントに記載されている「荒天警報」のような、事前に通知の対象がわかっている場合は使い勝手が良いです。 しかし弊社の場合は、急に「こういうユーザーに対してこういう通知を送ってみたい!」という 実験 が提案され、対象となる大量のユーザーIDが渡される、ということがままあります。そのような場合、Topicを新規に作成しなければならず、それに時間がかかること、Topic自体も作成から使用可能までに最大で1日の遅れが生じることから、「即・大量に!」というユースケースには使い勝手があまりよくありませんでした。

既存の実装で使えるものはないか?

まずは、インターネット上に大量にPush通知を送信するためのプロダクトがないかどうか調べることにしました。すると、Mercariさんでの事例がOSSとして公開されていることを見つけました。

tech.mercari.com

github.com

「これじゃん!」と思い導入しようと、まずソースコードを読んでみました。すると、GaurunはiOSはAPNs、AndroidGoogle Cloud MessagingもしくはFirebase Cloud Messagingを使用するような実装になっていました。 CASHでは、iOSAndroidもFCMを使用してPush通知を送信しています。Gaurunを、両OSでFCMを使用するように変更することは不可能ではありませんでしたが、既存のAPIを変更せずに、ということが結構難しそうだった1ので、何か別のやりかたを探すことにしました。

FaaSを用いたPush通知

そこで、Faasを使うことを思い付きました。もともとPush通知というタスクは、複雑な処理をしない小さなものであり、単発のタスクなので、FaaSに乗せるにはもってこいの題材でしょう。

また、ちょうどいいタイミングでGoogle Cloud FunctionsがNode.js 8 Runtimeをサポートし始めたので、async/awaitも使えるしやってみようということになりました。2

The Node.js 8 Runtime  |  Cloud Functions Documentation  |  Google Cloud

Promiseを用いた並列実行

Cloud Functionsを使うことにしたところで、Push通知1件に対して1 function callでは、以前の問題を解決できているとは言えません。

なので、対象となるデバイストークンを一気に投げて、その大量のトークンを分割したものを自分自身に送信する、という再帰的な処理を行なうことで大量のデバイスに対してのPush通知システムを作成しました。

github.com

結果

幸か不幸か、数万規模の通知を送ることが直近は無さそうした。なので社内の有志を募り、その人の端末に向けて大量の通知を送ってみることにしました。下記のスクリーンショットはそのときの様子です。

このときは14端末に向けてそれぞれに500通、合計7000件のPush通知を送信しました。送信完了までにかかった時間は約1分間でした。

実験の様子

これが高速なのかそうでないのかは、他の通知基盤がどのようなスペックかわからないので何も言えません。しかし手動で実行したrequest自体は1回で、そのresponseは一瞬で返ってきていることを考えると、これまでの手間が大幅に削減されたことは明白です。

問題点

呼び出し上限に達してしまう

そりゃそうだろ、という感じではあるのですが、自身を再帰的に呼び出すので一瞬にして実行数が跳ね上がり、quota limitに引っ掛かります。

Quotas  |  Cloud Functions Documentation  |  Google Cloud

一応、Function invocations per second は申請によって上限を緩和させることができます。しかしなるべくなら初期上限のままで運用できるような仕組みにしたいです。案としては再帰実行前にジッタを挿入して呼び出しタイミングをずらすというものがあります。

他には、API limitation の存在しないFaaSを使用するという手もあります。いや、そんなものがあるのか?となりましたが、Knativeというものがありますね。これは確かに無制限に呼び出せますが……

その辺りの話を今度弊社が開催するイベントで話す予定なので、皆さん是非参加してください。

bank.connpass.com

Push通知の全てのパラメータに対応していない

ひとまずCASHで使用するパラメータに絞って実装したために、必要最小限のパラメータにしか対応していません。

まとめ

今回、FaaSによるPush通知基盤という、ほぼ実験的な手法を試してみました。結果、これまでの作業時間を大幅に短縮することに成功しましたが、API呼び出し回数制限などの新な課題も発見しました。

BANKでは、このような実験的なアプローチを、ビジネスモデルだけでなく、技術的な部分にも実践していく企業です。興味があれば、是非お声掛けください!

bank.co.jp


  1. 独自Forkを自社で運用することもできますが、せっかくなら上流に還元したいし、メンテはしたくないので……

  2. 結局 async/awaitは使いませんでしたが。

Identity-Aware Proxy を GKE で利用するコツ

こんにちは,BANK でサーバサイドエンジニア兼インフラエンジニアをやっております,
高橋 (@takutakahashi) といいます.
技術ブログの技術記事第一弾として,管理画面をいい感じにした話をしようと思います!

Identity-Aware Proxy?

さて,GCP では,GAE や Google 提供のHTTPS Loadbalancer を経由する web サービスに対し,
超簡単に Google 認証を付与できる Identity-Aware Proxy (以下 IAP) が提供されています.
Google アカウントによる認証,認可を設定することが可能です.
詳細は以下を参照ください.

https://cloud.google.com/iap/docs/concepts-overview?hl=ja

CASH 管理画面の課題

CASH では,定常運用のために管理画面を持っています.
ActiveAdmin で実装し,アプリケーションのバックエンド API の傍らで動作しています.

この管理画面,もちろん組織の人間でない第三者からのアクセスを防ぐ必要があります.
以前は,アクセス防御のために Basic 認証を利用し,1つのユーザー/パスワードで運用していました.
この状態だと,

  • ユーザーとパスワードがわかっていれば誰でもアクセスできる
  • インターン生や退職者など,元関係者からのアクセスを防ぐことができない

という課題がありました.
なんとかうまい具合に認証できないか?ということで,
Cloud Identity-Aware Proxy を GKE と組み合わせて使ってみて,そこから得た教訓を共有する.
というのが今回の記事の趣旨です.

GKE と HTTPS Loadbalancer

以下は,kubernetes の用語が多く出てきます.ここでは解説しませんので調べてください.

CASH のバックエンドオーケストレーションには,Google Kubernetes Engine (以下 GKE) を利用しています.
GKE では,アプリケーションを外部公開するための Ingress リソースを作成した際に,
Google HTTPS LoadBalancer と連携しロードバランサを作成してくれる機能があります .

IAP + GKE

IAP は,HTTPS Loadbalancer に適用できる認証システムです.
GKE で Loadbalancer は自動作成されるため,GKE がどのように Loadbalancer を作成するのかが理解できれば,
IAP と GKE をどのように組み合わせて利用するべきか,理解することができます.

IAP は Service に適用できる

IAP を効果的に使うためには,LoadBalancer と Kubernetes リソースがどうマッピングされているかを知る必要があります.
以下は,機能のマッピング表です.

役割 Cloud LoadBalancer Kubernetes
IP や HostHeader によるルーティング Frontend Ingress
実際のワークロードへのアクセス Backend Service
アプリケーション健全性確認 HealthCheck Pod (Liveness Probe)

IAP は,HTTP(S) LoadBalancer の Backend に適用することができます.
つまり,Kubernetes の文脈では Service に適用することとなります.

IAP 適用で気をつけること

CASH 管理画面 の IAP 化でも発生した問題ですが,API と管理画面で同じ Service を経由している場合,
IAP を有効にすると API にも認証がかかってしまうことになります.
これを回避するために,Service はアプリケーションポートごとではなく役割ごとに作成しておくことが望ましいです.

以前の CASH のリソース図はこの様になっており,
f:id:takutakahashi:20180810100238p:plain

この構成を以下のように変更し,
f:id:takutakahashi:20180810100355p:plain

管理画面のアクセス先 svc を分離することでこの問題を解決できました.
ミソは,同一 deployment を向く svc を定義することです. 今後アプリケーションを構築する際も,このように役割分離をしておくことで,
単一役割となりリソース編集コストが減る,マイクロサービス化した際に楽,など,色々とメリットがあります.

ちなみに

現在 IAP を有効にするには,GUI で設定するか,gcloud を利用して CUI で設定するかの方法を取る必要があります.
できれば ingress-gce にやってほしいなあ...という気持ちがあるので調べたら,以下の issue で議論されていました.

github.com

issue の進みがあまり良くないので,機能が実装されるまで結構時間がかかりそうですね...

終わりに

アプリケーション事業を運営する上で欠かせない管理画面.
ユーザー認証など,ビジネスロジックに影響しない部分はインフラレイヤーで解決し,
節約したリソースで爆速開発していくことが望ましいですね.

宣伝

cloud.withgoogle.com

9/19, 20 で開催される Google Cloud Next '18 in Tokyo にて,BANK インフラストラクチャ事例紹介のセッションを実施いたします! このブログを読んで,詳しい構成が気になった方は,ぜひお越しいただき,弊社のセッションをご覧ください!