溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Golang中grpc怎么用

發布時間:2021-12-15 09:27:50 來源:億速云 閱讀:241 作者:小新 欄目:大數據

Golang中gRPC怎么用

1. 什么是gRPC?

gRPC是一個高性能、開源的通用RPC框架,由Google開發。它基于HTTP/2協議,使用Protocol Buffers(簡稱Protobuf)作為接口定義語言(IDL),支持多種編程語言。gRPC的主要特點包括:

  • 高性能:基于HTTP/2,支持雙向流、多路復用等特性,性能優于傳統的RESTful API。
  • 跨語言:支持多種編程語言,如C++、Java、Python、Go等。
  • 強類型:使用Protobuf定義接口,生成強類型的客戶端和服務端代碼。
  • 流式處理:支持單向流、雙向流等流式處理模式。

2. gRPC的核心概念

2.1 Protocol Buffers

Protocol Buffers(簡稱Protobuf)是Google開發的一種輕量級、高效的結構化數據序列化格式。它比XML和JSON更小、更快、更簡單。Protobuf使用.proto文件定義數據結構,然后通過編譯器生成對應語言的代碼。

2.2 服務定義

在gRPC中,服務通過.proto文件定義。一個服務可以包含多個方法,每個方法可以定義請求和響應的消息類型。

2.3 四種服務方法

gRPC支持四種類型的服務方法:

  1. Unary RPC:客戶端發送一個請求,服務器返回一個響應。
  2. Server Streaming RPC:客戶端發送一個請求,服務器返回一個流式響應。
  3. Client Streaming RPC:客戶端發送一個流式請求,服務器返回一個響應。
  4. Bidirectional Streaming RPC:客戶端和服務器都可以發送流式請求和響應。

3. 在Golang中使用gRPC

3.1 安裝gRPC和Protobuf編譯器

首先,我們需要安裝gRPC和Protobuf編譯器。

# 安裝gRPC
go get -u google.golang.org/grpc

# 安裝Protobuf編譯器
go get -u github.com/golang/protobuf/protoc-gen-go

3.2 定義服務

創建一個hello.proto文件,定義一個簡單的服務:

syntax = "proto3";

package hello;

service Greeter {
  rpc SayHello (HelloRequest) returns (HelloResponse);
}

message HelloRequest {
  string name = 1;
}

message HelloResponse {
  string message = 1;
}

3.3 生成代碼

使用protoc編譯器生成Golang代碼:

protoc --go_out=plugins=grpc:. hello.proto

這將生成hello.pb.go文件,其中包含客戶端和服務端的代碼。

3.4 實現服務端

創建一個server.go文件,實現服務端邏輯:

package main

import (
	"context"
	"log"
	"net"

	"google.golang.org/grpc"
	pb "path/to/your/proto/package"
)

type server struct{}

func (s *server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloResponse, error) {
	return &pb.HelloResponse{Message: "Hello " + in.Name}, nil
}

func main() {
	lis, err := net.Listen("tcp", ":50051")
	if err != nil {
		log.Fatalf("failed to listen: %v", err)
	}
	s := grpc.NewServer()
	pb.RegisterGreeterServer(s, &server{})
	if err := s.Serve(lis); err != nil {
		log.Fatalf("failed to serve: %v", err)
	}
}

3.5 實現客戶端

創建一個client.go文件,實現客戶端邏輯:

package main

import (
	"context"
	"log"
	"time"

	"google.golang.org/grpc"
	pb "path/to/your/proto/package"
)

func main() {
	conn, err := grpc.Dial("localhost:50051", grpc.WithInsecure(), grpc.WithBlock())
	if err != nil {
		log.Fatalf("did not connect: %v", err)
	}
	defer conn.Close()
	c := pb.NewGreeterClient(conn)

	ctx, cancel := context.WithTimeout(context.Background(), time.Second)
	defer cancel()
	r, err := c.SayHello(ctx, &pb.HelloRequest{Name: "World"})
	if err != nil {
		log.Fatalf("could not greet: %v", err)
	}
	log.Printf("Greeting: %s", r.Message)
}

3.6 運行服務端和客戶端

首先運行服務端:

go run server.go

然后運行客戶端:

go run client.go

你應該會看到客戶端輸出:

Greeting: Hello World

4. 流式RPC

4.1 Server Streaming RPC

hello.proto中添加一個Server Streaming RPC方法:

service Greeter {
  rpc SayHello (HelloRequest) returns (HelloResponse);
  rpc SayHelloStream (HelloRequest) returns (stream HelloResponse);
}

