We have a .NET Web Role hosted on Windows Azure that only serves a REST API with only a hand few web methods.
API is u
This article http://social.msdn.microsoft.com/Forums/en-US/windowsazuredata/thread/d84ba34b-b0e0-4961-a167-bbe7618beb83 covers performance issues with Azure.
Azure roles by default only run in a single thread, which is very inefficient on the servers. There are some very nice design patterns out there that shows you how to implement multithreaded Azure roles, I personally follow this one http://www.31a2ba2a-b718-11dc-8314-0800200c9a66.com/2010/12/running-multiple-threads-on-windows.html . With this your roles can serialize objects in parallel.
I use JSON as an interchange format instead of XML, it has a much smaller bytesize and is well supported with .NET 4. I currently use DataContractJsonSerializer
but you could also look into JavaScriptSerializer
or JSON.NET, if it is serialization performance you are after I would suggest you compare these.
WCF services are single threaded by default ( source: http://msdn.microsoft.com/query/dev10.query?appId=Dev10IDEF1&l=EN-US&k=k(SYSTEM.SERVICEMODEL.SERVICEBEHAVIORATTRIBUTE.CONCURRENCYMODE);k(TargetFrameworkMoniker-%22.NETFRAMEWORK%2cVERSION%3dV4.0%22);k(DevLang-CSHARP)&rd=true ) . Here is a code sample that will make your RESTfull API multi-threaded:
ExampleService.svc.cs
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple, InstanceContextMode = InstanceContextMode.PerCall,
IncludeExceptionDetailInFaults = false, MaxItemsInObjectGraph = Int32.MaxValue)]
public class ExampleService : IExample
web.config
ExampleService.svc
<%@ ServiceHost Language="C#" Debug="true" Service="WebPages.Interfaces.ExampleService" CodeBehind="ExampleService.svc.cs" %>
Also, ASP.NET by default only allow for two concurrent HTTP connections (source See http://social.msdn.microsoft.com/Forums/en-US/windowsazuredata/thread/d84ba34b-b0e0-4961-a167-bbe7618beb83 ) . These settings will allow for up to 48 concurrent HTTP connections:
web.config
If your HTTP POST body messages are usually smaller than 1460 bytes you should turn of nagling to improve performance ( source http://social.msdn.microsoft.com/Forums/en-US/windowsazuredata/thread/d84ba34b-b0e0-4961-a167-bbe7618beb83 ) . Here is some settings that does this:
web.config
Define your JSON APIs something like this:
using System.ServiceModel;
using System.ServiceModel.Web;
using Interchange;
namespace WebPages.Interfaces
{
[ServiceContract]
public interface IExample
{
[OperationContract]
[WebInvoke(Method = "POST",
BodyStyle = WebMessageBodyStyle.Bare,
RequestFormat = WebMessageFormat.Json,
ResponseFormat = WebMessageFormat.Json)]
string GetUpdates(RequestUpdates name);
[OperationContract]
[WebInvoke(Method = "POST",
BodyStyle = WebMessageBodyStyle.Bare,
RequestFormat = WebMessageFormat.Json,
ResponseFormat = WebMessageFormat.Json)]
string PostMessage(PostMessage message);
}
}
You can serialize to JSON in .NET 4 like this:
string SerializeData(object data)
{
var serializer = new DataContractJsonSerializer(data.GetType());
var memoryStream = new MemoryStream();
serializer.WriteObject(memoryStream, data);
return Encoding.Default.GetString(memoryStream.ToArray());
}
A typical interchange entity you can define as normal:
using System.Collections.Generic;
using System.Runtime.Serialization;
namespace Interchange
{
[DataContract]
public class PostMessage
{
[DataMember]
public string Text { get; set; }
[DataMember]
public List Tags { get; set; }
[DataMember]
public string AspNetSessionId { get; set; }
}
}
You could write your own HTTPModule for upstream GZip compression, but I would try the stuff above first.
Finally, make sure that your table storage is at the same location as the services that consume them.