Session state loss during Blue-Green deployment in ASP.NET Core
0 reputation · 20 Sept 2024, 01:12 UTC
0 reputation · 20 Sept 2024, 01:12 UTC
The goal is to maintain user session data when traffic is switched from the existing (Blue) environment to the updated (Green) environment during a Blue‑Green deployment of an ASP.NET Core application, aiming for zero downtime.
Constraints include using the default ASP.NET Core session middleware with its in‑memory provider, a load balancer that can route requests without sticky sessions, and the need for session serialization to be compatible across the old and new application versions. There is uncertainty about whether the session payload produced by the current version can be deserialized correctly by the new version, and whether an external Redis store eliminates the risk of session loss when sticky sessions are disabled.
Does ASP.NET Core’s session middleware preserve session data when routed to a new instance without sticky sessions? Is the default JSON serializer used for session state compatible across minor version upgrades of the application? What Redis configuration is required to guarantee session persistence during a Blue‑Green cutover?
33275 reputation · 20 Sept 2024, 06:48 UTC
No, ASP.NET Core’s session middleware cannot preserve session data when routing to a new instance without sticky sessions if you are using the default in-memory provider. Because in-memory state is local to the process, the Green environment has no access to the Blue environment's memory. To achieve zero-downtime session persistence without sticky sessions, you must migrate to a distributed cache (such as Redis) and share Data Protection keys between environments.
The default AddDistributedMemoryCache() is a misnomer in the context of multi-instance deployments; it is a local cache. When the load balancer switches traffic to the Green environment, the user's session cookie points to a session ID that does not exist in the Green instance's memory, forcing the application to create a new, empty session.
ASP.NET Core session state stores data as byte[]. The middleware itself does not dictate the serializer; the developer chooses how to serialize objects before calling ISession.Set().
SerializationException if the assembly version or class structure changes between the Blue and Green builds.A Redis store eliminates the need for sticky sessions by decoupling state from the compute instance. However, Redis alone is insufficient. ASP.NET Core uses Data Protection APIs to encrypt and sign the session cookie. If Blue and Green use different local key rings, Green will be unable to decrypt the cookie issued by Blue, treating the user as unauthenticated or session-less regardless of the Redis backend.
Program.cs:
builder.Services.AddStackExchangeRedisCache(options =>
{
options.Configuration = "your-redis-connection-string";
options.InstanceName = "Session_";
});
builder.Services.AddDataProtection()
.PersistKeysToFileSystem(new DirectoryInfo("\\shared-network-path\\keys"))
.SetApplicationName("shared-app-name");
System.Text.Json) to convert complex objects to strings/bytes before storing them in the session.To verify the Redis connection is active and receiving data during a cutover, you can use the Redis CLI to monitor keys in real-time:
redis-cli monitor
Missing Diagnostic Detail: Are you using a shared identity provider (like OpenID Connect) or relying solely on the ASP.NET Core Session cookie for authentication state? If using a shared provider, the Data Protection requirement may differ.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.