更新server.go實現流式響應:

func (s *server) SayHelloStream(in *pb.HelloRequest, stream pb.Greeter_SayHelloStreamServer) error {
	for i := 0; i < 5; i++ {
		if err := stream.Send(&pb.HelloResponse{Message: "Hello " + in.Name}); err != nil {
			return err
		}
		time.Sleep(time.Second)
	}
	return nil
}

更新client.go處理流式響應:

stream, err := c.SayHelloStream(ctx, &pb.HelloRequest{Name: "World"})
if err != nil {
	log.Fatalf("could not greet: %v", err)
}
for {
	msg, err := stream.Recv()
	if err == io.EOF {
		break
	}
	if err != nil {
		log.Fatalf("could not receive: %v", err)
	}
	log.Printf("Greeting: %s", msg.Message)
}

4.2 Client Streaming RPC

hello.proto中添加一個Client Streaming RPC方法:

service Greeter {
  rpc SayHello (HelloRequest) returns (HelloResponse);
  rpc SayHelloStream (HelloRequest) returns (stream HelloResponse);
  rpc SayHelloClientStream (stream HelloRequest) returns (HelloResponse);
}

更新server.go實現流式請求處理:

func (s *server) SayHelloClientStream(stream pb.Greeter_SayHelloClientStreamServer) error {
	var names []string
	for {
		req, err := stream.Recv()
		if err == io.EOF {
			return stream.SendAndClose(&pb.HelloResponse{Message: "Hello " + strings.Join(names, ", ")})
		}
		if err != nil {
			return err
		}
		names = append(names, req.Name)
	}
}

更新client.go發送流式請求:

stream, err := c.SayHelloClientStream(ctx)
if err != nil {
	log.Fatalf("could not greet: %v", err)
}
for _, name := range []string{"Alice", "Bob", "Charlie"} {
	if err := stream.Send(&pb.HelloRequest{Name: name}); err != nil {
		log.Fatalf("could not send: %v", err)
	}
}
reply, err := stream.CloseAndRecv()
if err != nil {
	log.Fatalf("could not receive: %v", err)
}
log.Printf("Greeting: %s", reply.Message)

4.3 Bidirectional Streaming RPC

hello.proto中添加一個Bidirectional Streaming RPC方法:

service Greeter {
  rpc SayHello (HelloRequest) returns (HelloResponse);
  rpc SayHelloStream (HelloRequest) returns (stream HelloResponse);
  rpc SayHelloClientStream (stream HelloRequest) returns (HelloResponse);
  rpc SayHelloBidirectionalStream (stream HelloRequest) returns (stream HelloResponse);
}

更新server.go實現雙向流式處理:

func (s *server) SayHelloBidirectionalStream(stream pb.Greeter_SayHelloBidirectionalStreamServer) error {
	for {
		req, err := stream.Recv()
		if err == io.EOF {
			return nil
		}
		if err != nil {
			return err
		}
		if err := stream.Send(&pb.HelloResponse{Message: "Hello " + req.Name}); err != nil {
			return err
		}
	}
}

更新client.go處理雙向流式通信:

stream, err := c.SayHelloBidirectionalStream(ctx)
if err != nil {
	log.Fatalf("could not greet: %v", err)
}
waitc := make(chan struct{})
go func() {
	for {
		msg, err := stream.Recv()
		if err == io.EOF {
			close(waitc)
			return
		}
		if err != nil {
			log.Fatalf("could not receive: %v", err)
		}
		log.Printf("Greeting: %s", msg.Message)
	}
}()
for _, name := range []string{"Alice", "Bob", "Charlie"} {
	if err := stream.Send(&pb.HelloRequest{Name: name}); err != nil {
		log.Fatalf("could not send: %v", err)
	}
}
stream.CloseSend()
<-waitc

5. 總結

本文介紹了如何在Golang中使用gRPC。我們首先了解了gRPC的基本概念,然后通過一個簡單的例子演示了如何定義服務、生成代碼、實現服務端和客戶端。最后,我們探討了gRPC的四種服務方法,包括Unary RPC、Server Streaming RPC、Client Streaming RPC和Bidirectional Streaming RPC。

gRPC是一個功能強大、性能優越的RPC框架,適用于構建高性能、跨語言的分布式系統。通過本文的學習,你應該能夠在Golang中使用gRPC構建自己的服務。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

亚洲午夜精品一区二区_中文无码日韩欧免_久久香蕉精品视频_欧美主播一区二区三区美女