![]() ![]() | HTTP Dynamic Load Balancing Using SocketProsupport@udaparts.com Contents
1. Introduction When a large company has a web site with many features implemented, the site is usually heavy loaded by many people over world. One particular problem is that web site is often very slow to response to a request from a web browser. This is normal even for many well known companies. To solve this problem, load balancers are used. Typically people use hardware as man-in-middle to distribute web requests onto a set of real HTTP servers to process in parallel so that response time is reduced and through put is increased to make users happy. However, hardware approach is simple but it has its own drawbacks in comparison to other approaches. We'll not compare hardware approach with others, but will focus comparison between hardware approach with load balancing by our SocketPro. SocketPro is written with batching requests and processing them in parallel by non-blocking socket communication from the very beginning. On client side, SocketPro comes with an ATL/COM object USocketPool, the foundation for UDAParts load balancing. The following sites are useful for you to further study the object. a. ASP.NET
2 Async Pages with SocketPro The web server application runs with a central load balancer, which is connected with a set of real servers, A, B, C and D. Communication between the central and real servers is binary instead of text-based HTTP. Most of business processing is completed on real servers. However, load balancer may be used for logging transaction data into a central store (memory, file, or database). Also, the balancer may have its own memory cache implemented. Further, the load balancer may access other servers for other business requirements, which are not shown in the above figure. Because this is a common business web application, many transactions can be partitioned into a small number of different types of jobs, which can be distributed onto real servers to process concurrently. At the end, the central balancer collects results from these real servers. The sample project is located at the directory C:\Program Files\UDAParts\SocketPro\samples\HTTPLoadingBalance\csharp (vbnet) for both C# and vb.NET. To
take advantage of parallel computing. First, we need to partition a large and
complicate task into a set of small and simple jobs. Take this sample as an
example. We partition the following web tasks into three jobs, which are three
SQL statements for three data tables. The source data may come from three
different databases through three real servers.
protected { if (!StartLB()) //Start load balancer return; List<string> lstSQL = new List<string>(); lstSQL.Add(txtSQL1.Text); lstSQL.Add(txtSQL2.Text); lstSQL.Add(txtSQL3.Text); IList<DataTable> tables = m_lbRAdo.PrepareAndExecuteJobs(lstSQL); gvSQL1.DataSource = tables[0]; gvSQL2.DataSource = tables[1]; gvSQL3.DataSource = tables[2]; gvSQL1.DataBind(); gvSQL2.DataBind(); gvSQL3.DataBind(); } At the end, bind three data tables onto three data grid view controls after calling the method PrepareAndExecuteJobs. Now, let's
look at the code snippet of the method PrepareAndExecuteJobs.
public { if(lstSQL == null || lstSQL.Count == 0) throw new InvalidOperationException("Must pass in a list of SQL statements");
//lock an identity for an async handler CRAdo handler = (CRAdo)JobManager.LockIdentity(); if(handler == null) throw new InvalidOperationException("ADO loading balance is down");
//set a sorted list (job identification number <==> data table) handler.m_JobTable = new SortedList<long, DataTable>();
foreach (string strSQL in lstSQL) //prepare and execute jobs automatically through async handler, and each of them contains one task (request) only handler.GetDataReaderAsyn(strSQL);
//wait until all of jobs with this identity are completed. JobManager.Wait(handler); IList<DataTable> tables = handler.m_JobTable.Values; //release identity back to pool for reuse JobManager.UnlockIdentity(handler); return tables;} At the beginning, we lock an identity for an asynchronous ADO.NET handler. Afterwards, we prepare a set of jobs, and each of jobs contains one SQL statement for a data table. Next, we'll wait until all of jobs are processed and returned from different real servers. At the end, we sort returned data tables according to job identification numbers so that a list of original SQL statements correctly correspond to the list of data tables. Finally, we release the previously locked identity back to pool for reuse. We have talked about how to create jobs from a large and complicate web request by partitioning. Now we need to know how to gather results from different real servers. First of all, we should make sure how to process one result from one real server. This is simple as long as you go through the tutorial one. This sample is slightly more difficult because you'll reuse existing class CAsyncAdoHandler inside SocketProAdapter. However, this is still simple as long as you read through this article and look at the attached sample at the directory. To
gather returned results from different real servers, you need to override either
virtual function OnReturnedResultProcessed or OnJobDone. For this
sample, we override the later one as shown in the below.
protected { CRAdo RAdo = (CRAdo)JobContext.Identity; lock (m_cs) { RAdo.m_JobTable[JobContext.JobId] = Handler.ReturnTable; } } There are two pitfalls here. First, it is mandatory that we should synchronize the dictionary object because the object may be accessed from different threads at the same time. The second is that the reference of job context identity (RAdo) is not necessarily equal to the reference Handler. However, the reference Handler must contain a data table if available, which must belong to the job context. As described at this article, requests and their returning results are processed separately by different handlers. Once knowing the above two pitfalls, you are expected to understand the above code snippet. 5. Load balancing comparison between software and hardware Now, let's compare hardware load balancing with SocketPro approach. SocketPro approach has following list of advantages over hardware load balancing.
|