devsumi LT 2019-07-02
Title: マイクロサービスにおける技術と組織の衝突に向き合う
Introduction
"マイクロサービスは組織論" という言葉が最近よく聞こえる
今回のカンファレンスのテーマ 「エンジニア組織とソフトウェアアーキテクチャを再考する」にもぴったりの話
実はほぼ最初の出典にきちんと書いてある
"Organized around Business Capabilities"
マイクロサービスの理想
ビジネスドメインでモデリングされたサービスに対し、チームが1対1に対応する
各サービスは、ビジネスドメインで切り出される
そのサービスを所有するチームもビジネスドメインに合わせて構成される
コンウェイの法則
システムを設計するあらゆる組織は、必ずその組織のコミュニケーション構造に倣った構造を持つ設計を生み出す
(訳は マイクロサービスアーキテクチャ, Oreilly から引用)
マイクロサービスもこの法則にのっかることでうまくいくとされる
サービスとビジネスチームが一対一対応する
わかってる人は最初から注目している
by @teppeis , Microservices Meetup vol.1 なんと3年前!
マイクロサービスは小さなサービスとビジネスごとの小さなチームを紐づけることが重要と位置付けた上で、「フロントエンドはその組織に含まれるんだっけ?」という鋭い指摘をされている
この議論は海外でもされており、実際に Micro Frontends という考え方に発展している
以下は teppeis さん他2人を迎えて行ったパネルディスカッションのログ。めちゃくちゃ面白いので、興味ある方はぜひ見てください。
最近の "マイクロサービスは組織論" (qsonaの偏見混じる)
"チームを割り当てられないならマイクロサービスを作ってはいけない"
"N人未満の会社ではマイクロサービスを志向してはいけない"
コンウェイの法則原理主義 (カーゴ・カルト的で狭量)
なぜか組織が目的になっている人も
本来は技術・組織の両輪で課題を解決していくものなのに
常にそうできるとは限らないと感じている
現場の経験やさまざまな組織での話を見聞きした経験から
もちろんコンウェイの法則どおりにできるとよいのは前提だが。
きれいごとでは済まない、マイクロサービスの技術と組織が衝突する話を現場の技術者目線で語っていきたい
テーマを一言で表すと "協力の組織デザイン"
話者 (qsona) の紹介
@qsona (FiNC Technologies Inc.) Microservices Meetup 主催
主に現場でサービス開発に関わりながら、横断課題を見つけて解決していく仕事をしている
現在はSREチームに所属
話者の立場
基本的には純技術者(?)としてマイクロサービスを推進してきた
Engineering Managerは未経験
ただし、アーキテクチャを考えていく中で当然組織の問題にぶち当たることは多い
技術目線で見える組織課題を明示し、その解決をこの場のみなさん (想定: 組織マネジメントをしている人、関心がある人) に要請するスタイルで進めます
課題の実例とプラクティス
1. 共有機能サービス
ある1つの機能を、複数のサービスから使うパターン
共有される機能の例
Push通知, アプリ内通知機能
タイムライン
etc... (他にもめっちゃあるし紹介できるが、自社のビジネスのコンテキストが共有されないと伝わりにくいので一旦割愛)
実例: push通知
前提: push通知を担当するサービスが存在する
本当に単にpush通知するだけだったら、マネージドサービスを利用すればよい
実際は「push通知を有効にするかの設定」など、それなりにロジックが存在するので、サービスが必要になるケースが多い
前提: push通知を送りたいビジネス・サービスは複数存在する
https://gyazo.com/592d705f4d88e93a2a5705072d617455
あるビジネスチームAからの要望で、新しく「push通知予約機能」を作りたくなった。
(背景の例) AはtoBのユーザー向けサービスで、深夜帯にpush通知を送りたくなかった。したがって夜に起きた何かについては朝までキューイングしておきたい。
どこに実装するのが正しいか?
1. Aサービス
2. push通知サービス
アーキテクチャの検討
もっとも重要な指標は 高凝集, 疎結合。これはマイクロサービス設計の基本。
Push通知の関心ごとは一箇所に集めたい。
再利用性も高くできそう。
「push通知予約」はAビジネスだけでなく、汎用的に使える機能
push通知サービスに実装するほうが汎用性が高い
ユーザーにも統一した体験を提供できる
例: push通知配信許可する時間を設定できる (TODO)
結論: push通知サービスに実装したほうが良さそう。
技術的なプラクティス
smart endpoint
共通で使われるサービス (ここでいう"push通知サービス") をあまり薄くしすぎず、できる限り頭を寄せるほうが、経験的に失敗しにくい
simple + good defaults
というわけで、アーキテクチャ的には「push通知サービスに実装すべき」と結論づけられるが...
組織の課題 (技術とのコンフリクト)
Push通知チームは存在するのか?
会社の規模や、事業的な優先度、実装・運用の頻度、などによりそう
前提として、Push通知チームを単体で作れるほど潤沢なリソースを持った会社なんてほとんどない! (だよね???)
push通知チームが存在する場合
おそらく、この機能はpush通知チームが実装することになりそう
課題: push通知チームの、他のタスクとの優先度はどうやって調整する?
Push通知チームとしてもやるべきタスクではあるが、今すぐほしいのはBiz Aチーム
なのでとりあえず現存のタスクよりも優先度が低く設定される
Biz Aチームは本来やりたかった企画を遂行できない
もしくはもっと上のレイヤを巻き込んで優先度の議論が行われる
政治戦の様相を呈する
優先度が上げられた場合、Push通知チーム側は「差し込まれた」という感覚、モチベーション低下の原因にも
push通知チームが存在しない場合
Aチームのエンジニアが実装するのは良いけど、保守・運用するのは誰?
プラクティス (組織)
現在の組織構成にそのまま流された実装 (コンウェイの法則どおり) をしない
今push通知のチーム作れなくてもそれが理想とは限らない。もし理想はpush通知をマネジメントするチームが別に存在することだとしたら、今そうできなくてもいいのでその状態を見据えてシステム構成に還元する。漫然とコンウェイの法則に乗るのは愚策。
直接所有しないサービスへのPull Requestを歓迎する
OSSに近い
もちろんOSSより距離は近いので、PR投げる前に設計相談とかしたほうがいいことは多いよ!
(OSSだってそういうことはあるよ!)
「サービスの守り手」のロールを定義する
これについては多分賛否両論ある
マイクロサービスアーキテクチャ (Oreilly) に近い話題の記述がある
フィーチャーチームを大規模に採用すると、...誰もがすべてのサービス、すべてのコードを変更できます。すると、サービス管理者の役割は(もし存在するなら)ずっと複雑です。残念ながら、このパターンを採用している場面で管理者が機能しているのをほとんど見たことはありません。
qsona の経験として、いくつかのサービスの守り手のロールをやってきたので、ワークしないことはないと思う
他のビジネスチームからのPRを受けつける
意識したロール
サービス間をまたがる実装が行われそうなときに情報をキャッチし、設計をアドバイスする
コードレビューやリファクタリングにより最低限の品質を守る
エラー通知の監視
コードレビューはあまり好みを押し付けず、うるさくやらない
必要なら自分でリファクタリング (これはOSSっぽいかも)
設計思想を共有し、属人性をなるべく排除する
時が来たらサービスの所有権を明け渡す
組織マネージャーへの要請
「サービスの守り手」を作るような組織デザインをして欲しい
以下はqsonaが思いつくもの
Job Description
OKRに入れる
カルチャーの明文化
(そういった行動を取れる程度の) 時間的なバッファ
10%は使っていい、みたいなのとか
育成
評価制度の工夫
2. Multi-Sided Platform
複数のユーザーグループに対してプロダクトを提供していく形態
先生/生徒
買う人/売る人
医師/患者
etc...
前提: ほとんどのケースにおいて、各ユーザーグループごとのビジネスチームが出来る
デマンドや、営業/マーケティングが全然違うので、その分け方が自然だしビジネスとしては本質的
課題
組織構造にサービスを一致させる (コンウェイの法則どおり) と、サービスにまたがってデータの共有が必要になる
典型的には共有DBアンチパターンに行き着きがち
https://gyazo.com/01fe9cdd5d998192d28db0dc5f7b6892
"分断されたモノリス"
自分もかなり関心のあるテーマで過去にいろいろ考えてました
Shared Database Pattern Deep Dive という章を書いています
結論としては、マネージする方法はあるけど、避けられるなら避けたほうがいい
プラクティス (技術)
Multi-Sided Platform は モノリスから始めよ
1サービスで複数のマーケット向けプロダクトを提供できるようにする
"ユーザー種別名" サービスを安直に作らない
SPA (Single Page Application) やBFF (Backends for Frontends) なら良い
https://gyazo.com/1e57af883290d506970e76f5b2453dbc
組織マネージャーへの要請
Multi-Sided Platform 事業において、それぞれのユーザー種別ごとにチームが構成されるのはほぼ避けられない
ドメインが交わる部分は技術的にも難易度が高い
調整や協力が必要になることを理解し、問題解決に導いて欲しい
3. サービス横断課題への対処
前提: この項では上の2つの項の議論を一旦さしおき、マイクロサービスとチームが1:1に結びついていると仮定する
マイクロサービスでは、サービス横断的な課題が発生する
横断課題の例: 非機能要件
セキュリティ
トレーシング
系全体の耐障害性
サービスメッシュ
機能要件も横断することがある
実際に取り組んだ例: マスターデータをうまく管理したい
いろんなサービスがそれぞれ独自の方法でマスターデータを管理している
独自の方法にしたいというよりは、そんなに工数とれないから毎度それなりのやり方で作っている
共通のライブラリと管理の仕方を提供することで、全サービスが恩恵を受けられる状態になる
横断課題への対処方法
サービスチーム側で対処する
いわゆる「共通基盤チーム」を作る
共通課題を共通チームが対処ってことでちょっとコンウェイっぽさはあるが
https://gyazo.com/375da67028028e9cc37a3167ec7500f3
課題 (1) プロダクト側で解決する力学が働かない問題
モノリスの場合、1つの問題は多くの人の問題
解決するメリットが大きい
マイクロサービスの場合、問題が各サービスチームに分散している
1つのサービスの課題だけ解決しようとすると、コスパが悪くなりがち
局所最適に陥り、解決されない
課題 (2) 基盤チームがワークしない問題
基盤チームの仕事が、現場に浸透しない (視点・感覚のズレ)
基盤チームに問題が押し付けられがち
基盤チームは専用(専任)である必要はなく、むしろ各チームのエンジニアを出し合って目的ごとに作られるグループであるほうが健全である、というのが私個人の考えだ。
そこだけ切り取ると感じ悪いかなと思ったので控えたが、感謝されてる基盤チームを見たことがないというくだりが本当にそれすぎて
プラクティス (1) サービス側での解決を促す
基本的に、困ってる人が一番モチベーションが高い
横断課題に気づけるための "雑な会話" を増やす
特定の横断課題対処のための一時的なチームを作る (タスクフォース)
なるべくゴールを明確に定め、達成したら解散する
一時的ではなくても、目的が明確な横断組織のほうがワークしやすい
例: "データチーム" や "SRE" はある種の横断組織だが、"共通チーム" に比べたらずっと目的が明確
プラクティス (2) 基盤チームはマイナスを消すべし
基盤チームはプラスを作ろうとすると上手くいかない、マイナスをなくす方が上手くいく。なぜなら現場が困っているから (@sukesan1984)
基盤チームは現場が本当に困っていることを理解し、そこにフォーカスするべき
時にはマイナスを「見せる」努力も必要
例: セキュリティパッチが当たっていないのが常態化している
明らかに「マイナスの状態」であることに気づけていない
そのリスクの大きさを理解し、やらなければいけないこととして扱ってもらう
=> サービスチーム側が、すばやくライブラリを更新してデプロイ出来ることの必要性に気づく
カナリヤリリースなどの横断的施策のありがたみを理解できるきっかけになる
プロダクトと基盤の良い協力の例
データチームは、目的が明確化された横断組織と言える
データチームからtoCチームに "社内留学" し、実際にそこの中で結果を出している
横断組織とビジネス組織が協力して結果を出せているとても良い話
組織マネージャーへの要請
基盤チームとプロダクトチームが協力できる組織デザインをしてほしい
基盤チームがなくても、横断的な問題解決をする動きを活性化してほしい
まとめ: 技術と組織が衝突する時、我々は何を考えるべきか
コンウェイは貴し、コンウェイにたのまず
コンウェイの法則は「組織と技術を揃えるとうまくいく」という示唆でもあるが
「何も考えていないと、組織と技術が揃ってしまう」ということでもある
コンウェイの法則に対し、明確な意図をもってコントロールすることも大事
"サービスやチームを超えた協力" の組織デザイン
マイクロサービスをやる上で、技術(サービス)と組織(チーム)が完全一致するのが理想。
そういうときは普通にうまくいく。
けれど、どうあがいても一致しないケースは出てくる。マイクロサービスだからといって完全に独立するんじゃなく、うまく協力して全体最適にしていくべき。