Episode ini membangun sistem terintegrasi: background dan hosted services, message brokers seperti RabbitMQ, Kafka, dan Azure Service Bus, integrasi gRPC dan REST antar layanan, serta distributed transactions dan eventual consistency dalam arsitektur terdistribusi.

Aplikasi modern jarang berdiri sendiri. Episode 17 membahas messaging dan integration — bagaimana layanan .NET berkomunikasi, memproses pekerjaan di latar belakang, dan tetap konsisten saat dibagi menjadi banyak layanan.
Kalian akan belajar hosted services untuk pekerjaan background, integrasi dengan message broker seperti RabbitMQ, Kafka, dan Azure Service Bus, komunikasi gRPC dan REST, serta cara menangani konsistensi dalam sistem terdistribusi — di mana transaksi database tunggal tidak lagi cukup.
Hosted service adalah layanan yang berjalan seumur hidup aplikasi di dalam Generic Host. Template worker menyediakan kerangkanya:
dotnet new worker -n OrderWorkerdotnet new worker -n OrderWorker membuat project dengan Worker yang mengimplementasikan BackgroundService — method ExecuteAsync dijalankan segera setelah host mulai, dan dihentikan rapi saat host shut down.
Kelas worker memproses antrean dalam loop:
public class OrderWorker : BackgroundService
{
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
while (!stoppingToken.IsCancellationRequested)
{
await Task.Delay(TimeSpan.FromSeconds(30), stoppingToken);
Console.WriteLine("Cek pesanan baru");
}
}
}ExecuteAsync berjalan terus sampai stoppingToken dibatalkan saat host berhenti. Pola ini dipakai untuk job terjadwal, pembersihan cache, dan integrasi background.
Message broker menengahi komunikasi antar layanan lewat antrean atau topik. Produsen mengirim pesan tanpa menunggu konsumen; konsumen memproses sesuai kecepatannya. Ini memutus kopling waktu antara layanan.
Library MassTransit menyatukan integrasi broker dengan abstraksi yang rapi:
dotnet add package MassTransit
dotnet add package MassTransit.RabbitMQKonfigurasi koneksi:
builder.Services.AddMassTransit(x =>
{
x.UsingRabbitMq((context, cfg) =>
{
cfg.Host("localhost", "/", h =>
{
h.Username("guest");
h.Password("guest");
});
});
});UsingRabbitMq menghubungkan bus ke broker. Setelah terdaftar, layanan bisa mengirim pesan via IPublishEndpoint atau menerima lewat consumer. Mengganti broker (misalnya ke Azure Service Bus) cukup dengan mengubah satu baris konfigurasi — kode bisnis tidak berubah.
Panduan:
gRPC memberi performa tinggi dengan binary protocol untuk komunikasi antar layanan. Definisi kontrak ditulis di file .proto:
syntax = "proto3";
service Katalog {
rpc GetProduk(ProdukId) returns (Produk);
}
message ProdukId { int32 id = 1; }
message Produk { string nama = 1; double harga = 2; }gRPC mengkompilasi file .proto menjadi client dan server C# yang strongly typed. Untuk komunikasi internal antar layanan yang sensitif terhadap latensi, gRPC mengungguli REST karena serialisasi binary dan HTTP/2.
Gunakan REST di batas sistem yang terbuka untuk klien eksternal — browser, mobile, dan partner — karena keterbacaan dan dukungan tooling-nya universal. Pola umum: REST di tepi, gRPC di dalam. Keduanya hidup berdampingan di ASP.NET Core tanpa konflik.
Di microservice, operasi melintasi banyak database — transaksi ACID tunggal tidak berlaku. Solusi pragmatis adalah eventual consistency: sistem mencapai konsistensi setelah jangka waktu tertentu, dengan event sebagai penggeraknya.
public class OutboxMessage
{
public Guid Id { get; set; }
public string Tipe { get; set; }
public string Payload { get; set; }
public bool Dikirim { get; set; }
}Pola transactional outbox menyimpan event dalam tabel yang sama dengan transaksi bisnis, lalu worker mengirimkannya ke broker. Ini menjamin event tidak hilang: jika pengiriman gagal, pesan tetap di outbox dan dicoba lagi.
Untuk alur panjang antar layanan, gunakan saga: setiap langkah punya pasangan kompensasi. Jika langkah gagal, saga menjalankan kompensasi langkah-langkah sebelumnya — misalnya batalkan pesanan jika pembayaran gagal. Konsistensi tercapai secara eventual, bukan atomik.
Tip
Desain pesan agar idempotent: konsumen harus bisa memproses pesan yang sama lebih dari sekali tanpa efek ganda. Ini menyederhanakan retry dan kompensasi secara drastis.
Inti yang harus dibawa pulang:
Di episode 18 selanjutnya kita akan membahas tooling modern dan build automation — dotnet CLI, MSBuild, dan SDK-style projects, continuous integration dengan GitHub Actions, source generators dan Roslyn analyzers, serta code formatting, linting, dan reproducible builds.