0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

gRPC クライアント接続の新旧比較 – grpc.Dial と grpc.NewClient の違いと移行の経緯

Posted at

概要

この記事では、gRPC クライアントの接続方法として利用されてきた grpc.Dial と、最近推奨される grpc.NewClient について、入門者向けに解説します。なぜ grpc.Dial が非推奨となったのか、その経緯と新しい API の使い方も含めて整理しました。

1. gRPC クライアント接続の基本

grpc.Dial とは?

  • 概要:
    従来の gRPC クライアント接続作成の標準APIです。

    conn, err := grpc.Dial("localhost:50051",
        grpc.WithTransportCredentials(insecure.NewCredentials()),
        grpc.WithBlock(), // (オプション:接続が確立するまでブロック)
    )
    

    このように使用し、即座に接続を確立(またはブロックして待つ)することができます。

  • 特徴:

    • 同期的に接続を試みる(grpc.WithBlock を指定した場合)
    • デフォルトのスキームは、内部では passthrough が利用されることが多い
    • 多くの既存コードやチュートリアルで採用されています

grpc.NewClient とは?

  • 概要:
    最近導入された新しい gRPC クライアント接続作成の API です。

    conn, err := grpc.NewClient("dns:///localhost:50051",
        grpc.WithTransportCredentials(insecure.NewCredentials()),
    )
    if err != nil {
        // エラーハンドリング
    }
    // NewClient は接続を遅延開始するので、必要に応じて明示的に接続を開始
    conn.Connect()
    
  • 特徴:

    • 非同期に接続を開始し、後から明示的に Connect() で接続を確立する設計になっています
    • デフォルトスキームが dns になっており、クラウド環境などでの名前解決を前提としています
    • 柔軟な接続管理が可能になり、将来の機能拡張や効率改善を見据えた API となっています

2. なぜ grpc.Dial は非推奨になったのか?

背景と経緯

  1. 非同期接続の要求:
    従来の grpc.Dial は、grpc.WithBlock を指定すれば同期的に接続を試みるため、接続確立までブロックするという動作がありました。しかし、現代の多くの環境では、非同期に接続を開始し、必要なタイミングで接続状態を確認するほうが柔軟です。

  2. デフォルトスキームの変更:
    grpc.Dial は、デフォルトで passthrough スキームを利用するケースがありました。
    一方、クラウド環境やコンテナ環境では、サービスディスカバリのために DNS を使うことが一般的になっているため、grpc.NewClient ではデフォルトスキームが dns に変更されています。
    これにより、環境に合わせた接続の仕組みが提供されます。

  3. API の一貫性と将来性:
    gRPC チームは、より効率的で柔軟な接続管理を可能にするために、新しい API を導入しました。
    将来的に接続の再試行や動的な接続管理の仕組みが強化されることを見据え、旧 API を段階的に非推奨とし、移行を促しています。

非推奨の警告

  • 警告例:
    grpc.Dial is deprecated: use NewClient instead. Will be supported throughout 1.x.
    
    このように、将来的なサポートを前提に、新しい API への移行が推奨されています。

3. grpc.NewClient の使い方(入門者向けサンプル)

以下は、grpc.NewClient を使って gRPC サーバーに接続するサンプルコードです。
※ サンプルコード内のターゲット URI や認証設定は適宜調整してください。

package main

import (
    "context"
    "log"
    "time"

    "google.golang.org/grpc"
    "google.golang.org/grpc/credentials/insecure"
    pb "github.com/yourusername/yourproject/proto/hello"
)

func main() {
    // NewClient の使用(デフォルトは dns スキーム)
    conn, err := grpc.NewClient("dns:///localhost:50051",
        grpc.WithTransportCredentials(insecure.NewCredentials()),
    )
    if err != nil {
        log.Fatalf("Failed to create client: %v", err)
    }
    defer conn.Close()

    // 明示的に接続開始(NewClient は接続を遅延開始するため)
    conn.Connect()

    // 接続状態を確認(例: 最大5秒待機)
    ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
    defer cancel()
    for {
        state := conn.GetState().String()
        log.Printf("Current state: %s", state)
        if state == "READY" {
            break
        }
        if !conn.WaitForStateChange(ctx, conn.GetState()) {
            log.Fatalf("Connection failed to become READY within timeout")
        }
    }
    log.Println("Client connected successfully")

    // gRPC サービスクライアントの生成と RPC 呼び出し
    client := pb.NewGreeterClient(conn)
    res, err := client.SayHello(context.Background(), &pb.HelloRequest{Name: "Gopher"})
    if err != nil {
        log.Fatalf("RPC error: %v", err)
    }
    log.Printf("Server response: %s", res.Message)
}

補足説明

  • スキームの選択:
    上記の例では dns:///localhost:50051 としています。
    ローカル開発の場合、場合によっては passthrough:///localhost:50051 の方がうまく動作することもあります

  • 非同期接続:
    grpc.NewClient はすぐには接続しないので、Connect() を呼んで接続開始を促し、その後接続状態を監視しています。
    これにより、接続が READY 状態になるまで待機できます

4. まとめ

  • grpc.Dial と grpc.NewClient の違い:
    • grpc.Dial: 従来の同期的な接続(必要に応じてブロック)をサポート。
    • grpc.NewClient: 非同期に接続を開始し、柔軟な接続管理が可能。
      • デフォルトスキームが dns になっているため、クラウド環境に適している。
  • なぜ grpc.Dial が非推奨になったのか:
    非同期接続の要件、デフォルトスキームの変更、将来的な API 拡張と一貫性のため、grpc チームはより柔軟な grpc.NewClient への移行を推奨しています。

これらのポイントを押さえて、今後のプロジェクトでは新しい API を使って、効率的で信頼性の高い gRPC クライアント接続を実現してください。

参考リンク

gRPC Go のアンチパターン(英語)


この内容を参考に、ぜひ新しい API を試してみてください。質問や不明点があればコメントでお知らせください!

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?