Amalan terbaik untuk menggunakan gRPC untuk melaksanakan penghantaran data serentak di Golang

WBOY
Lepaskan: 2023-07-18 22:17:08
asal
2388 orang telah melayarinya

Amalan terbaik untuk menggunakan gRPC untuk melaksanakan penghantaran data serentak di Golang

Pengenalan:
Dengan pembangunan pengkomputeran awan dan teknologi data besar, permintaan untuk penghantaran data menjadi semakin mendesak. Sebagai rangka kerja panggilan prosedur jauh berprestasi tinggi sumber terbuka Google, gRPC telah menjadi pilihan pertama banyak pembangun kerana kecekapan, fleksibiliti dan ciri merentas bahasanya. Artikel ini akan memperkenalkan amalan terbaik tentang cara menggunakan gRPC untuk melaksanakan penghantaran data serentak di Golang, termasuk pembinaan struktur projek, penggunaan kumpulan sambungan dan pengendalian ralat, dsb.

1. Bina struktur projek
Sebelum mula menggunakan gRPC, kita perlu membina struktur projek yang sesuai untuk menjadikan organisasi dan pengurusan program lebih jelas.

  1. Buat direktori projek
    Pertama, kita perlu mencipta direktori projek untuk menyimpan kod dan fail sumber berkaitan gRPC. Ia boleh disusun mengikut struktur direktori berikut:
myproject
├── api
│   └── myservice.proto
│
├── client
│   ├── client.go
│   └── main.go
│
└── server
    ├── server.go
    ├── handler.go
    └── main.go
Salin selepas log masuk

Antaranya, direktori api digunakan untuk menyimpan definisi antara muka perkhidmatan gRPC, direktori klien menyimpan kod berkaitan klien dan fungsi utama, dan menyimpan direktori pelayan. kod berkaitan pelayan dan fungsi utama.

  1. Tentukan antara muka perkhidmatan
    Buat fail bernama myservice.proto dalam direktori api untuk menentukan antara muka perkhidmatan kami. Kod sampel adalah seperti berikut:
syntax = "proto3";

package myproject;

service MyService {
    rpc GetData (GetDataRequest) returns (GetDataResponse) {}
}

message GetDataRequest {
    string id = 1;
}

message GetDataResponse {
    string data = 1;
}
Salin selepas log masuk

Perkhidmatan bernama MyService ditakrifkan di sini, termasuk kaedah RPC bernama GetData, yang menerima parameter GetDataRequest dan mengembalikan parameter GetDataResponse.

  1. Jana kod
    Laksanakan arahan berikut dalam direktori akar projek untuk menjana fail kod Golang:
protoc --proto_path=./api --go_out=plugins=grpc:./api ./api/myservice.proto 
Salin selepas log masuk

Ini akan menjana fail bernama myservice.pb.go dalam direktori api, yang mengandungi perkhidmatan gRPC dan Definisi mesej dan kod lain yang berkaitan.

2. Cipta pelanggan
Seterusnya kami akan mula menulis kod klien untuk menghantar permintaan serentak ke pelayan dan menerima data yang dikembalikan.

  1. Import dependencies
    Dalam client/main.go, kita perlu mengimport kebergantungan berkaitan dahulu, termasuk gRPC, konteks dan penyegerakan, dsb.:
package main

import (
    "context"
    "log"
    "sync"
    "time"

    "google.golang.org/grpc"
    pb "myproject/api" // 导入生成的代码
)
Salin selepas log masuk
  1. Buat sambungan
    Dalam fungsi utama, kita perlu mencipta sambungan dengan pelayan. Sambungan boleh dibuat menggunakan fungsi grpc.Dial. Kod sampel adalah seperti berikut: grpc.Dial函数来创建连接。示例代码如下:
