Meningkatkan performa service SOAP dari dua sisi: tuning client dengan connection pooling, timeout, retry policy, dan caching response, serta tuning server dengan thread pool, batas ukuran payload, dan monitoring untuk mencegah salah satu mitra menurunkan layanan.

Setelah di episode 11 kita mengoptimasi transmisi biner, sekarang kita bahas performansi — tetapi dengan sudut pandang yang sering dilupakan developer SOAP: performansi bukan hanya kecepatan, melainkan keandalan di bawah beban. Service SOAP yang melayani integrasi B2B bisa menerima ribuan request per menit dari banyak mitra sekaligus.
Mengapa penting? Karena SOAP itu berat: XML parsing, validasi XSD, dan (sering) signing/encryption menghabiskan CPU. Tanpa tuning, satu mitra yang mengirim request besar bisa menghabiskan seluruh thread pool dan membuat semua mitra lain menunggu. Episode ini mengajarkan kalian mempertahankan performansi dari sisi client dan server.
Membuat koneksi HTTP baru untuk setiap request mahal (handshake TLS + TCP). Client yang baik memakai connection pool dan memakai ulang koneksi:
import org.apache.cxf.transport.http.HTTPConduit;
import org.apache.cxf.transports.http.configuration.HTTPClientPolicy;
HTTPConduit conduit = (HTTPConduit) client.getConduit();
HTTPClientPolicy policy = conduit.getClient();
policy.setConnectionTimeout(5000); // 5 detik koneksi
policy.setReceiveTimeout(15000); // 15 detik menunggu response
policy.setMaxRetransmits(2); // retry maksimal 2xSatu client instance (dan satu pool) sebaiknya di-reuse sepanjang hidup aplikasi, bukan dibuat per request.
Timeout adalah perlindungan pertama dari service yang membeku. Aturan praktis:
Retry harus bijak — retry yang salah memperburuk beban server yang sedang down (efek thundering herd). Pola yang benar:
Request gagal
├── Sender/Client fault -> JANGAN retry (request salah)
├── Receiver/Server fault -> Retry dengan backoff (mis. 1s, 2s, 4s)
├── Network timeout -> Retry dengan backoff, batasi jumlah
└── Non-idempotent op -> JANGAN retry otomatis tanpa idempotencyKombinasikan dengan jitter (variasi acak pada jeda retry) agar retry dari banyak client tidak datang bersamaan.
Untuk data yang jarang berubah (rate limit policy, kode negara, status), caching menyelamatkan server dari pekerjaan berulang:
import time
_cache = {}
def get_cached(key, ttl=60):
now = time.time()
item = _cache.get(key)
if item and now - item[0] < ttl:
return item[1]
value = client.service.getExchangeRate("USD", "IDR")
_cache[key] = (now, value)
return valueTip
Hanya cache operasi yang idempotent dan toleran staleness — misalnya lookup, kurs, status. Jangan pernah cache operasi transfer uang atau klaim. Cache response SOAP biasanya kunci di level aplikasi, bukan header HTTP, karena SOAP tidak memakai mekanisme cache HTTP standar.
Server SOAP menerima request, memproses, membalas. Jumlah worker thread menentukan berapa banyak request yang bisa berjalan paralel:
<Connector port="8080" protocol="HTTP/1.1"
maxThreads="200"
acceptCount="100"
connectionTimeout="20000"/>Riset kunci: maxThreads yang terlalu kecil membuat request mengantre; yang terlalu besar membuat memory jebol. Pantau lalu sesuaikan — jangan tebak.
Tanpa batasan, siapa pun bisa mengirim XML raksasa dan memenuhi memory. Batasi di layer transport:
<Connector port="8080" protocol="HTTP/1.1"
maxPostSize="5242880"/>5 MB default maxPostSize sering terlalu kecil untuk MTOM (episode 11) — sesuaikan dengan ukuran dokumen maksimal bisnis kalian, tetapi tetap ada batasnya. Batasi juga di layer aplikasi (mis. di interceptor CXF) untuk validasi yang lebih presisi.
Server yang baik memperlakukan mitra secara adil. Rate limiting per identitas (IP atau token) mencegah satu mitra yang error mengganggu yang lain — ini tema yang kita dalami di episode 20 (API gateway).
Tanpa monitoring, tuning adalah menebak. Metrik minimum yang wajib ada:
| Metrik | Menjawab pertanyaan |
|---|---|
| Latency (p50, p95, p99) | Seberapa cepat service merespons? |
| Throughput (request/detik) | Berapa banyak beban yang ditangani? |
| Error rate (fault/request) | Apakah service sehat? |
| Thread pool utilization | Apakah worker kehabisan? |
| Memory/GC (Java) | Apakah perlu scale up? |
Kita bahas observability SOAP lebih dalam di episode 13.
Warning
Timeout di server dan retry di client adalah dua sisi yang harus selaras. Jika client menunggu 30 detik tapi server memproses selama 60 detik, setiap request timeout akan menghasilkan retry — dan request yang sebenarnya sedang diproses jadi berjalan dua kali. Desain timeout berdasarkan SLO operasi, bukan tebakan.
for i in $(seq 1 20); do
curl -s -o /dev/null -w "%{time_total}\n" \
-X POST http://localhost:8080/bank \
-H 'Content-Type: text/xml' \
--data-binary @request.xml &
done
waitRata-ratakan time_total untuk baseline sebelum dan sesudah tuning. Inilah cara paling sederhana mengukur dampak perubahan.
Inti yang harus dibawa pulang:
Di episode 13 selanjutnya kita akan membahas logging, monitoring & troubleshooting — log payload + header SOAP, tracing dengan correlation ID, TCP/IP monitor dan SoapUI, -Djavax.net.debug untuk masalah TLS, serta pengecekan WS-I compliance. Sampai jumpa di episode 13!