Carpe Diem

備忘録

gRPC

gRPCで一時的なネットワーク断でのtransportエラーを回避する

背景 gRPCを利用していると、デプロイを含む一時的なネットワーク断で以下のようなエラーが発生することがあります。 rpc error: code = Unavailable desc = connection error: desc = "transport: Error while dialing: dial tcp xxx: connect: connection …

gRPCでFieldMaskを使う(更新編)

概要 christina04.hatenablog.com 前回はFieldMaskを使ってオーバーフェッチを避ける方法を説明しました。 今回はMutation(更新)におけるFieldMaskの活用方法を説明します。 環境 Go v1.18.3 protoc-gen-go v1.25.0 protoc v3.19.4 grpc-go v1.47.0 MongoDB…

gRPCでFieldMaskを使う(取得編)

概要 クライアントデバイスが多様化する中、UIに必要なデータもそれぞれ異なるためAPIのオーバーフェッチ(不要なデータの取りすぎ)が課題になってきます。 またマイクロサービス間の通信でも、例えばマスタ系データのうち必要なデータだけ取得して利用した…

Bazelを使ってみる その4(gRPCのビルド)

概要 Bazel解説第4弾です。 Bazelを使ってみる その1(Goのビルド) - Carpe Diem Bazelを使ってみる その2(protobufのビルド) - Carpe Diem Bazelを使ってみる その3(docker imageのビルド) - Carpe Diem 今回はgRPCをビルドしてみます。 gRPCは2…

gRPCのkeepaliveで気をつけること その2

背景 以前gRPCのkeepaliveについて説明しました。 christina04.hatenablog.com keepaliveの目的は idleコネクションを維持するため 死んだコネクション(TCPハーフオープン)があったら切断し、再接続するため と書きましたが、どちらの検証もアクティブなRP…

gRPCのChannelについて

背景 gRPCにはクライアントとサーバとの通信を抽象化したChannelという仕組みがあります。 GRPC_GO_LOG_SEVERITY_LEVEL=infoを有効にした際に出てくる [core] Channel Created [core] parsed scheme: "" [core] scheme "" not registered, fallback to defau…

gRPCのkeepaliveで気をつけること

概要 gRPCでは1つのHTTP/2コネクション上でstreamを多重化します。 しかしidleなコネクションは、LBなど間に介在するネットワーク機器によって気づいたら切断されているケースがあります。 そうならないよう、定期的にパケット(PINGフレーム)を流して「id…

GoGo Protobufのメリット・デメリット

概要 Goでprotobufのコードを生成する際には公式のgolang/protbuf以外にgogo/protobufが候補に挙がると思います。 メリット 大きなメリットはパフォーマンスとカスタマイズ性です。 marshalling と unmarshalling が高速 去年のベンチマークですが、公式より…

gRPCのヘルスチェック

概要 gRPCサーバのヘルスチェック方法として HTTPサーバを別途立ち上げてHTTPでチェック tcpでポートがopenしたかチェック といった方法がありますが、前者はgRPCサーバなのにHTTPサーバを用意しないといけなかったり、後者はtcpのopenは実際にServe開始した…

gRPCでのLoad Balancing

背景 gRPCでは主に Proxy Model Balancing-aware Client External Load Balancing Service といったLBアプローチがあります。 それぞれの特徴や実装方法を調べてみました。 Load Balancingアプローチ こちらで定義されてます。 grpc/load-balancing.md at ma…

gRPCでのClient-Side LB実装の変遷

概要 gRPCでのバランシングをClient-Sideで直接実装する方法の紹介です。 gRPCはPolyglot(様々な言語で扱う)を意識しているので、gRPC自体の仕様が策定→各言語がそれに則って実装となります。 なので「元々はこういう実装だったけど、他の言語と統一してこ…

gRPCでエラー詳細を渡す方法

概要 以前 christina04.hatenablog.com こちらの記事で、アプリケーション内でのレイヤ間のエラーハンドリングについてまとめました。 ではマイクロサービス間でそのエラーコードを伝播していくのはどうすれば良いのか、というのが今回の主題です。 課題 gRP…

Prometheus でAPIサーバの監視【gRPC】

概要 前回はHTTPのAPIサーバの監視の仕方を説明しました。 christina04.hatenablog.com 今回はgRPCでのメトリクスの作り方を説明します。 環境 Prometheus 2.11.1 Golang 1.12.7 Grafana 6.2.5 prometheus/client_golang 1.0.0 go-grpc-prometheus 1.2.0 メ…

gRPC Unary Interceptorを複数設定した時の実行順序

概要 以前 christina04.hatenablog.com にてgRPCのUnary Interceptorの基本的な使い方を説明しました。 このInterceptorを複数設定したい時に使われるのがgo-grpc-middlewareの出している ChainUnaryServer ChainUnaryClient です。READMEにありますが、以下…

gRPC の Unary Interceptor の基本的な使い方

概要 gRPCのInterceptorのClient側、Server側の基本的な使い方を紹介します。 環境 golang 1.12.0 grpc 1.18.0 Interceptorの種類 以下の4つがあります。今回はUnaryの方の使い方を説明します。 サーバサイド UnaryServerInterceptor StreamServerIntercept…

gRPCで大きなファイルのやり取りをする

概要 gRPCで4MB以上のデータ転送をしようとすると rpc error: code = ResourceExhausted desc = grpc: received message larger than max (xxxxxxx vs. 4194304) のようなエラーが出ます。この上限はデフォルト値なのでgrpc.MaxRecvMsgSize()やgrpc.MaxCallS…

.proto ファイルの整形に clang-format を使う

概要 gRPCで通信しようとすると.protoファイルが沢山出てきます。 ただ人によってインデントが異なったりするのは良くないので、何かしらformatterが無いかなと探したら github.com こちらのissueで「Googleではclang-formatを使ってるよ」という回答があっ…

EnvoyのFrontProxyを用意してgRPCの負荷分散をする

概要 gRPCはHTTP/2プロトコルをベースとしたRPCです。 なのでコネクションが永続化され、その中で複数のストリームがリクエスト・レスポンスを取り扱うため負荷分散に注意する必要があります。 今回はEnvoyというgRPCに向いたproxyを使うことでそれを実現し…

Consulで各サービスのコンテナ群のIPを取得する

概要 以前Consulの基本的な使い方を紹介しました。 christina04.hatenablog.com このConsulに登録する各ノードに対しサービス設定をすることで、各マイクロサービスに所属しているコンテナ群のIPを取得できるようします。 それによってgRPCでの負荷分散とし…

grpc-gatewayでgRPCサーバをRESTで叩けるようにする

概要 gRPCはProtocol Buffersを喋るもの同士ではメリットが大きいですが、RESTしか叩け無いものや、curlでRESTを叩くようにサクッと検証したかったりするときに不便です。 そんな問題を解消してくれるのがgrpc-gatewayで、protobuf定義からREST APIを提供す…

gRPCにおける各RPC方式の実装方法【Bidirectional streaming RPC】

概要 前回の gRPCにおける各RPC方式の実装方法【Client streaming RPC】 - Carpe Diem に引き続き、最後はBidirectional streaming RPCの実装方法を紹介します。 チャットのようなリアルタイム通信や、大きなデータを少しずつ処理したい時、Simple RPCで毎回…

gRPCにおける各RPC方式の実装方法【Client streaming RPC】

概要 前回の gRPCにおける各RPC方式の実装方法【Server streaming RPC】 - Carpe Diem に引き続き、今回はClient streaming RPCの実装方法を紹介します。 こちらは大きなリクエストを分割して送りたい時に有用です。 環境 golang 1.9.2 grpc 1.7.2 protobuf …

gRPCにおける各RPC方式の実装方法【Server streaming RPC】

概要 前回の gRPCにおける各RPC方式の実装方法【Simple RPC】 - Carpe Diem に引き続き、今回はServer streaming RPCの実装方法を紹介します。 サーバ側から複数のレスポンスを送ることができるので、フィードなどをReactiveに取得したい時に使ったり、サー…

gRPCにおける各RPC方式の実装方法【Simple RPC】

概要 gRPCは4つのRPC方式を持っています。 RPC方式 説明 使い所 Unary(Simple) RPC シンプルな1 Request - 1 Response方式 一般的なマイクロサービスなど Server streaming RPC 1 Request - N Response方式 サーバサイドプッシュ・フィードなど Client stre…

protoeasyでprotobufのコンパイルを簡単にする

概要 gRPCなどで使われているprotobufですが、.protoの定義は簡単でもコンパイルにちょっと学習コストがかかります。 gogoprotoやgrpc-gatewayといった他のライブラリも使うと、中々にカオスなコマンドになります。 grpc-gatewayの例 protoc -I/usr/local/in…