func main() {
    // 创建连接并指定服务端地址和端口
    conn, err := grpc.Dial("localhost:50051", grpc.WithInsecure())
    if err != nil {
        log.Fatalf("failed to connect: %v", err)
    }
    defer conn.Close()

    // 创建客户端
    client := pb.NewMyServiceClient(conn)
    
    // 发送并发请求
    var wg sync.WaitGroup
    for i := 0; i < 10; i++ {
        wg.Add(1)
        go func(id int) {
            defer wg.Done()

            // 创建上下文和请求
            ctx, cancel := context.WithTimeout(context.Background(), time.Second)
            defer cancel()
            req := &pb.GetDataRequest{
                Id: strconv.Itoa(id),
            }

            // 调用服务端方法
            resp, err := client.GetData(ctx, req)
            if err != nil {
                log.Printf("failed to get data: %v", err)
                return
            }

            // 输出结果
            log.Printf("data: %s", resp.Data)
        }(i)
    }
    
    // 等待所有请求完成
    wg.Wait()
}
Salin selepas log masuk

在上述代码中,我们首先使用grpc.Dial函数创建与服务端的连接。这里采用了不安全的连接模式(Insecure),用于简化示例。实际应用中,建议采用安全的连接模式(Secure)。

然后,我们创建了一个MyServiceClient实例,用于调用服务端的方法。

接下来,我们使用sync.WaitGroup来协调并发请求。在循环中,我们创建了一个匿名函数,用于发起并发请求。在每个并发执行的请求中,我们创建了一个上下文和请求对象,然后调用服务端的方法GetData

最后,我们使用wg.Wait来等待所有的并发请求完成。

三、创建服务端
接下来我们将开始编写服务端的代码,用于接收客户端的请求并返回处理后的数据。

  1. 导入依赖
    在server/main.go中,我们首先需要导入相关的依赖,包括gRPC、log和net等:
package main

import (
    "log"
    "net"

    "google.golang.org/grpc"
    pb "myproject/api" // 导入生成的代码
)
Salin selepas log masuk
  1. 实现接口
    在handler.go中,我们需要实现定义的服务接口。示例代码如下:
package main

import (
    "context"
)

// 定义服务
type MyServiceServer struct{}

// 实现方法
func (s *MyServiceServer) GetData(ctx context.Context, req *pb.GetDataRequest) (*pb.GetDataResponse, error) {
    // 处理请求
    data := "Hello, " + req.Id

    // 构造响应
    resp := &pb.GetDataResponse{
        Data: data,
    }

    return resp, nil
}
Salin selepas log masuk

这里我们实现了MyServiceServer结构体,并实现了GetData方法。在该方法中,我们首先处理请求,然后构造响应并返回。

  1. 创建服务
    在main函数中,我们需要创建并启动gRPC服务。可以使用grpc.NewServer函数来创建服务。示例代码如下:
func main() {
    // 监听TCP端口
    lis, err := net.Listen("tcp", ":50051")
    if err != nil {
        log.Fatalf("failed to listen: %v", err)
    }

    // 创建gRPC服务
    s := grpc.NewServer()

    // 注册服务
    pb.RegisterMyServiceServer(s, &MyServiceServer{})

    // 启动服务
    if err := s.Serve(lis); err != nil {
        log.Fatalf("failed to serve: %v", err)
    }
}
Salin selepas log masuk

在上述代码中,我们首先使用net.Listen函数创建一个TCP监听器,指定监听端口为50051。

然后,我们使用grpc.NewServer函数创建一个gRPC服务,并使用pb.RegisterMyServiceServer方法将我们实现的服务注册到该服务中。

最后,我们使用s.Serve(lis)

package main

// main函数入口
func main() {
    // 注册服务
    pb.RegisterMyServiceServer(s, &MyServiceServer{})
    
    // 启动服务
    if err := s.Serve(lis); err != nil {
        log.Fatalf("failed to serve: %v", err)
    }
}
Salin selepas log masuk

Dalam kod di atas, kami mula-mula menggunakan fungsi grpc.Dial untuk membuat sambungan dengan pelayan. Mod sambungan tidak selamat (Tidak selamat) digunakan di sini untuk memudahkan contoh. Dalam aplikasi praktikal, adalah disyorkan untuk menggunakan mod sambungan selamat (Secure).

Kemudian, kami mencipta contoh MyServiceClient untuk memanggil kaedah sisi pelayan.

