- Java 8 / Netty 3 gateway · ~5k sockets/VM · 32 vCPU vertical scale
- C/C++ custom wire-format parser · gcc 4.8 · shared-memory IPC
- PostgreSQL 11 · streaming replication · ~15 min manual failover
- RHEL 7/8 VMs · handcrafted HA pair per region
Microsoft WorkshopPlus · Instructor-led · L200 → L300 (L400 stretch)
Replatforming a Real-Time Messaging System to AKS
A hands-on workshop that moves a 20-year-old socket-based real-time messaging platform — Java gateway, C/C++ parser over HTTPS (REST/JSON), PostgreSQL on RHEL VMs — onto containers on Azure Kubernetes Service, against the latency, throughput, and availability targets a real-time messaging bus demands.
- 2.4B
- messages / month moved
- 180k
- concurrent client sockets
- <250 ms
- P99 round-trip SLO
- 99.99%
- global availability target
The scenario in one paragraph
Skybridge Messaging Services runs a real-time messaging bus over persistent TCP sockets: a Java socket gateway holding long-lived connections to client endpoints, a C/C++ message parser reached over HTTPS (REST/JSON) that decodes the wire format and applies routing rules, and a PostgreSQL store for routing tables, journals, and end-of-day reconciliation. Today it runs on RHEL VMs, scaled vertically, patched in place, and failed over by hand.
The board approved a 12-month modernization. This workshop builds the MVP — the first vertical slice that proves the architecture on Azure against realistic load, sufficient to onboard one client partner for a controlled pilot.
gateway-java· Java 21 / Netty · StatefulSet · sticky by socketparser-cpp· C++17 / gcc 13 · KEDA-scaled · A/B by versionops-console· React behind Front Door + WAF (only HTTP surface)- Azure DB for PostgreSQL Flexible Server · ZR HA · geo-replica
Target architecture
Hub-spoke across two regions · private zone-redundant AKS · Istio mesh · GitOps rings · managed observability.
Primary and passive regional deployment
The workshop MVP mapped to concrete Azure services. Each service links to its official Microsoft Learn documentation.
gateway-javaStatefulSet
parser-cppKEDA-scaled
ops-consoleHTTP only
Azure active-active regional deployment
The active-active pattern mapped to Azure services, with both AKS regions serving traffic and each PostgreSQL writer owning a disjoint partner partition.
Design moves the workshop defends
Containerize first, refactor later
The Java gateway and C++ parser ship in containers with no source rewrite — gaining autoscale, GitOps, and zone-survival without a rewrite.
Private API · CNI Overlay · 3 zones · Istio
Connection-oriented workloads stay off a public API server. Overlay scales sockets without VNet exhaustion; Istio adds mTLS and ring-routing.
StatefulSet gateway, sticky by socket
Long-lived TCP behaves poorly behind a rolling Deployment. Stable identities and sticky routing avoid reconnect storms on every push.
Managed PostgreSQL, not in-cluster
State stays out of the cluster. Managed HA, PITR, and geo-replication with an Azure SLA fit this workload better than a self-managed StatefulSet.
A/B by parser, not gateway
The gateway holds socket state; the parser is stateless per message. A/B parser-cpp:v1 vs v2 by Istio header match — sockets never move.
Rings with a human gate
dev → canary → prod, with canary soak and a required PR review plus a manual Argo sync before prod. Every change is traceable.
Nine modules
Each module follows the same shape: outcomes → framing → talk track → participant steps → validation → L400 stretch.
SLIs & SLOs for a socket workload
These aren't HTTP-API metrics. They drive the intrinsic and extrinsic outage modules and the L400 questions.
| SLI | Definition | SLO | Error budget (30d) |
|---|---|---|---|
| Socket establishment success | % of TCP handshakes completing within 2 s | 99.95% | 21m 36s |
| Message round-trip latency | P99 of received-by-gateway → ack-from-parser | <250 ms | latency SLO |
| Parser correctness | % of decoded messages where replay matches input | 99.999% | correctness |
| Ops-console availability | % of /ops/* responses with status < 500 | 99.9% | 43m 12s |
| DR drill | Cross-region failover RTO during a quarterly drill | <5 min | per-drill |
Three delivery shapes, one set of content
WorkshopPlus 3-day
Single team, intensive. Kick-off through cross-region failover and assessment in one tight block.
WorkshopPlus 5-day
For operating teams that can't go offline a full day. One module per day keeps day jobs alive.
Briefing + Lab
Awareness across a larger audience, with a self-paced lab to follow at each participant's pace.
Roles in the room
Lead trainer
Microsoft SME (CSA / FTE / GBB). Drives the narrative, demos hard steps, owns the room.
Co-trainer / TA
Second SME. Unblocks individuals, monitors chat, runs the war-room view.
Participant
Customer engineer (≤12 per cohort). Owns their own lab subscription, executes every step.
Customer sponsor
Architecture / SRE lead. Joins the daily readout, validates the design maps to reality.
Intro to AKS L200
New to containers, Kubernetes, or Azure? Start here. This L200 primer builds the mental model — why, what, and a hands-on lab for each layer — before the L300 modules. Full write-up and labs in Appendix A ↗.
Each layer builds on the last: containers package an app · Kubernetes runs many of them reliably · AKS is Kubernetes run for you on Azure.
1 · Containers L200
Why: kill "works on my machine" — package an app and everything it needs into one portable, lightweight artifact (no whole guest OS like a VM).
What: an isolated process started from an immutable image, built by a Dockerfile, shared via a registry.
How — quick lab: run and build your first image.
docker run --rm hello-world
docker run --rm -d -p 8080:80 nginx # open http://localhost:8080
docker build -t hello-primer:1 . # from your own Dockerfile
2 · Kubernetes L200
Why: run many containers across many hosts and keep them alive — restart, reschedule, scale, and roll out without downtime.
What: a declarative orchestrator — a control plane reconciles your desired state (Pods, Deployments, Services) continuously.
vs containers: a container is a package; Kubernetes is the system that keeps many packages running and reachable, self-healing by default.
kubectl create deployment web --image=nginx --replicas=3
kubectl delete pod <name> # watch it self-heal back to 3
kubectl scale deployment web --replicas=5
3 · Azure Kubernetes L200
Why: drop the burden of running the control plane and plumbing — Azure operates Kubernetes and wires it into identity, networking, secrets, and monitoring.
What: managed Kubernetes on Azure — same kubectl and YAML, with node pools of Azure VMs and Entra, CNI, Key Vault, and Grafana integrated.
vs Kubernetes: the same engine, run and serviced by Azure. Your manifests don't change — the operational burden does.
az aks create -g rg-aks-primer -n aks-primer --node-count 2
az aks get-credentials -g rg-aks-primer -n aks-primer
kubectl expose deployment web --port=80 --type=LoadBalancer
Run the cohort
Start with the trainer guide, send participants the prerequisites, and open the lab guide on day one.