{"id":30,"date":"2025-11-08T03:09:42","date_gmt":"2025-11-08T03:09:42","guid":{"rendered":"https:\/\/mryelamanchili.dev\/?p=30"},"modified":"2025-11-09T01:02:01","modified_gmt":"2025-11-09T01:02:01","slug":"session-affinity-in-azure-container-apps-a-hands-on-demo","status":"publish","type":"post","link":"https:\/\/mryelamanchili.dev\/?p=30","title":{"rendered":"Session Affinity in Azure Container Apps: A Hands-On Demo"},"content":{"rendered":"\n<p>When building cloud-native applications, load balancing across multiple replicas is essential for scalability and resilience. But what happens when your application needs <em>session affinity<\/em>, ensuring that a user\u2019s requests are consistently routed to the same replica? This is where <strong>sticky sessions<\/strong> come in.<\/p>\n\n\n\n<p>I recently published a demo project on GitHub that shows how to configure and test session affinity in <strong>Azure Container Apps (ACA)<\/strong> using a Spring Boot application and Nginx for local load balancing. \ud83d\udc49 <a href=\"https:\/\/github.com\/yelamanchili-murali\/azure\/tree\/main\/aca\/session-affinity\">View the repo here<\/a>.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Why Session Affinity Matters<\/h2>\n\n\n\n<p>Imagine a shopping cart application. Without sticky sessions, a user\u2019s requests might bounce between replicas, losing track of their cart state. With sticky sessions enabled, the load balancer ensures that all requests from the same client go to the same replica, preserving continuity.<\/p>\n\n\n\n<p>This demo illustrates both scenarios\u2014sticky sessions ON and OFF\u2014so you can see the difference in behavior.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Local Development and Testing<\/h2>\n\n\n\n<p>The project includes a <strong>Docker Compose setup<\/strong> with Nginx acting as the load balancer.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Round-robin mode<\/strong>: Requests are distributed across replicas.<\/li>\n\n\n\n<li><strong>Sticky mode<\/strong>: Requests from the same client are pinned to one replica.<\/li>\n<\/ul>\n\n\n\n<p>You can toggle between these modes by editing the <code>docker-compose.yml<\/code> file to mount either <code>nginx.roundrobin.conf<\/code> or <code>nginx.sticky.conf<\/code>.<\/p>\n\n\n\n<p>Testing is straightforward with <code>curl<\/code> and a cookie jar. With sticky sessions enabled, you\u2019ll see the same <code>replicaHost<\/code> across requests and an incrementing <code>hitCountsInThisSession<\/code>. Without sticky sessions, requests will bounce between replicas.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Building and Publishing Images<\/h2>\n\n\n\n<p>The demo includes instructions for building the Docker image and pushing it to your preferred registry\u2014GitHub Container Registry, Azure Container Registry, or Docker Hub. This flexibility makes it easy to integrate into your existing CI\/CD pipelines.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Deploying to Azure Container Apps<\/h2>\n\n\n\n<p>The real power of this demo is in showing how ACA handles session affinity in production:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>A deployment script (<code>azure-deploy.sh<\/code>) automates resource group creation, environment setup, and application deployment.<\/li>\n\n\n\n<li>The app is scaled to two replicas to demonstrate load balancing.<\/li>\n\n\n\n<li>Session affinity can be toggled dynamically using the Azure CLI:<\/li>\n\n\n\n<li><code>sticky<\/code> for enabling affinity<\/li>\n\n\n\n<li><code>none<\/code> for disabling affinity<\/li>\n<\/ul>\n\n\n\n<p>Expected outputs are clearly documented, so you can validate whether sticky sessions are working as intended.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Managing and Cleaning Up<\/h2>\n\n\n\n<p>The demo also covers how to:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Check current affinity settings with <code>az containerapp ingress sticky-sessions show<\/code>.<\/li>\n\n\n\n<li>Clean up resources with a single <code>az group delete<\/code> command.<\/li>\n<\/ul>\n\n\n\n<p>This ensures you can experiment freely without leaving behind unused infrastructure.<\/p>\n\n\n\n<p>\ud83d\udd17 Explore the full code and instructions here: <a href=\"https:\/\/github.com\/yelamanchili-murali\/azure\/tree\/main\/aca\/session-affinity\">Session Affinity Demo on GitHub<\/a>.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n","protected":false},"excerpt":{"rendered":"<p>When building cloud-native applications, load balancing across multiple replicas is essential for scalability and resilience. But what happens when your application needs session affinity, ensuring that a user\u2019s requests are consistently routed to the same replica? This is where sticky sessions come in. I recently published a demo project on GitHub that shows how to &#8230; <a title=\"Session Affinity in Azure Container Apps: A Hands-On Demo\" class=\"read-more\" href=\"https:\/\/mryelamanchili.dev\/?p=30\" aria-label=\"Read more about Session Affinity in Azure Container Apps: A Hands-On Demo\">Read more<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4,20],"tags":[12,13,19],"class_list":["post-30","post","type-post","status-publish","format-standard","hentry","category-azure","category-microsoft","tag-azure","tag-azure-container-apps","tag-microsoft"],"_links":{"self":[{"href":"https:\/\/mryelamanchili.dev\/index.php?rest_route=\/wp\/v2\/posts\/30","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/mryelamanchili.dev\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/mryelamanchili.dev\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/mryelamanchili.dev\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/mryelamanchili.dev\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=30"}],"version-history":[{"count":2,"href":"https:\/\/mryelamanchili.dev\/index.php?rest_route=\/wp\/v2\/posts\/30\/revisions"}],"predecessor-version":[{"id":49,"href":"https:\/\/mryelamanchili.dev\/index.php?rest_route=\/wp\/v2\/posts\/30\/revisions\/49"}],"wp:attachment":[{"href":"https:\/\/mryelamanchili.dev\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=30"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mryelamanchili.dev\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=30"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mryelamanchili.dev\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=30"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}