1. Pengantar
Dalam codelab ini, Anda akan menggunakan gRPC-Go untuk membuat klien dan server yang membentuk dasar aplikasi pemetaan rute yang ditulis dalam Go.
Di akhir tutorial, Anda akan memiliki klien yang terhubung ke server jarak jauh menggunakan gRPC untuk mendapatkan nama atau alamat pos dari apa yang terletak di koordinat tertentu pada peta. Aplikasi yang berfungsi penuh dapat menggunakan desain klien-server ini untuk menghitung atau meringkas lokasi menarik di sepanjang rute.
Layanan ini ditentukan dalam file Protocol Buffers, yang akan digunakan untuk membuat kode boilerplate bagi klien dan server sehingga keduanya dapat berkomunikasi satu sama lain, sehingga menghemat waktu dan upaya Anda dalam menerapkan fungsi tersebut.
Kode yang dihasilkan ini tidak hanya menangani kompleksitas komunikasi antara server dan klien, tetapi juga serialisasi dan deserialisasi data.
Yang akan Anda pelajari
- Cara menggunakan Protocol Buffers untuk menentukan API layanan.
- Cara membangun klien dan server berbasis gRPC dari definisi Protocol Buffers menggunakan pembuatan kode otomatis.
- Pemahaman tentang komunikasi klien-server dengan gRPC.
Codelab ini ditujukan bagi developer Go yang baru menggunakan gRPC atau ingin mempelajari kembali gRPC, atau siapa pun yang tertarik untuk membangun sistem terdistribusi. Tidak diperlukan pengalaman gRPC sebelumnya.
2. Sebelum memulai
Prasyarat
Pastikan Anda telah menginstal berikut ini:
- Rangkaian alat Go versi 1.24.5 atau yang lebih baru. Untuk mengetahui petunjuk penginstalan, lihat Mulai Go.
- Compiler buffer protokol,
protoc
, versi 3.27.1 atau yang lebih baru. Untuk mengetahui petunjuk penginstalan, lihat panduan penginstalan compiler. - Plugin compiler buffering protokol untuk Go dan gRPC. Untuk menginstal plugin ini, jalankan perintah berikut:
go install google.golang.org/protobuf/cmd/protoc-gen-go@latest go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest
Perbarui variabel PATH
agar compiler buffer protokol dapat menemukan plugin:
export PATH="$PATH:$(go env GOPATH)/bin"
Mendapatkan kode
Agar Anda tidak perlu memulai dari awal, codelab ini menyediakan kerangka kode sumber aplikasi yang dapat Anda selesaikan. Langkah-langkah berikut akan menunjukkan cara menyelesaikan aplikasi, termasuk menggunakan plugin compiler buffer protokol untuk membuat kode gRPC boilerplate.
Download kode sumber ini sebagai arsip .ZIP dari GitHub dan ekstrak isinya.
Atau, kode sumber yang telah selesai tersedia di GitHub jika Anda ingin melewati pengetikan implementasi.
3. Menentukan layanan
Langkah pertama Anda adalah menentukan layanan gRPC aplikasi, metode RPC, serta jenis pesan permintaan dan responsnya menggunakan Protocol Buffers. Layanan Anda akan menyediakan:
- Metode RPC yang disebut
GetFeature
yang diimplementasikan server dan dipanggil klien. - Jenis pesan
Point
danFeature
yang merupakan struktur data yang dipertukarkan antara klien dan server saat menggunakan metodeGetFeature
. Klien memberikan koordinat peta sebagaiPoint
dalam permintaanGetFeature
ke server, dan server membalas denganFeature
yang sesuai yang menjelaskan apa pun yang berada di koordinat tersebut.
Metode RPC ini dan jenis pesannya akan ditentukan dalam file routeguide/route_guide.proto
kode sumber yang diberikan.
Protocol Buffers biasanya dikenal sebagai protobuf. Untuk mengetahui informasi selengkapnya tentang terminologi gRPC, lihat Konsep inti, arsitektur, dan siklus proses gRPC.
Jenis pesan
Dalam file routeguide/route_guide.proto
kode sumber, tentukan terlebih dahulu jenis pesan Point
. Point
mewakili pasangan koordinat lintang-bujur di peta. Untuk codelab ini, gunakan bilangan bulat untuk koordinat:
message Point {
int32 latitude = 1;
int32 longitude = 2;
}
Angka 1
dan 2
adalah nomor ID unik untuk setiap kolom dalam struktur message
.
Selanjutnya, tentukan jenis pesan Feature
. Feature
menggunakan kolom string
untuk nama atau alamat pos sesuatu di lokasi yang ditentukan oleh Point
:
message Feature {
// The name or address of the feature.
string name = 1;
// The point where the feature is located.
Point location = 2;
}
Metode layanan
File route_guide.proto
memiliki struktur service
bernama RouteGuide
yang menentukan satu atau beberapa metode yang disediakan oleh layanan aplikasi.
Tambahkan metode rpc
GetFeature
di dalam definisi RouteGuide
. Seperti yang dijelaskan sebelumnya, metode ini akan mencari nama atau alamat lokasi dari sekumpulan koordinat tertentu, jadi buat GetFeature
menampilkan Feature
untuk Point
tertentu:
service RouteGuide {
// Definition of the service goes here
// Obtains the feature at a given position.
rpc GetFeature(Point) returns (Feature) {}
}
Ini adalah metode RPC unary: RPC sederhana di mana klien mengirim permintaan ke server dan menunggu respons kembali, seperti panggilan fungsi lokal.
4. Buat kode klien dan server
Selanjutnya, buat kode gRPC boilerplate untuk klien dan server dari file .proto
menggunakan compiler protocol buffer. Di direktori routeguide
, jalankan:
protoc --go_out=. --go_opt=paths=source_relative \ --go-grpc_out=. --go-grpc_opt=paths=source_relative \ route_guide.proto
Perintah ini akan menghasilkan file berikut:
route_guide.pb.go
, yang berisi fungsi untuk membuat jenis pesan aplikasi dan mengakses datanya.route_guide_grpc.pb.go
, yang berisi fungsi yang digunakan klien untuk memanggil metode gRPC jarak jauh layanan, dan fungsi yang digunakan oleh server untuk menyediakan layanan jarak jauh tersebut.
Selanjutnya, kita akan menerapkan metode GetFeature
di sisi server, sehingga saat klien mengirim permintaan, server dapat membalas dengan jawaban.
5. Menerapkan layanan
Fungsi GetFeature
di sisi server adalah tempat pekerjaan utama dilakukan: fungsi ini mengambil pesan Point
dari klien dan menampilkan informasi lokasi yang sesuai dari daftar tempat yang diketahui dalam pesan Feature
. Berikut penerapan fungsi di server/server.go
:
func (s *routeGuideServer) GetFeature(ctx context.Context, point *pb.Point) (*pb.Feature, error) {
for _, feature := range s.savedFeatures {
if proto.Equal(feature.Location, point) {
return feature, nil
}
}
// No feature was found, return an unnamed feature
return &pb.Feature{Location: point}, nil
}
Saat metode ini dipanggil setelah permintaan dari klien jarak jauh, fungsi akan meneruskan objek Context
yang menjelaskan panggilan RPC, dan objek buffer protokol Point
dari permintaan klien tersebut. Fungsi ini menampilkan objek buffer protokol Feature
untuk lokasi yang dicari dan error
jika diperlukan.
Dalam metode ini, isi objek Feature
dengan informasi yang sesuai untuk Point
yang diberikan, lalu return
bersama dengan error nil
untuk memberi tahu gRPC bahwa Anda telah selesai menangani RPC dan objek Feature
dapat ditampilkan ke klien.
Metode GetFeature
memerlukan pembuatan dan pendaftaran objek routeGuideServer
sehingga permintaan dari klien untuk penelusuran lokasi dapat dirutekan ke fungsi tersebut. Hal ini dilakukan di main()
:
func main() {
flag.Parse()
lis, err := net.Listen("tcp", fmt.Sprintf("localhost:%d", *port))
if err != nil {
log.Fatalf("failed to listen: %v", err)
}
var opts []grpc.ServerOption
grpcServer := grpc.NewServer(opts...)
s := &routeGuideServer{}
s.loadFeatures()
pb.RegisterRouteGuideServer(grpcServer, s)
grpcServer.Serve(lis)
}
Berikut yang terjadi di main()
, langkah demi langkah:
- Tentukan port TCP yang akan digunakan untuk memproses permintaan klien jarak jauh, menggunakan
lis, err := net.Listen(...)
. Secara default, aplikasi menggunakan port TCP50051
seperti yang ditentukan oleh variabelport
atau dengan meneruskan tombol--port
di command line saat menjalankan server. Jika port TCP tidak dapat dibuka, aplikasi akan berakhir dengan error fatal. - Buat instance server gRPC menggunakan
grpc.NewServer(...)
, dan beri nama instance inigrpcServer
. - Buat pointer ke
routeGuideServer
, struktur yang merepresentasikan layanan API aplikasi, dengan memberi nama pointers.
- Gunakan
s.loadFeatures()
untuk mengisi arrays.savedFeatures
dengan lokasi yang dapat dicari melaluiGetFeature
. - Daftarkan layanan API dengan server gRPC sehingga panggilan RPC ke
GetFeature
dirutekan ke fungsi yang sesuai. - Panggil
Serve()
di server dengan detail port kami untuk melakukan penantian pemblokiran permintaan klien; ini berlanjut hingga proses dihentikan atauStop()
dipanggil.
Fungsi loadFeatures()
mendapatkan pemetaan koordinat ke lokasi dari server/testdata.go
.
6. Buat klien
Sekarang edit client/client.go
, tempat Anda akan menerapkan kode klien.
Untuk memanggil metode layanan jarak jauh, kita harus membuat channel gRPC terlebih dahulu untuk berkomunikasi dengan server. Kita membuatnya dengan meneruskan string URI target server (yang dalam hal ini hanyalah alamat dan nomor port) ke grpc.NewClient()
dalam fungsi main()
klien sebagai berikut:
conn, err := grpc.NewClient("dns:///"+*serverAddr, grpc.WithTransportCredentials(insecure.NewCredentials()))
if err != nil {
log.Fatalf("fail to dial: %v", err)
}
defer conn.Close()
Alamat server, yang ditentukan oleh variabel serverAddr
, secara default adalah localhost:50051
, dan dapat diganti oleh switch --addr
di command line saat menjalankan klien.
Jika klien perlu terhubung ke layanan yang memerlukan kredensial autentikasi, seperti kredensial TLS atau JWT, klien dapat meneruskan objek DialOptions
sebagai parameter ke grpc.NewClient
yang berisi kredensial yang diperlukan. Layanan RouteGuide
tidak memerlukan kredensial apa pun.
Setelah channel gRPC disiapkan, kita memerlukan stub klien untuk melakukan RPC melalui panggilan fungsi Go. Kita mendapatkan stub menggunakan metode NewRouteGuideClient
yang disediakan oleh file route_guide_grpc.pb.go
yang dihasilkan dari file .proto
aplikasi.
import (pb "github.com/grpc-ecosystem/codelabs/getting_started_unary/routeguide")
client := pb.NewRouteGuideClient(conn)
Panggil metode layanan
Di gRPC-Go, RPC beroperasi dalam mode pemblokiran/sinkron, yang berarti bahwa panggilan RPC menunggu server merespons, dan akan menampilkan respons atau error.
RPC Sederhana
Memanggil RPC GetFeature
sederhana hampir sama mudahnya dengan memanggil metode lokal, dalam hal ini client.GetFeature
:
point := &pb.Point{Latitude: 409146138, Longitude: -746188906}
log.Printf("Getting feature for point (%d, %d)", point.Latitude, point.Longitude)
// Call GetFeature method on the client.
feature, err := client.GetFeature(context.TODO(), point)
if err != nil {
log.Fatalf("client.GetFeature failed: %v", err)
}
Klien memanggil metode pada stub yang dibuat sebelumnya. Untuk parameter metode, klien membuat dan mengisi objek buffer protokol permintaan Point
. Anda juga meneruskan objek context.Context
yang memungkinkan kami mengubah perilaku RPC jika perlu, seperti menentukan batas waktu untuk panggilan atau membatalkan RPC yang sedang berjalan. Jika panggilan tidak menampilkan error, klien dapat membaca informasi respons dari server dari nilai yang ditampilkan pertama:
log.Println(feature)
Secara keseluruhan, fungsi main()
klien akan terlihat seperti ini:
func main() {
flag.Parse()
// Set up a connection to the gRPC server.
conn, err := grpc.NewClient("dns:///"+*serverAddr, grpc.WithTransportCredentials(insecure.NewCredentials()))
if err != nil {
log.Fatalf("fail to dial: %v", err)
}
defer conn.Close()
// Create a new RouteGuide stub.
client := pb.NewRouteGuideClient(conn)
point := &pb.Point{Latitude: 409146138, Longitude: -746188906}
log.Printf("Getting feature for point (%d, %d)", point.Latitude, point.Longitude)
// Call GetFeature method on the client.
feature, err := client.GetFeature(context.TODO(), point)
if err != nil {
log.Fatalf("client.GetFeature failed: %v", err)
}
log.Println(feature)
}
7. Cobalah
Pastikan server dan klien berfungsi dengan benar satu sama lain dengan menjalankan perintah berikut di direktori kerja aplikasi:
- Jalankan server di satu terminal:
cd server go run .
- Jalankan klien dari terminal lain:
cd client go run .
Anda akan melihat output seperti ini, dengan stempel waktu yang dihilangkan agar lebih jelas:
Getting feature for point (409146138, -746188906)
name:"Berkshire Valley Management Area Trail, Jefferson, NJ, USA" location:<latitude:409146138 longitude:-746188906 >
Getting feature for point (0, 0)
location:<>
8. Langkah berikutnya
- Pelajari cara kerja gRPC di Pengantar gRPC dan Konsep inti
- Pelajari tutorial Dasar-Dasar.
- Jelajahi referensi API