= !MapGuide RFC 3 - Session Affinity = This page contains an change request (RFC) for the !MapGuide Open Source project. More !MapGuide RFCs can be found on the [wiki:MapGuideRfcs RFCs] page. == Status == ||RFC Template Version||(1.0)|| ||Submission Date||November 1, 2006|| ||Last Modified||Tom Fukushima [[Timestamp]]|| ||Author||Chris Claydon|| ||RFC Status||adopted|| ||Implementation Status||completed|| ||Proposed Milestone||1.2|| ||Assigned PSC guide(s)||(when determined)|| ||'''Voting History'''||Jan 5, 2007|| ||+1||Tom, Andy, Bruce, Jason, Bob|| ||+0||Paul|| ||-0|| || ||-1|| || == Overview == When multiple !MapGuide instances are accessed via a load balancer, problems arise when a request that requires a session that was created on one !MapGuide site server is processed by a different server. The proposed short-term solution to this problem is to ensure that any requests that make use of a session and its related resources are always processed by the same server that created (and therefore has access to) that session. == Motivation == Configuring a load balancer to distribute requests between multiple !MapGuide instances should be simple. The need to ensure that a session-related request is always directed to the server that originally created that session makes configuration of a load balancer undesirably complicated. In a deployment that uses multiple, synchronized !MapGuide Servers, a load balancer is typically used to distribute incoming client requests to a number of !MapGuide Web Tier deployments. Each instance of the web tier makes use of a single !MapGuide Site Server in order to process its requests. Many operations require the use of sessions in !MapGuide. Once a session has been created, the server may create temporary resources in a session repository. A session repository is very similar to the main (!Library://) repository, except that the resources it contains only persist for the lifetime of the session. Requests that require the use of such session-based resources can only succeed if those resources are present on the server. Thus, if the load balancer hits one web tier deployment, and hence one particular server, when it creates a session, subsequent requests for that same session which get directed to an alternate web tier instance (and hence a different server) will fail. This is because the alternate server knows nothing about the requested session, and does not have a copy of the session repository. All requests related to that particular session will fail unless the load balancer happens to direct the request to the server that created it. The proposal is to modify !MapGuide to handle this problem so that the load balancer can direct incoming requests to any of its available web tier deployments. This allows the load balancer configuration to be trivial. == Proposed Solution == The proposed changes represent a short-term solution to this problem. In the long term, steps should be taken to ensure that any of the available servers in a site are capable of handling sessions created on any of the other servers. The changes can be summarized as follows: 1. Modify the web tier so that it can be configured to access more than one site server - this allows each web tier instance to make use of all of the site servers. 2. Modify the web tier so that requests that require a session are always directed to the site server that created the session. 3. Modify the server code so that any support servers that require access to session resources are able to retrieve them from the appropriate site server. === Technical === To support item 1, the web tier needs to perform some rudimentary load-balancing to distribute requests among the available servers. A simple round-robin algorithm would suffice. Support for failover if errors occur or servers are taken offline is beyond the scope of this proposal. To support items 2 and 3, some means is required to map between a session ID and the corresponding server. The proposed solution is to use the following approach: i) Allow the "IPAddress" and "Port" settings in webconfig.ini to be specified as comma-separated lists, thus allowing a 1:n relationship between the web tier and site server(s) instead of the current 1:1 relationship. ii) Create a singleton object that persists for the lifetime of the web tier that is capable of distributing requests from the web tier to each of the available site servers using a round-robin algorithm. iii) Include the IP address of the site server in the ID of any session that it hosts. The IP address would be encrypted and would form a part of the session ID string. iv) Modify the !MgCommand object (which creates the connection from the web tier to the site server) to detect requests that are dependent upon a session. For such requests, the site server IP address will be extracted and decrypted from the session ID. If that IP address matches one that is configured for this web tier, the connection will be made to that site server. If the IP address does not match any of the web tier's site server IPs, an error message will be returned. For requests that do not depend upon a session, the singleton class will be used to send the request to the next site server in the round-robin sequence. v) The Server Admin PHP pages are currently dependent upon the 1:1 relationship between the web tier and site server. The login page would need to be updated to present a dropdown list of available site servers to configure. In the case where the web tier is only configured to access one site server, this field could be hidden or disabled. The login process would create a new session on the selected site server, and all subsequent interactions from the pages would be locked to that site via the session ID. == Example == The default web tier configuration file, webconfig.ini contains the following settings (comments have been removed for conciseness): {{{ [AdministrativeConnectionProperties] Port = 2810 [ClientConnectionProperties] Port = 2811 [SiteConnectionProperties] IpAddress = 127.0.0.1 Port = 2812 }}} To set up the web tier to access two site servers, with ip addresses 111.111.111.111 and 111.111.111.222 using the standard ports, only the !IpAddress setting needs to be modified: {{{ [AdministrativeConnectionProperties] Port = 2810 [ClientConnectionProperties] Port = 2811 [SiteConnectionProperties] IpAddress = 111.111.111.111,111.111.111.222 Port = 2812 }}} It is also possible to use different port settings for each server. So if server 111.111.111.111 uses the standard ports, and 111.111.111.222 uses 2820, 2821 and 2822, the settings should look like this: {{{ [AdministrativeConnectionProperties] Port = 2810,2820 [ClientConnectionProperties] Port = 2811,2821 [SiteConnectionProperties] IpAddress = 111.111.111.111,111.111.111.222 Port = 2812,2822 }}} == Implications == Client requests, particularly from the !MapGuide viewers, often depend upon a session, so most of the traffic from a given client will always be directed back to the same server. == Test Plan == Testing will require multiple site servers, support servers, and web tiers to be deployed under a load balancer. Testing should then be carried out by making requests from multiple clients accessing different sessions. == Funding/Resources == Autodesk to supply the resources to make the required changes.