How to achieve high-performance REST API on Azure with .NET?

后端 未结 7 1659
Happy的楠姐
Happy的楠姐 2021-02-07 15:24

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

7条回答
  •  梦如初夏
    2021-02-07 16:01

    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.

提交回复
热议问题