How to Configure Load Balancing with Sticky Sessions in Easegress
Configure sticky sessions in Easegress by setting the stickySession field inside your proxy's loadBalance configuration, choosing from three modes: CookieConsistentHash, DurationBased, or ApplicationBased.
Easegress implements sophisticated load balancing through the GeneralLoadBalancer in pkg/filters/proxies/loadbalance.go, with sticky session support handled by HTTPSessionSticker in pkg/filters/proxies/stickysession.go. This architecture allows you to maintain client-server affinity using cookie-based session persistence, ensuring subsequent requests from the same client reach the same backend server.
Sticky Session Modes in Easegress
Easegress supports three distinct sticky session modes, each suited for different application architectures. The mode is configured via the mode field in StickySessionSpec.
CookieConsistentHash
This mode uses an existing application cookie as the hash key. Easegress reads the value of appCookieName from the request and uses consistent hashing to select a backend server. This is ideal when your application already sets a session ID or user identifier cookie.
DurationBased
In this mode, Easegress generates its own load balancer cookie (lbCookieName, defaulting to EG_SESSION) that encodes a signed server ID and expiration timestamp. The cookie persists for lbCookieExpire (default 2h). This mode is best for stateful applications that need temporary session affinity without modifying application code.
ApplicationBased
Similar to DurationBased, but the LB cookie is only set if the upstream response already contains the application cookie specified in appCookieName. This enables "lazy" session affinity—stickiness only activates after the application has established a session, conserving resources for stateless requests.
Configuration Syntax and Examples
Sticky sessions are configured within the loadBalance block of a Proxy or GRPCProxy filter. The relevant schema is defined in proxy.StickySessionSpec (documented in docs/07.Reference/7.02.Filters.md).
Key Configuration Fields
| Field | Type | Description |
|---|---|---|
mode |
string | Required. One of CookieConsistentHash, DurationBased, or ApplicationBased. |
appCookieName |
string | Name of the application cookie used in CookieConsistentHash and ApplicationBased modes. |
lbCookieName |
string | Name of the LB-generated cookie. Defaults to EG_SESSION. |
lbCookieExpire |
string | Duration string (e.g., "2h", "30m"). Defaults to 2h. |
YAML Configuration Example
apiVersion: easegress.megaease.com/v2
kind: Proxy
metadata:
name: sticky-proxy
spec:
serverPool:
servers:
- url: http://10.0.0.1:8080
- url: http://10.0.0.2:8080
- url: http://10.0.0.3:8080
loadBalance:
policy: roundRobin
stickySession:
mode: DurationBased
lbCookieName: SESSION_ID
lbCookieExpire: 1h
In this example, Easegress first checks for the SESSION_ID cookie. If present and valid, the request routes to the encoded backend server. Otherwise, the round-robin policy selects a server, and Easegress sets the SESSION_ID cookie with a 1-hour expiration.
How Sticky Sessions Work Internally
Understanding the internal flow helps debug sticky session behavior and implement custom extensions.
The Load Balancing Flow
The GeneralLoadBalancer in pkg/filters/proxies/loadbalance.go orchestrates the process:
-
Initialization: In
GeneralLoadBalancer.Init(lines 99-125), the system creates the load balancing policy based onLoadBalanceSpec.Policy. If aStickySessionspec exists, it invokes the session sticker factory to create aSessionStickerinstance (line 27), stored inglb.ss. -
Server Selection:
GeneralLoadBalancer.ChooseServerfirst queries the session sticker viaglb.ss.GetServer. If the sticker returns a valid server (e.g., decoded from a cookie), that server is used immediately. Otherwise, the configured policy selects a server (lines 13-20). -
Response Processing: After the upstream response,
GeneralLoadBalancer.ReturnServercallsglb.ss.ReturnServer. This allows theHTTPSessionStickerto inspect the response and set the stickiness cookie if needed.
HTTPSessionSticker Implementation
The HTTPSessionSticker in pkg/filters/proxies/stickysession.go handles cookie logic:
-
Consistent Hashing: For
CookieConsistentHashmode, it builds a consistent hash ring inUpdateServers(lines 22-34) usingconsistent.New. It hashes theappCookieNamevalue to select a backend. -
Cookie Validation: In
getServerByLBCookie(lines 52-71), it validates the signed cookie using HMAC to prevent tampering. The cookie contains the server ID and expiration timestamp. -
Cookie Generation: The
signmethod (lines 93-105) creates a new signed cookie. InReturnServer(lines 15-34), if no valid sticky cookie exists, it generates one using the selected server's ID and the configured expiration duration.
Programmatic Usage in Go
For developers building custom filters, you can instantiate the load balancer programmatically:
import (
"github.com/megaease/easegress/pkg/filters/proxies"
"github.com/megaease/easegress/pkg/filters/proxy"
)
// Define the load balance specification
spec := &proxy.LoadBalanceSpec{
Policy: "roundRobin",
StickySession: &proxy.StickySessionSpec{
Mode: proxy.StickySessionModeDurationBased,
LBCookieName: "MY_SESSION",
LBCookieExpire: "1h",
},
}
// Create server list
servers := []*proxy.Server{
{URL: "http://10.0.0.1:8080"},
{URL: "http://10.0.0.2:8080"},
}
// Instantiate the load balancer
lb := proxies.NewGeneralLoadBalancer(spec, servers)
lb.Init(
func(s *proxy.StickySessionSpec) proxies.SessionSticker {
return proxies.NewHTTPSessionSticker(s)
},
nil, // health checker (optional)
nil, // policy (optional, uses spec.Policy)
)
// Usage in request handling
server := lb.ChooseServer(req)
// ... process request ...
lb.ReturnServer(server, req, resp)
This pattern allows custom filters to leverage the same sticky session logic used by the built-in Proxy filter.
Summary
-
Sticky sessions in Easegress are configured within the
loadBalance.stickySessionblock of a Proxy or GRPCProxy filter, supporting three modes:CookieConsistentHash,DurationBased, andApplicationBased. -
Core implementation resides in
pkg/filters/proxies/loadbalance.go(GeneralLoadBalancer) andpkg/filters/proxies/stickysession.go(HTTPSessionSticker), which handle server selection, cookie validation, and consistent hashing. -
Configuration fields include
mode,appCookieName,lbCookieName(defaults toEG_SESSION), andlbCookieExpire(defaults to2h). -
Programmatic usage allows custom filters to instantiate
GeneralLoadBalancerwith aStickySessionSpecand a session sticker factory.
Frequently Asked Questions
What is the default cookie name for sticky sessions in Easegress?
The default cookie name is EG_SESSION. You can override this by setting the lbCookieName field in your sticky session configuration. This cookie stores a signed server ID and expiration timestamp when using DurationBased or ApplicationBased modes.
How does Easegress handle sticky sessions when a backend server goes down?
When a backend server becomes unavailable, the GeneralLoadBalancer.ChooseServer method first attempts to retrieve the server from the session sticker. If the sticker returns a server that is no longer in the healthy server pool, the load balancer falls back to the configured load balancing policy (round-robin, random, etc.) to select a new available backend.
Can I use sticky sessions with gRPC services in Easegress?
Yes, sticky sessions work with the GRPCProxy filter using the same configuration syntax as the HTTP Proxy. The loadBalance.stickySession block supports identical fields (mode, lbCookieName, etc.) for gRPC traffic, though cookie-based stickiness is typically relevant when gRPC is transported over HTTP/2 with browser-based clients or specific metadata handling.
What is the difference between DurationBased and ApplicationBased sticky session modes?
DurationBased mode generates a load balancer cookie immediately upon the first request, regardless of whether the application has created a session. ApplicationBased mode only sets the LB cookie if the upstream response already contains the application cookie specified in appCookieName. Use ApplicationBased to conserve resources by only enabling stickiness for clients that have established application sessions, while DurationBased provides immediate affinity for all clients.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →