2024.12.19
システムの穴を運用でカバーしようとしてミス多発… バグが大量発生、決算が合わない状態から業務効率化を実現するまで
リンクをコピー
記事をブックマーク
松村有倫氏(以下、松村):それでは、「Goでprotocプラグイン作った話」というタイトルで発表します。
自己紹介します。松村有倫と申します。2020年に新卒でDMM.comに入社して、現在はプラットフォーム事業本部の基盤開発グループで働いています。Go歴は1年くらいで、ここ1年間は、Go製プロダクトの保守だったり、プロキシやツールの実装だったりをGoでやってきました。
本日は、運用自動化のためのツールをGoで自作した話をします。「Protocol Buffers」のスキーマ定義からGoのコードを生成するツールです。
それと関連して、GoでGoのコードを生成する時についても少し話せるとよいかなと思っています。よろしくお願いします。
まず、僕が所属している基盤開発グループの紹介からしたいと思います。プラットフォーム事業本部(以下、PF)では、各事業共通で使われる会員基盤だったり、決済基盤だったりをWebAPIで提供していて、僕が所属している基盤開発グループは、それらのAPIの横断処理の部分を担当しています。持ち物のプロダクトとしては、Go製のAPI Gatewayや認可APIなどを持っています。
これ以外にも、PF全体のAPI改善に向けた取り組みも行っていて、最近だと、PF内のDDD推進も行っています。
さて、そんな基盤開発グループですが、最近「API-Gatewayが提供するAPI定義の管理基盤が欲しい」という話が上がってきています。
「APIの追加時にレビューをして、APIの品質を高めていきたい」「管理したデータを活用して各種の自動化みたいなのが行えるとよい」といった部分がモチベーションにつながっています。
そこで、このAPI定義の管理基盤をProtocol BuffersとGitで構築できないか、というプロジェクトを最近は進めています。
「Protocol Buffers」について、少し紹介したいと思います。Protocol Buffersは、Googleが作ったプログラミング言語非依存の通信データのシリアライズフォーマットです。
専用のInterface Definition Language(IDL)で通信スキーマを定義して使うかたちになっています。例えばこんな感じで、「Ping」というサービスがあって、その中にPingというrpcメソッドがあります。リクエストの型がPingReqで、中身の定義は(スライドを示して)こんな感じ。レスポンスはPingRespという型を返して中身は(スライドを示して)こんな感じ。という風に専用のDSLで通信スキーマを定義して使えるものになっています。
今回、API定義の管理フォーマットとしてProtocol Buffersを採用した理由ですが、まず、スキーマ記述言語としてIDLが非常に使いやすかったことが挙げられます。
Protocol BuffersのIDLは部分構造を分けて記述できますし、それ以外でもいろいろと簡素で読みやすいものになっています。あとは、「protoc」というProtocol Buffersのコンパイラによって定義した「スキーマ定義」を幅広く活用できるのも利点の1つだと思います。
すでにスキーマ定義からgRPCを実装したり、ドキュメントを生成したりするツールが世の中にありますし、自分のプラグインで拡張すると、ほかにもさまざまなコード生成が可能になります。
このあたりの特徴から、API定義のフォーマットとして、Protocol Buffersは非常に優秀だと思って、API定義の管理フォーマットとしてProtocol Buffersを採用しました。
今日は「プラグインで拡張すれば、ほかにもさまざまなコード生成が可能」という部分を紹介したいと思います。
例として、「rest-frontend」というAPI-Gateway用のREST/gRPC変換プロキシの話をします。
これが必要になった経緯ですが、API-GatewayとしてRESTのバックエンドとgRPCのバックエンドの両系統をサポートしつつ、一方でクライアントには、共通してRESTで提供する構成を取りたいという話が出てきました。
その過程で、gRPCのバックエンドに対して、RESTとgRPCの変換を行うモジュールとして、API Gatewayの後ろに、rest-frontendという変換プロキシを置くことになりました。
このrest-frontendのコードは、実装に使うコード自体もProtocol Buffersからツールで生成しています。「grpc-gateway」というツールがあって、protobufからサービス定義ごとに、RESTとgRPCの変換を行うプロキシのGo実装を生成してくれます。
コードは、こんな感じになっています。まず、NewServeMuxという関数で、gRPC用のGateway(grpc-gateway用のルータ)の生成を行います。その生成したルーターに対して、ホストを指定してサービスごとにプロキシをマウントしていきます。
例えば、生成のもとになったprotoファイルに「foo」というサービスと「bar」というサービスがある場合、RegisterFooHandlerFromEndpointで、fooのプロキシをマウントして、バックエンドのホストはfoo.example.com。
あとは、barに対して、RegisterBarHandlerFromEndpointという関数でプロキシをマウントして、ホストはbar.example.comみたいに指定します。このように、サービスごとにプロキシをマウントして、最後にhttp.ListenAndServeで、通常のhttp.Handlerとしてlistenすることで、変換プロキシを実装できます。
(スライドを示して)ここですが、grpc-gatewayはそれぞれのサービスごとにgRPCの変換部分のコードを自動生成してくれますが、最後にホストを指定して、ルーターに埋め込む部分は手作業になってしまいます。
このルーティング設定をなんとか自動化できないかと考えました。ホストの設定は、コードに直接埋め込むのではなく、別に管理して注入できるようにしたいという話があったからです。
また、「Gatewayに新規のサービスが追加されるたびに、いちいち作業するのはちょっと面倒くさい」というのもモチベーションだったりします。
今回はprotoファイルの中にサービスの一覧の定義があるので、このルーティング設定の部分も、protocプラグインで自動生成できるのではないかと考えて、プラグインを制作する流れになりました。
ここからは、protocのプラグインの実装について、紹介していきたいと思います。
protocのプラグインの実体ですが、protocと標準入出力で通信する実行形式になっています。この通信フォーマットが、なんとprotobufになっていて、protobufのツールであるprotoc自身にprotobufが使われているという、ちょっとかっこいい作りになっています。
実はプラグインの実装に使える言語は、protobufを解釈できて、実行形式をビルドできるものであれば自由になんでも使えるのですが、今回はGoで実装することにしました。
作りとしては、protocから標準入力経由で、protobuf形式のprotoファイル情報をもらってきます。
それとは別に、プラグインにバックエンドのホスト設定をYAMLの形式で渡して、この2つから情報を抽出して、出力ファイルの情報もprotobuf形式で標準出力に返します。すると、protocがそのレスポンスを標準出力から読み取って、ルーターのコードを生成してくれる流れになります。
使うライブラリですが、Go言語の場合は、google.golang.orgの「protbuf」というモジュールに全部まとまっています。
主に利用するパッケージは3つ。1つ目は「proto」っていうパッケージです。これはprotobufの各種処理をGoから行うためのライブラリです。
2つ目が「types/pluginpb」。これは、protocとプラグインの間の通信に対するメッセージの型を管理するためのパッケージです。
最後が「types/descriptorpb」。protocから渡されてくるprotoファイルの情報を記述するためのメッセージ型を管理するための定義が入ったパッケージです。
(次回へつづく)
2024.12.20
日本の約10倍がん患者が殺到し、病院はキャパオーバー ジャパンハートが描く医療の未来と、カンボジアに新病院を作る理由
2024.12.19
12万通りの「資格の組み合わせ」の中で厳選された60の項目 532の資格を持つ林雄次氏の新刊『資格のかけ算』の見所
2024.12.16
32歳で成績最下位から1年でトップ営業になれた理由 売るテクニックよりも大事な「あり方」
2023.03.21
民間宇宙開発で高まる「飛行機とロケットの衝突」の危機...どうやって回避する?
PR | 2024.12.20
モンスター化したExcelが、ある日突然崩壊 昭和のガス工事会社を生まれ変わらせた、起死回生のノーコード活用術
2024.12.12
会議で発言しやすくなる「心理的安全性」を高めるには ファシリテーションがうまい人の3つの条件
2024.12.18
「社長以外みんな儲かる給与設計」にした理由 経営者たちが語る、優秀な人材集め・会社を発展させるためのヒント
2024.12.17
面接で「後輩を指導できなさそう」と思われる人の伝え方 歳を重ねるほど重視される経験の「ノウハウ化」
2024.12.13
ファシリテーターは「しゃべらないほうがいい」理由 入山章栄氏が語る、心理的安全性の高い場を作るポイント
2024.12.10
メールのラリー回数でわかる「評価されない人」の特徴 職場での評価を下げる行動5選
Climbers Startup JAPAN EXPO 2024 - 秋 -
2024.11.20 - 2024.11.21
『主体的なキャリア形成』を考える~資格のかけ算について〜
2024.12.07 - 2024.12.07
Startup CTO of the year 2024
2024.11.19 - 2024.11.19
社員の力を引き出す経営戦略〜ひとり一人が自ら成長する組織づくり〜
2024.11.20 - 2024.11.20
「確率思考」で未来を見通す 事業を成功に導く意思決定 ~エビデンス・ベースド・マーケティング思考の調査分析で事業に有効な予測手法とは~
2024.11.05 - 2024.11.05