title: 100. Studi Kasus: Arsitektur Microservices Lengkap dengan gRPC di Go
author: Maya Wijaya
date: 2024-06-20
tags: [microservices, golang, grpc, arsitektur, studi kasus, kode, devops]
Pendahuluan
Pada era modern pengembangan perangkat lunak, microservices architecture menjadi standard yang banyak diadopsi oleh perusahaan teknologi skala kecil maupun besar. Salah satu alasan utamanya adalah kemampuan microservices untuk meningkatkan skalabilitas, fleksibilitas teknologi, serta mempercepat deployment fitur baru. Namun, implementasi microservices seringkali menimbulkan tantangan terkait komunikasi antar layanan, otomatisasi, serta orkestrasi deployment. Di artikel ke-100 ini, saya akan membahas studi kasus lengkap arsitektur microservices menggunakan gRPC di Go, lengkap dengan contoh kode, simulasi alur, serta workflow pengembangan.
Studi Kasus: Sistem Pemesanan Online
Sebagai contoh, kita akan membuat sebuah sistem dasar pemesanan online dengan tiga layanan utama:
- User Service: mengelola data pengguna
- Order Service: menangani pemesanan
- Product Service: mengelola data produk
Ketiga layanan ini berkomunikasi secara internal menggunakan gRPC.
Gambaran Arsitektur
Mari kita mulai dengan diagram arsitekturnya:
flowchart TD A[User Service] --gRPC--> B[Order Service] C[Product Service] --gRPC--> B[Order Service] D[Client (REST/GRPC)] --gRPC--> A[User Service] D --gRPC--> B D --gRPC--> C
Dari diagram tersebut, baik user, order, maupun produk berkomunikasi secara peer-to-peer menggunakan gRPC.
Keunggulan gRPC di Microservices Go
Beberapa alasan utama kita memilih gRPC pada microservices Go:
- Performa Tinggi: gRPC menggunakan Protocol Buffers yang sangat cepat dan efisien dibandingkan JSON.
- Tipe Data Ketat: Meminimalisir bug akibat kesalahan tipe data.
- Cross Language: gRPC didukung banyak bahasa pemrograman.
- API Contract: Definisi layanan jelas melalui
.proto, sehingga mudah diintegrasikan antar tim.
1. Definisi Kontrak API: Protobuf
Semua komunikasi diawali dengan mendefinisikan kontrak API pada file .proto. Berikut adalah contoh file order.proto:
syntax = "proto3";
package order;
service OrderService {
rpc CreateOrder (CreateOrderRequest) returns (CreateOrderResponse);
rpc GetOrder (GetOrderRequest) returns (GetOrderResponse);
}
message CreateOrderRequest {
string user_id = 1;
string product_id = 2;
int32 quantity = 3;
}
message CreateOrderResponse {
string order_id = 1;
string status = 2;
}
message GetOrderRequest {
string order_id = 1;
}
message GetOrderResponse {
string order_id = 1;
string user_id = 2;
string product_id = 3;
int32 quantity = 4;
string status = 5;
}
Setiap microservice memiliki file .proto sendiri untuk mendeskripsikan interface publik.
2. Implementasi Layanan gRPC di Go
Setelah menentukan kontrak, kita dapat mengenerate kode Go dari file .proto di atas menggunakan plugin seperti:
protoc --go_out=. --go-grpc_out=. order.proto
Contoh Implementasi Order Service
Mari lihat implementasi sederhana server gRPC dari OrderService:
// order_service.go
package main
import (
"context"
pb "your_project/orderpb"
"log"
"net"
"google.golang.org/grpc"
)
type orderServer struct {
pb.UnimplementedOrderServiceServer
orders map[string]*pb.GetOrderResponse
}
func (s *orderServer) CreateOrder(ctx context.Context, req *pb.CreateOrderRequest) (*pb.CreateOrderResponse, error) {
orderID := "ORD12345" // simulasi autoID
order := &pb.GetOrderResponse{
OrderId: orderID,
UserId: req.UserId,
ProductId: req.ProductId,
Quantity: req.Quantity,
Status: "CREATED",
}
s.orders[orderID] = order
return &pb.CreateOrderResponse{
OrderId: orderID,
Status: order.Status,
}, nil
}
func (s *orderServer) GetOrder(ctx context.Context, req *pb.GetOrderRequest) (*pb.GetOrderResponse, error) {
if order, ok := s.orders[req.OrderId]; ok {
return order, nil
}
return nil, status.Errorf(codes.NotFound, "Order not found")
}
func main() {
lis, err := net.Listen("tcp", ":50052")
if err != nil {
log.Fatalf("failed to listen: %v", err)
}
grpcServer := grpc.NewServer()
pb.RegisterOrderServiceServer(grpcServer, &orderServer{orders: make(map[string]*pb.GetOrderResponse)})
log.Println("Order Service gRPC running on :50052")
grpcServer.Serve(lis)
}
Simulasi Client Order
// order_client.go
package main
import (
"context"
"log"
"time"
pb "your_project/orderpb"
"google.golang.org/grpc"
)
func main() {
conn, err := grpc.Dial(":50052", grpc.WithInsecure())
if err != nil {
log.Fatalf("did not connect: %v", err)
}
defer conn.Close()
client := pb.NewOrderServiceClient(conn)
ctx, cancel := context.WithTimeout(context.Background(), time.Second)
defer cancel()
// Membuat order baru
orderResp, err := client.CreateOrder(ctx, &pb.CreateOrderRequest{
UserId: "USR123",
ProductId: "PRD789",
Quantity: 2,
})
if err != nil {
log.Fatalf("CreateOrder failed: %v", err)
}
log.Printf("CreateOrder Response: OrderID=%s Status=%s", orderResp.OrderId, orderResp.Status)
}
3. Orkestrasi Microservices
Dalam praktik nyata, ketiga layanan (User, Order, Product) akan dijalankan pada port dan host berbeda. Untuk setup lokal, kita dapat menggunakan docker-compose.
Contoh docker-compose.yml
version: "3.8"
services:
user:
build: ./user-service
ports:
- "50051:50051"
order:
build: ./order-service
ports:
- "50052:50052"
product:
build: ./product-service
ports:
- "50053:50053"
4. Simulasi Alur Pemesanan
Mari gambarkan alur proses pesanan dari client hingga selesai via mermaid:
sequenceDiagram participant Client participant UserService participant OrderService participant ProductService Client->>UserService: Validate User UserService-->>Client: OK Client->>ProductService: Check Product & Stock ProductService-->>Client: OK Client->>OrderService: CreateOrder(UserID, ProductID, Qty) OrderService-->>Client: OrderID, Status
5. Perbandingan gRPC vs REST (Tabel)
| Fitur | gRPC | REST |
|---|---|---|
| Payload | Protocol Buffers | JSON |
| Speed | Sangat cepat | Lebih lambat |
| Contract | Strongly Typed | Flexible |
| Streaming | Ya | Sulit |
| Binary Support | Native | Tidak |
| Language Support | Multi (Auto-gen) | Semua |
| Backward Comp | Lebih Mudah | Bergantung |
6. Best Practices
Beberapa tips penerapan arsitektur microservices gRPC di Go:
- Gunakan context dan timeout untuk semua RPC.
- Handle error dengan jelas pada setiap layanan.
- Terapkan observability: tracing & monitoring (OpenTelemetry, Prometheus).
- Gunakan central registry/discovery service saat production (misal Etcd, Consul).
- Terapkan Protobuf versioning yang baik.
Kesimpulan
Pada studi kasus ini, kita telah melihat bagaimana membangun arsitektur microservices dengan gRPC di Go dari mendefinisikan API contract, implementasi service, orchestrasi hingga simulasi workflow antar service. Dengan gRPC, kita mendapatkan performa, keamanan, dan maintainability yang lebih baik—sangat cocok untuk skala enterprise. Untuk pengembangan lebih lanjut, silakan tambahkan authentication JWT, circuit breaker, dan monitoring ke setiap service Anda!
Selamat bereksperimen dengan arsitektur microservices modern!
Referensi
Happy hacking 🍃