74. Integrasi gRPC dengan Envoy Proxy
74. Integrasi gRPC dengan Envoy Proxy
gRPC telah menjadi salah satu pilihan utama dalam membangun layanan microservices yang cepat, efisien, dan mudah dikembangkan. Namun, pada skala produksi, kebutuhan seperti load balancing, service discovery, observability, hingga mTLS sering kali menuntut adanya proxy canggih—dan di sinilah Envoy Proxy hadir sebagai solusi. Dalam artikel ini, saya akan membahas secara praktis bagaimana mengintegrasikan gRPC dengan Envoy Proxy, mulai dari konsep, benefit, hingga contoh implementasi yang bisa langsung kamu coba.
Mengapa Harus Menggunakan Envoy untuk gRPC?
Sebelum masuk ke kode dan simulasi, mari kita telaah alasan di balik keputusan untuk meletakkan Envoy di depan gRPC server:
- gRPC memiliki protocol berbasis HTTP/2 yang tidak selalu kompatibel dengan proxy HTTP konvensional.
- Load balancing cerdas: Envoy mendukung load balancing level aplikasi dan aware terhadap state koneksi HTTP2.
- Observability: Integrasi logging, metrics (Prometheus), dan tracing (Jaeger, Zipkin) menjadi jauh lebih mudah.
- Security: Envoy dapat mengenakan mTLS tanpa perlu memodifikasi aplikasi.
- Network resilience: Dapat mengatur retry, timeouts, circuit breaking, dsb.
Komponen yang Akan Kita Bangun
Skenario sederhana yang akan kita simulasikan:
- Service A: Client aplikasi (gRPC client)
- Envoy Proxy: Sebagai reverse proxy dan load balancer
- Service B: gRPC server (hello world)
- Semua layanan berjalan secara lokal, bisa dengan Docker atau langsung run binary.
Arsitektur High-Level
flowchart LR
subgraph Client Side
A[gRPC Client]
end
subgraph Proxy
B[Envoy Proxy]
end
subgraph Backend
C[gRPC Server]
end
A -- gRPC/HTTP2 --> B
B -- gRPC/HTTP2 --> C
1. Membuat gRPC Service Sederhana
Kita mulai dengan mendefinisikan service sederhana dengan Protocol Buffers:
helloworld.proto
1syntax = "proto3";
2
3package helloworld;
4
5service Greeter {
6 rpc SayHello (HelloRequest) returns (HelloReply);
7}
8
9message HelloRequest {
10 string name = 1;
11}
12
13message HelloReply {
14 string message = 1;
15}Generate kode stub-nya menggunakan protoc. Untuk Go, contohnya:
1protoc --go_out=. --go-grpc_out=. helloworld.protoImplementasi sederhana untuk server (Go):
1// server.go
2package main
3
4import (
5 "context"
6 "log"
7 "net"
8
9 pb "yourmod/helloworld"
10 "google.golang.org/grpc"
11)
12
13type server struct {
14 pb.UnimplementedGreeterServer
15}
16
17func (s *server) SayHello(ctx context.Context, in *pb.HelloRequest) (*pb.HelloReply, error) {
18 return &pb.HelloReply{Message: "Hello, " + in.Name}, nil
19}
20
21func main() {
22 lis, err := net.Listen("tcp", ":50051")
23 if err != nil {
24 log.Fatalf("failed to listen: %v", err)
25 }
26 s := grpc.NewServer()
27 pb.RegisterGreeterServer(s, &server{})
28 log.Println("gRPC server listening on :50051")
29 s.Serve(lis)
30}2. Konfigurasi Envoy Proxy untuk gRPC
Envoy harus diatur untuk memahami protokol HTTP/2. Kita setup sebagai reverse proxy dari port 9901 ke backend gRPC server di 50051.
envoy.yaml:
1static_resources:
2 listeners:
3 - name: listener_0
4 address:
5 socket_address: { address: 0.0.0.0, port_value: 9901 }
6 filter_chains:
7 - filters:
8 - name: envoy.filters.network.http_connection_manager
9 typed_config:
10 "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
11 codec_type: AUTO
12 stat_prefix: ingress_http
13 route_config:
14 name: local_route
15 virtual_hosts:
16 - name: backend
17 domains: ["*"]
18 routes:
19 - match: { prefix: "/" }
20 route: { cluster: greeter_service }
21 http_filters:
22 - name: envoy.filters.http.router
23 # Envoy will use HTTP/2 to proxy the gRPC calls.
24 clusters:
25 - name: greeter_service
26 connect_timeout: 0.25s
27 type: logical_dns
28 lb_policy: round_robin
29 http2_protocol_options: {} # Enables HTTP2 for this cluster
30 load_assignment:
31 cluster_name: greeter_service
32 endpoints:
33 - lb_endpoints:
34 - endpoint:
35 address:
36 socket_address:
37 address: 127.0.0.1
38 port_value: 50051
39admin:
40 access_log_path: "/tmp/admin_access.log"
41 address:
42 socket_address:
43 address: 0.0.0.0
44 port_value: 9900Poin Penting:
- http2_protocol_options: {} menginstruksikan Envoy untuk menggunakan HTTP/2 ketika berbicara ke backend cluster.
- Pastikan cluster mengarah ke port di mana gRPC server berjalan.
- Envoy proxy expose port 9901 (frontend).
3. Membuat Client untuk Terhubung ke Envoy
Implementasi client Go, spesifik konek ke Envoy, buka channel ke localhost:9901:
1// client.go
2package main
3
4import (
5 "context"
6 "log"
7 "time"
8
9 pb "yourmod/helloworld"
10 "google.golang.org/grpc"
11)
12
13func main() {
14 conn, err := grpc.Dial("localhost:9901", grpc.WithInsecure())
15 if err != nil {
16 log.Fatalf("did not connect: %v", err)
17 }
18 defer conn.Close()
19 c := pb.NewGreeterClient(conn)
20
21 ctx, cancel := context.WithTimeout(context.Background(), time.Second)
22 defer cancel()
23 r, err := c.SayHello(ctx, &pb.HelloRequest{Name: "Envoy"})
24 if err != nil {
25 log.Fatalf("could not greet: %v", err)
26 }
27 log.Printf("Greeting: %s", r.Message)
28}Jalankan server, Envoy, lalu client:
1go run server.go
2envoy -c envoy.yaml
3go run client.go4. Simulasi Request Flow
Mari visualisasikan alur request-nya:
sequenceDiagram
participant Client
participant Envoy
participant Server
Client->>Envoy: gRPC Request (SayHello)
Envoy->>Server: gRPC Request (forward)
Server-->>Envoy: gRPC Response
Envoy-->>Client: gRPC Response (relay)
Benefit-nya:
- Client tidak perlu tahu IP/host server gRPC backend
- Bisa scaling server gRPC dan update konfigurasi cluster Envoy secara dinamis
- Observabilitas, circuit breaker, dll bisa langsung kita manfaatkan
5. Studi Kasus: Load Balancing dan Health Checking
Bayangkan kita menambah dua node server di belakang Envoy (misal di port 50051 dan 50052). Cukup ubah bagian load_assignment:
1load_assignment:
2 cluster_name: greeter_service
3 endpoints:
4 - lb_endpoints:
5 - endpoint:
6 address:
7 socket_address:
8 address: 127.0.0.1
9 port_value: 50051
10 - endpoint:
11 address:
12 socket_address:
13 address: 127.0.0.1
14 port_value: 50052Kita juga bisa menambahkan health check:
1health_checks:
2 - timeout: 1s
3 interval: 2s
4 unhealthy_threshold: 2
5 healthy_threshold: 2
6 grpc_health_check: {} # Sesuai standard gRPC health checkTabel ringkas fitur utama Envoy pada integrasi gRPC:
| Fitur | Deskripsi | Konfigurasi |
|---|---|---|
| Load Balancing | Round robin, least request, dll | lb_policy |
| Observability | Metrics Prometheus, tracing | Metrics, Tracing config |
| Security | mTLS, AuthZ, Rate Limiting | tls_context, Filter HTTP |
| Health Checking | Cek status backend, auto-remove instance | health_checks |
| Retry/Timeout | Menjamin resilience | retry_policy, timeout |
6. Kesimpulan, Tantangan, dan Best Practices
Dengan integrasi gRPC dan Envoy Proxy, aplikasi microservices Anda mendapatkan bonus skala, observability, dan security tanpa perlu banyak perubahan di level aplikasi. Namun, ada beberapa catatan penting:
- Selalu menggunakan health check pada cluster backend
- Monitor Envoy metrics untuk understanding traffic dan latency
- Konfigurasikan rate limiting dan circuit breaking secukupnya
- Untuk production, pastikan Envoy berjalan dengan mTLS
- Deployment sebaiknya dilakukan via container orchestration (Kubernetes, Nomad, dsb) untuk hasil optimal
Integrasi ini bukan solusi “one size fits all”, tetapi menawarkan fondasi kokoh untuk service mesh dan scalable platform microservices Anda. Cobalah simulasi sederhana ini di lingkungan lokal Anda, dan eksplorasi lebih lanjut seluruh potensi Envoy di production!
Referensi
Selamat bereksperimen! Jangan ragu share insight dan pertanyaan di kolom komentar.