Seterusnya, kami menggunakan sync.WaitGroup untuk menyelaraskan permintaan serentak. Dalam gelung, kami mencipta fungsi tanpa nama yang memulakan permintaan serentak. Dalam setiap permintaan yang dilaksanakan secara serentak, kami mencipta objek konteks dan permintaan, dan kemudian memanggil kaedah sebelah pelayan GetData.

Akhir sekali, kami menggunakan wg.Wait untuk menunggu semua permintaan serentak selesai.

3. Buat pelayan

Seterusnya kita akan mula menulis kod pelayan untuk menerima permintaan pelanggan dan mengembalikan data yang diproses.

Import dependencies

Dalam server/main.go, kita perlu mengimport dependencies berkaitan, termasuk gRPC, log dan net, dsb.:

package main

// main函数入口
func main() {
    ctx, cancel := context.WithTimeout(context.Background(), time.Second)
    defer cancel()
    req := &pb.GetDataRequest{
        Id: "1",
    }

    resp, err := client.GetData(ctx, req)
    if err != nil {
        log.Fatalf("failed to get data: %v", err)
    }

    log.Printf("data: %s", resp.Data)
}
Salin selepas log masuk
🎜🎜Laksanakan antara muka🎜Dalam handler.go, kita perlu melaksanakan antara muka perkhidmatan yang ditentukan. Kod sampel adalah seperti berikut: 🎜🎜
go run server/main.go
go run client/main.go
Salin selepas log masuk
🎜Di sini kami melaksanakan struktur MyServiceServer dan melaksanakan kaedah GetData. Dalam kaedah ini, kami mula-mula memproses permintaan, kemudian membina respons dan mengembalikannya. 🎜🎜🎜Buat perkhidmatan🎜Dalam fungsi utama, kita perlu mencipta dan memulakan perkhidmatan gRPC. Perkhidmatan boleh dibuat menggunakan fungsi grpc.NewServer. Kod sampel adalah seperti berikut: 🎜🎜
2021/01/01 15:00:00 data: Hello, 1
Salin selepas log masuk
🎜Dalam kod di atas, kami mula-mula menggunakan fungsi net.Listen untuk mencipta pendengar TCP dan menentukan port mendengar sebagai 50051. 🎜🎜Kemudian, kami menggunakan fungsi grpc.NewServer untuk mencipta perkhidmatan gRPC dan menggunakan kaedah pb.RegisterMyServiceServer untuk mendaftarkan perkhidmatan yang kami laksanakan ke dalam perkhidmatan. 🎜🎜Akhir sekali, kami menggunakan kaedah s.Serve(lis) untuk memulakan perkhidmatan dan mendengar port yang ditentukan. 🎜🎜4. Demonstrasi Contoh Kod🎜 Di bawah ini kami menggunakan contoh lengkap untuk menunjukkan cara menggunakan gRPC untuk melaksanakan penghantaran data serentak di Golang. 🎜🎜Mula-mula, kita perlu menambah kod berikut dalam server/main.go: 🎜rrreee🎜Kemudian, tambah kod berikut dalam client/main.go: 🎜rrreee🎜Akhir sekali, kita boleh melaksanakan arahan berikut dalam direktori akar projek untuk memulakan Pelayan dan pelanggan: 🎜rrreee🎜Keputusan berjalan adalah seperti berikut: 🎜rrreee🎜Dapat dilihat pelayan berjaya menerima permintaan pelanggan dan mengembalikan data yang diproses. 🎜🎜Ringkasan: 🎜Artikel ini memperkenalkan amalan terbaik tentang cara menggunakan gRPC untuk melaksanakan pemindahan data serentak di Golang. Dengan membina struktur projek yang sesuai, mencipta sambungan, melaksanakan antara muka perkhidmatan dan memulakan perkhidmatan, kami boleh menggunakan gRPC dengan mudah untuk penghantaran data serentak. Saya harap artikel ini dapat membantu pembangun yang menggunakan atau akan menggunakan gRPC. 🎜

Atas ialah kandungan terperinci Amalan terbaik untuk menggunakan gRPC untuk melaksanakan penghantaran data serentak di Golang. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Label berkaitan:
sumber:php.cn
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan