Cloud PubSubなどのgRPCを使ったサービスでrpc error: code = Unavailable desc = transport is closingが出たときの対処方法




gRPC

gRPCはGoogleが開発し、GCPのバックエンドでよく使われている通信プロトコルです。

gRPCはHTTP2.0をベースに作られ、Protocol Buffersを使ってデータをシリアライズし、高速な通信を実現しています。

Googleが開発

gRPCはGoogleが開発し、GCPのいろんなサービスのバックエンドで使われています。

Firebase、Cloud PubSub、Cloud Endpointなどで実際に使われています。

今回はgRCPのアップデートにより思わぬエラーを引き当てたので紹介と解決方法を説明したいと思います。

Cloud PubSubでのエラー

Cloud PubSubを使っていると一日に数十回もエラーを吐くようになったのが始まりでした。エラーの内容は下記です。

rpc error: code = Unavailable desc = transport is closing

コネクションが切れて使えなくなってるみたいですね。けどこれいきなりだったので謎でした。

最近更新されたv1.13.0したものの中にkeepaliveの機能をデフォルトで無効にする処理が入りました。

PubSubのアイドルタイムが長い場合、keepaliveが機能するように設定しないと勝手にコネクションが切られてしまい、予期せぬエラーを発生させてしまいます。

https://github.com/grpc/grpc-go/releases

  • transport: avoid extra work for keepalive when it’s disabled. (#2148)

GolangでのgRPCのkeepalive設定方法

設定方法は簡単でClient生成時にオプションを渡してあげるだけです。

Timeはpingを送る間隔で、デフォルトだと無限になっているので設定しないとpingを送ってくれません。

Timeputはpingのレスポンスが返ってくるまで何秒待つか設定します。デフォルト20秒です。

PermitWithoutStreamはデフォルトfalseでこれをtrueにしないとkeepaliveの機能が有効にならないので気をつけてください。

import (
	"context"

	"cloud.google.com/go/pubsub"
	"google.golang.org/grpc"
	"google.golang.org/grpc/keepalive"
)

keepaliveOption := option.WithGRPCDialOption(grpc.WithKeepaliveParams(keepalive.ClientParameters{
	Time:                              30 * time.Millisecond,
	Timeout:                        20 * time.Millisecond,
	PermitWithoutStream: true,
}))

client, err = pubsub.NewClient(context.Background(), PROJECT_ID, keepaliveOption)

まとめ

GCP関連のサービスは改善のスピードがものすごく早いのでGitHubなどで何が更新されているのかキャッチアップしていくことが必要です。

とくにgRPCは今後よく使われるプロトコルになると思うので学んでおくことをおすすめします。

The following two tabs change content below.

髙妻智一

2013年CyberAgent新卒入社 スマホゲームを作る子会社に所属し、サーバーサイドのエンジニアを担当。2年目の終わりから新規子会社の立ち上げに参加し、サーバーサイドのエンジニアリーダーとしてサービースのリリースから運用までを担当。 2018年仮想通貨のスマホウォレットを提供するGinco Incにブロックチェーンエンジニアとして入社。






よく読まれている関連記事はこちら




コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です