今の会社(BeeX Inc.)に来て、半年くらいサーバーレス開発をやってきました。
やっと人並みに(?)サーバーレス開発進められるようになったのと、開発が一息ついたので振り返りをしてみようと思います。
はじめに
初めてのサーバーレス開発を手がけたこの数カ月を振り返ってみると、エンジニアとしての自信を完全に失った数カ月だったなと感じてました。
端的に言えば、開発にとても時間がかかりました。この時間は絶対的時間というよりも感覚的時間です。
ほとんどのエンジニアにとって、初めて触る技術の場合、正確な開発工数の見積もりは難しいと思います。 それでもエンジニアの方なら肌感覚で「少し調べた感じと、この機能なら勉強、検証含めてこれくらいかな・・」みたいな自分なりの見積もり感覚はあると思います。 今回は、その感覚が3倍くらいズレてしまいました。
この3倍という数字は自分の効率の悪さも表してるのですが、サーバ有りの開発と違うところが多いので最初は経験からの見積もり以上に時間がかかる可能性があることはお伝えしたいです。
実際には無理しながらも、何個かあったマイルストン的なスケジュールには間に合わせたので、その点は問題ありませんでしたが、 今まで色々な技術を触ってきて、ここまで大きく自分の感覚とズレることは無かったので、自信の喪失には十分なものでした。
そんな風に自信喪失中していた中、以下のクラメソさんのサーバーレス開発部のブログが公開されました。
すごく共感できました。同時にすごく救われました。もしかしたら自分が経験した苦労も、書いてみる意味があるのかなと思い、この記事書いてみることにしました。
サーバーサイドについて
主に2つのマイクロサービス作っていたのですが、サービスについてざっくりと。
使用サービス
今回利用している主なAWSサービスです。
デプロイはAWS SAMとSwagger組み合わせてます。 他にも外部サービスとして、認証にAuth0使ってたりします。
LambdaはGolangで書きました
一部Java使ってますが、主なLambdaはGolangを利用して書いています。なんでGolang選んだか。検討する時間がありませんでした。開発は自分一人だったので、リリースされたばかりで心配だったのですが、一番得意な言語なので選びました。
一番のマニュアルはGithubのリポジトリです。書いている途中でSQSのEventトリガーがサポートされた際もすぐに対応されていたので助かりました。
Golang以外の言語でしっかりLambda書いてないので、比較はできないのですが、Golangで辛かったこと、良かったことの所感だけ。
Golangで辛かったこと
LambdaをGolangで書いている人がほとんどいないと思うので情報少なかったです。といってもGolangが原因だったでハマりポイントは結果として無かったのですが。
あと、アーティファクトのサイズが比較的大きくなるので、デプロイ時の転送に時間がかります。普段は大したこと無いのですが、ネットワーク環境が良くない作業場所だと厳しいです。
Golangで良かったこと
早いです。簡単な集計処理とか回しても大丈夫です。処理時間が短いのでコストも安いはず。
並列処理もしやすいのも良かったです。外部のAPIを複数呼び出す際に、シーケンシャルで流すとネットワーク的に時間がかかるのですが、Golangの並列処理簡単に書いてとりあえずサラッと解決した際には、Golangにして良かったと思いました。
最後に、Golangとは直接関係無いのですが、Golangの文化でMakefileをビルドツールとして使っています。他のと比較したわけでは無いのですが少なくともMakefileとSAMの相性は良いと思います。場合分けとかもシンプルに書けました。
クライアントサイド
主に別サービスにAPI提供している形ですが、一部、SPAで画面開発しています。Vue.js使ってます。
なぜVue.jsか。一番学習コストが低いと何箇所かで読んだからです。
とりあえずSPAやると決めてから、形にするまで2週間しか時間無く、SPA書くのも初めてだしとなると、比較検討する余裕もスキルも無いというのが正直なところでした。
UI Frameworkは一応下記サイトTop3(element-ui,Bootstrap-Vue,Vuetify)を少しずつ使ってみました、
マテリアルデザインが気に入ったのと、特にデータテーブルの標準機が要件に近かったVuetifyを選びました。
フロントのJavascriptは本当の素人でしたが、それでもそれなりに作れてるので、Vue.jsの学習コストは低いというのは当たっているのではないかと思っています。
Windows Storeアプリを結構開発していて、あれもMVVMだったので、UI周りのグリッドシステムも合わせて結構類似点多いと思っています。それも、学習時間短縮できた要因だと思っています。
サーバーレス開発が大変だったこと
関連コンポーネントが多い
NginxとPHP-FPMとMySQLといったコンポーネントで作られている仕組みがあれば、それぞれに別のスキルが必要になります。当然初めて使う際には、ある程度勉強する必要があります。
サーバーレスで作られたサービスの構成図を見ると、色々なAWSアイコンが線で繋がっていると思います。誤解を恐れずに言えば、あの一つ一つがMySQLのようなコンポーネントと一緒です。
そういったコンポーネントを初めて使う時と同様に、サービスのクセ、APIの使い方から、制限、トラブルシュート方法まで知らないと満足に開発できないです。AWSのアイコン間の線、あれもコンポーネント間の連携そのものなので、一本一本にドラマがあったりします。
とは言え、一回使えるようになれば、便利なサービスばかりです。特に最初は検証等に時間かかること考慮しながら作業量の見積もりするよう気をつけると良いと思います。
障害の原因特定が難しい
個別の連携では動いたように見えても、通してみると動かないとか。エラーの原因と思って調べてしたサービスと全く違うサービスが原因だったというのが結構ありました。
OS上に乗っていれば、適当にログ漁ってても簡単にたどりつけるだろう原因も、サービスを跨っていて、それぞれが疎連携している状態だと、頭を切り替えながら調べていく必要があるなと感じています。
だからこそ、Lambda内でのログの出力は重要です。手元に環境が無い以上、ログに頼る部分が大きくなりますので。
ネットワーク絡むとハマりやすい
要件上、どうしてもVPC絡む部分が一部ありました。VPC絡むとLambda起動遅くなるのはよく知られていますが、例えば名前解決がうまくできないとか(VPCじゃない方のIP側の自分のホスト見てしまったり)。 そして要件変わってVPCから外すことになったら、思った以上に何箇所も問題が出たりとか。
いや。全部大したことない問題なのです。OSに入ってネットワーク調べられるのなら。しかし、揮発性のLambdaでネットワークの問題が出たら、ログしか頼りにできません。ログの出力方法変えて、デプロイして、ログの内容から設定調整してみて、またデプロイして・・というサイクルです。それぞれのデプロイが数分かかっていきます。このようなサイクルを回してると一気に時間を使ってしまいます。
統合テストが大変
UnitTestを書くのは当然として、SAM Localでのテストや、モックのテストも組み合わせてますが、コード以外の部分の問題はテストしきれません。その場合はステージング環境などをデプロイして、修正して、デプロイしてという繰り返しになるのですが、デプロイ一回毎にAWSへの転送とCloudFormationでの構築が走るので、数分程度待ちが発生します。スケジュールが押している時には辛いところです。
裏の動きが見えない
見えないからわからないですが、何回か発生して、辛かったパターン。
修正版をSAMでデプロイしてみたら突然動かない。といっても直したのはログ出力部分だけ
ひとまず、過去動いていたコミットチェクアウトしてデプロイしてみても動かない
もう一個前の動いていたバージョンにしてみてデプロイしても動かない。
よし一旦最初の最新版デプロイして、トイレ行ってから頭冷やしてエラー調査しよう
(5分後帰ってきた)何も問題なく動いている
その後再発無し
最悪なのは2と3を繰り返してしまった時です。気づいたら3時間くらい無駄にして、諦めて家に帰って動かしてみたら動いていた時もありました。当然自分の設定が悪い時もあります。原因がわかるときもあります。原因がわかってないものもあります。完全な切り分けの手順は今のところ持ち合わせていません。
情報収集の難易度が高い
サーバーレス開発は、関連するコンポーネントが多い分、必要な情報量が多くなり、変化のスピードも早いです。まだ新しい分野で、WEBの情報も十分だとは言えないと思います。これらの要因が相まって情報収集の難しい分野だと感じました。
サーバーレス開発で良いと思ったこと
サービスの環境全部をコードで表現できる
Infrastructure as Codeとかの言葉もありますが、今までもAnsibleとかChefとかは使ってきましたが、本当にサービス全てをコードに落とし込む開発を始めて行いました。gitの管理がそのままサービス全体のバージョン管理になります。一つ前のバージョンで、名前変えて環境複製、終わったら削除してみたいなことが、全てコマンド一本です。
処理の特性によっては圧倒的に安い
サービスの特性にもよりますが、処理が散発的に走るようなサービスの場合は圧倒的にコストが安くなる場合があります。実際に開発時のAWSコストはElasticsearch Serviceを使っている部分くらいで、それ以外は本当に小さい。
OSに入らない、入れない
開発で全くOS入らないのは新鮮でした。確かにアプリケーションに集中せざるを得ない状況になります。
有名なサーキットブレイカーみたいなサーバーレスならではの考慮点を意識するのでアプリケーションの組み方は少し大変になるイメージです。言い換えれば開発で運用の問題も先回りして取り除いている感はあります。
もし、初めての開発がサーバーレス開発の人が今後出てくるとしたら、本当にOSの知識無しでサービスを作成できるだろうことは感じました。
運用が楽になる(はず)
すみません。知識だけで経験してないのでわからないです。そろそろ運用フェーズに入り始めるので、そこはまたどこかで書こうと思います。
まとめ
一気に書いてきましたが、読み返すと辛いと嘆いている点が多いですね。
振り返れば辛い辛いと思っていたことが多いですが、タイトルの通りまだまだ使い始めたばかりであることが大きな要因な気がしています。実際に慣れとともに、かなり辛い部分も解消して、最近はストレス無く進められていますし、開発スピードも目に見えて上がりました。
何より、今は運用を始めたばかりなので、運用フェーズのメリットを享受しきれてないので、辛い部分が目立っているのかもしれません。