Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / ASP.NET / Web Services / July 2006

Tip: Looking for answers? Try searching our database.

Problem:  My web service calls only open a single connection to the web service machine

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Scott Baierl - 15 Jul 2006 23:44 GMT
I've got a web application that makes web service calls to a J2EE back-end
server farm.  It appears that the .NET runtime is setting up a single
connection to one of the J2EE servers on the back-end, and sends all the web
service calls over this connection.  We have a CISCO CSM between the .NET
server and the J2EE back-end server farm to network load balance the .NET
calls between 1 of 4 nodes in the server farm.  The problem is that the CSM
balances at the connection level, and since my .NET application is only
opening a single connection and keeps that connection open, no load
balancing occurs.  I noticed that the .NET runtime will create a maximum of
2 connections by default, but I'm only getting a single connection.  That
indicates to me that the amount of traffic I'm generating on the .NET
machine isn't enough to cause .NET to create more than one connection.  Is
there a way to force the .NET runtime to create and use more than a single
connection, or is there a way to time that connection out and cause it to
close between web service calls to the back-end, so I can use the full
horsepower of my back-end server farm?
Scott Baierl - 29 Jul 2006 02:16 GMT
Well, I figured out the answer to my problem, so I figured I'd post it here
in case someone else has to deal with this.

One way to handle this is to turn keep alives off in the web service proxy.
This will cause .NET to use a new connection for each web service request,
effectively allowing the CSM to balance each request to a different server
in the server pool.  I added the following code to my proxy class:

protected override System.Net.WebRequest GetWebRequest(Uri uri)
{
   System.Net.Http.WebRequest webRequest =
(System.Net.Http.WebRequest)base.GetWebRequest(uri);
   webRequest.KeepAlive = false;
   return webRequest;
}

This also fixed an issue I was having where I'd get the following error:
"The underlying connection was closed"  The one drawback of this solution is
that it doesn't allow .NET to use persistent connections, so you have a
little extra overhead to setup and tear down a connection for each web
service call.  However, in my case, the extra overhead is minor compared to
the performance benefits of being able to fully utilize my server farm.

The other solution again, requires modifying the proxy, and entails using
connection groups.  Basically, you leave keepalives on, but have the proxy
alternate it's requests to different connection groups.  When you use
connection groups, .NET will create one or more connections per group.
Then, when you create an instance of the proxy, you just specify a different
group for each request.  To make this happen, I did the following:

//Added an array of connection group names to use
private static string [] sConnGroups = {"CONNGRP1", "CONNGRP2", "CONNGRP3"};

// Created a function to randomly give out a name from the above array
private string GetConnectionGroupName()
{
   Random rand1 = new Random();
   return sConnGroups[rand1.Next(sConnGroups.GetUpperBound(0))];
}

// Add the following to your proxy class constructor
public MyProxyClass()
{
   this.ConnectionGroupName = GetConnectionGroupName();
}

By specifying a different group name, .NET will create the group if it
doesn't exist, and if there's an open connection it will use that
connection, or create one if one isn't open.  The above code will randomly
select one of the three connection groups, and thus will randomly use one of
the three connections.  If more connections are needed .NET will create more
up to the maximum that you've set in your machine.config.  The advantage of
this method is that persistent connections will continue to be used, so you
have that efficiency.  The disadvantage for me, is that .NET is now
controlling the load balancing, rather than my switch.  Also, I still have
the problem with .NET closing the connection, and I get the error I
mentioned previously in this response.  The above is for illustration
purposes only.  Since turning keepalives off fixes my problem, and also
fixes a bug, I've decided not to use this method myself.  But, if you don't
get the error I was getting, there's no reason you couldn't achieve greater
efficiency by using this technique.  A couple of improvements to the above
would be to make the number of connection groups externally configurable,
and making the GetConnectionGroupName() function round-robin the group
names.

> I've got a web application that makes web service calls to a J2EE back-end
> server farm.  It appears that the .NET runtime is setting up a single
[quoted text clipped - 15 lines]
> close between web service calls to the back-end, so I can use the full
> horsepower of my back-end server farm?

Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.