How do I implement server affinity or sticky sessions on App Engine?
google-app-engine, session-state, sticky
Solution
You can achieve these goals using App Engine backends (long-running, configurable, addressable, persistent servers):
- https://developers.google.com/appengine/docs/python/backends/
- https://developers.google.com/appengine/docs/java/backends/
Python implementation
Configure a backend to be both public and dynamic
# backends.yaml
backends:
- name: foo
instances: 20
options: public, dynamic
In addition to deploying your app in usual way:
appcfg.py update .
remember to deploy you backend:
appcfg.py backends . update
For the initial connection, have your client use the non-instance specific backend hostname, e.g.:
foo.your_app_id.appspot.com
App Engine will route your request to available backend instance, after optionally starting a new backend instance.
In the request handling code on the server, use the backends API to determine which instance is handling the request and return to the client a instance specific URL.
from google.appengine.api import backends
import webapp2
class GetPersistentUrlHandler(webapp2.RequestHandler):
def get(self):
"""Return the current backend's instance-specific URL."""
my_url = backends.get_url(instance=backends.get_instance())
self.response.write(my_url)
app = webapp2.WSGIApplication([
('/get_peristent_url', GetPersistentUrlHandler),
], debug=True)
Client makes subsequent connections to the instance specific backend URL:
http://3.foo.your_app_id.appspot.com
Note: when using https be sure to replace subdomain dots with `-dot-` in order to avoid SSL certificate issues.
https://3-dot-foo.your_app_id.appspot.com
Limitations
- Backends do not live forever and may be shutdown unexpectedly and without notice
- The number of backends your application can have is currently limited
Problem
My application wishes to have: Automatic scalability - I want App Engine to spin up new instances of my app when traffic increases - When instances become idle, I want App Engine to shut them down Client/server affinity - After an initial client->server HTTP request, I want clients to be able to connect to the same appserver, so that the appserver can maintain a bunch of client state - State may be updated frequently (in order to support real-time interactions), so memcache+datastore based persistence is not desirable. - The server may need to make decisions based on the state of multiple clients, e.g. real time multi-player game How can I accomplish this?