繁体中文
设为首页
加入收藏
当前位置:ASP技术首页 >> ASP应用 >> Chapter 10 — Improving Web Services Performance

Chapter 10 — Improving Web Services Performance

2005-10-01 12:12:40  作者:kaixin110  来源:互联网  浏览次数:6  文字大小:【】【】【
简介:  Chapter 10 — Improving Web Services PerformanceImproving .NET Application Performance and Scalability J.D. Meier, Srinath Vasireddy, Ashish Babbar, and Alex MackmanMicrosoft Corporati...

Chapter 10 — Improving Web Services Performance

Improving .NET Application Performance and Scalability

J.D. Meier, Srinath Vasireddy, Ashish Babbar, and Alex Mackman

Microsoft Corporation

May 2004

Related Links

patterns and practices Index

Improving .NET Application Performance and Scalability — Home Page

Chapter 5, "Improving Managed Code Performance"

"Checklist: Web Services Performance"

Send feedback to Scale@microsoft.com

Summary: This chapter focuses on design guidelines and techniques, such as state management, asynchronous invocation, serialization, threading, to help you develop efficient Web services. This chapter also presents a formula for reducing thread contention and HTTP connections to increase the throughput for your Web services.Contents

Objectives

Overview

How to Use This Chapter

Architecture

Prescriptive Guidance for Web Services, Enterprise Services, and .NET Remoting

Performance and Scalability Issues

Design Considerations

Implementation Considerations

Connections

Threading

One-Way (Fire-and-Forget) Communication

Asynchronous Web Methods

Asynchronous Invocation

Timeouts

WebMethods

Serialization

Caching

State Management

Bulk Data Transfer

Attachments

COM Interop

Measuring and Analyzing Web Services Performance

Web Service Enhancements

Summary

Additional ResourcesObjectivesIdentify top Web services performance issues. Design scalable Web services that meet your performance objectives. Improve serialization performance. Configure the HTTP runtime for optimum performance. Improve threading efficiency. Evaluate and choose the most appropriate caching mechanism. Decide when to maintain state. Evaluate and choose the most appropriate bulk data transfer mechanism. Overview

Services are the ideal communication medium for distributed applications. You should build all of your services using Web services and then, if necessary, use Enterprise Services or Microsoft® .NET remoting within the boundaries of your service implementation. For example, you might need to use Enterprise Services for distributed transaction support or object pooling.

Web services are ideal for cross-platform communication in heterogeneous environments because of their use of open standards such as XML and Simple Object Access Protocol (SOAP). However, even in a closed environment where both client and server systems use the .NET Framework, ease of deployment and maintenance make Web services a very attractive approach.

This chapter begins by examining the architecture of ASP.NET Web services, and then explains the anatomy of a Web services request from both the client and server-side perspectives. You need a solid understanding of both client and server to help you identify and address typical Web services performance issues. An understanding of Web services architecture will also help you when you configure the HTTP runtime to optimize Web services performance. The chapter then presents a set of important Web services design considerations, followed by a series of sections that address the top Web services performance issues.How to Use This Chapter

To get the most out of this chapter: Jump to topics or read from beginning to end. The main headings in this chapter help you to locate the topics that interest you. Alternatively, you can read the chapter from beginning to end to gain a thorough appreciation of performance and scalability design issues. Use the checklist. Use "Checklist: Web Services Performance" in the "Checklists" section of this guide to quickly view and evaluate the guidelines presented in this chapter. Use the "Architecture" section of this chapter to learn how Web services work. By understanding Web services architecture, you can make better design and implementation choices. Use the "Design Considerations" section of this chapter. This section helps you to understand the higher-level decisions that affect implementation choices for Web services code. Read Chapter 6, "Improving ASP.NET Performance" Many of the performance optimizations described in Chapter 6, "Improving ASP.NET Performance" — such as tuning the thread pool and designing and implementing efficient caching — also apply to ASP.NET Web services development. Read Chapter 13, "Code Review: .NET Application Performance" See the "Web Services" section of Chapter 13 for specific guidance. Measure your application performance. Read the "Web Services" and ".NET Framework Technologies" sections of Chapter 15, "Measuring .NET Application Performance" to learn about key metrics that you can use to measure application performance. It is important that you are able to measure application performance so that you can target performance issues accurately. Test your application performance. Read Chapter 16, "Testing .NET Application Performance" to learn how to apply performance testing to your application. It is important that you apply a coherent testing process and that you are able to analyze the results. Tune your application performance. Read the "Web Services" section of Chapter 17, "Tuning .NET Application Performance" to learn how to resolve performance issues identified through the use of tuning metrics. Architecture

The server-side infrastructure is based on ASP.NET and uses XML serialization. When the Web server processes an HTTP request for a Web service, Internet Information Services (IIS) maps the requested extension (.asmx) to the ASP.NET Internet server application programming interface (ISAPI) extension (Aspnet_isapi.dll). The ASP.NET ISAPI extension then forwards the request to the ASP.NET worker process, where it enters the request processing pipeline, which is controlled by the HttpRuntime object. See Figure 10.1 for an illustration of the Web services architecture and request flow.

Figure 10.1: ASP.NET Web services architecture and request flow

The request is initially passed to the HttpApplication object, followed by the series of registered HttpModule objects. HttpModule objects are registered in the system-wide Machine.config file or in the section of an application-specific Web.config file. HttpModule objects handle authentication, authorization, caching, and other services.

After passing through the HTTP modules in the pipeline, HttpRuntime verifies that the .asmx extension is registered with the WebServiceHandlerFactory handler. This creates an HTTP handler, an instance of a type that derives from WebServiceHandler, which is responsible for processing the Web services request. The HTTP handler uses reflection to translate SOAP messages into method invocations. WebServiceHandler is located in the System.Web.Services.Protocols namespace.Client-Side Proxy Classes

On the client side, proxy classes provide access to Web services. Proxy classes use XML serialization to serialize the request into a SOAP message, which is then transported using functionality provided by the System.Net namespace.

You can use the Wsdl.exe tool to automatically generate the proxy class from the Web Services Description Language (WSDL) contract file. Depending on the bindings specified in the WSDL, the request issued by the proxy may use the HTTP GET, HTTP POST, or HTTP SOAP protocols.

The proxy class is derived from one of the following base classes: System.Web.Services.Protocols.HttpGetClientProtocol System.Web.Services.Protocols.HttpPostClientProtocol System.Web.Services.Protocols.SoapHttpClientProtocol

These all derive from System.Web.Services.Protocols.HttpWebClientProtocol, which in turn derives from the System.Web.Services.Protocols.WebClientProtocol base class in the inheritance chain. WebClientProtocol is the base class for all automatically generated client proxies for ASP.NET Web services, and, as a result, your proxy class inherits many of its methods and properties.Prescriptive Guidance for Web Services, Enterprise Services, and .NET Remoting

Services are the preferred communication technique to use across application boundaries, including platform, deployment, and trust boundaries. You can implement services today by using Web services or Web Services Enhancements (WSE). Although WSE provides a rich set of features, you should evaluate whether or not you can accept the WSE support policy. Enterprise Services provides component services such as object pooling, queued components, a role-based security model and distributed transactions, and should be used as an implementation detail within your service when you need those features. .NET remoting is preferred for cross-application communication within the same process.Object Orientation and Service Orientation

When you design distributed applications, use the services approach whenever possible. Although object orientation provides a pure view of what a system should look like and is effective for producing logical models, an object-based approach can fail to consider real-world factors, such as physical distribution, trust boundaries, and network communication, as well as nonfunctional requirements, such as performance and security.

Table 10.1 summarizes some key differences between object orientation and service orientation.

Table 10.1: Object Orientation vs. Service Orientation

Object OrientationService OrientationAssumes a homogeneous platform and execution environment.Assumes a heterogeneous platform and execution environment.Shares types, not schemas.Shares schemas, not types.Assumes cheap, transparent communication.Assumes variable cost, explicit communication.Objects are linked: object identity and lifetime are maintained by the infrastructure.Services are autonomous: security and failure isolation are a must.Typically requires synchronized deployment of both client and server.Allows continuous, separate deployment of client and server.Is easy to conceptualize and thus provides a natural model to follow.Builds on ideas from component software and distributed objects. Dominant theme is to manage/reduce sharing between services.Provides no explicit guidelines for state management and ownership. Owns and maintains state or uses the reference state.Assumes a predictable sequence, timeframe, and outcome of invocations.Assumes message-oriented, potentially asynchronous, and long-running communications.Goal is to transparently use functions and types remotely.Goal is to provide inter-service isolation and wire interoperability based on standards.

Application Boundaries

Common application boundaries include platform, deployment, trust, and evolution. (Evolution refers to whether or not you develop and upgrade applications together.) When you evaluate architecture and design decisions that affect your application boundaries, consider the following: Objects and remote procedure calls (RPC) are appropriate within boundaries. Services are appropriate across and within boundaries. Recommendations for Web Services, Enterprise Services, and .NET Remoting

When you are working with ASP.NET Web services, Enterprise Services, and .NET remoting, Microsoft recommends that you: Build services by using ASP.NET Web Services. Enhance your ASP.NET Web services with WSE if you need the WSE feature set and you can accept the support policy. Use object technology, such as Enterprise Services or .NET remoting, within a service implementation. Use Enterprise Services inside your service boundaries in the following scenarios: You need the Enterprise Services feature set (such as object pooling; declarative, distributed transactions; role-based security; and queued components). You are communicating between components on a local server and you have performance issues with ASP.NET Web services or WSE. Use .NET remoting inside your service boundaries in the following scenarios: You need in-process, cross-application domain communication. Remoting has been optimized to pass calls between application domains extremely efficiently. You need to support custom wire protocols. Understand, however, that this customization will not port cleanly to future Microsoft implementations. Caveats

When you work with ASP.NET Web services, Enterprise Services, or .NET remoting, consider the following caveats: If you use ASP.NET Web services, avoid or abstract your use of low-level extensibility features such as the HTTP Context object. If you use .NET remoting, avoid or abstract your use of low-level extensibility such as .NET remoting sinks and custom channels. If you use Enterprise Services, avoid passing object references inside Enterprise Services. Also, do not use COM+ APIs. Instead, use types from the System.EnterpriseServices namespace. More InformationFor guidelines on how to make .NET Enterprise Services components execute as quickly as C++ COM components, see the MSDN® article, ".NET Enterprise Services Performance," at http://msdn.microsoft.com/library/en-us/dncomser/html/entsvcperf.asp. For more information on Enterprise Services, see Chapter 8, "Improving Enterprise Services Performance" For more information on remoting, see Chapter 11, "Improving Remoting Performance" Performance and Scalability Issues

The main issues that can adversely affect the performance and scalability of your Web services are summarized in the following list. Subsequent sections in this chapter provide strategies and technical information to prevent or resolve each of these issues. Incorrect communication mechanism. Currently, there are three main technologies for remoting a method call: Enterprise Services, .NET remoting, and ASP.NET Web services. The best choice depends upon various factors, including the source and target platforms, whether you need to communicate across an intranet or the Internet, whether you require additional services such as distributed transactions, your security requirements, deployment considerations (such as whether your communication must pass through a firewall), other port limitations, and so on. Web services. Use Web services to build your services. Enterprise Services. If you use Web services to build your services, you may still need to use Enterprise Services within your service implementation. For example, you may need it to support distributed transactions or if you want to use object pooling. .NET remoting. Use remoting for same-process, cross-application domain communication or for remote communication if you need to integrate with a legacy protocol. If you use remoting, avoid custom proxies, custom sinks, and using contexts. This helps to avoid compatibility issues with future communication technologies. Chatty calls. Network round trips to and from a Web service can be expensive. This issue is magnified if clients need to issue multiple requests to a Web service to complete a single logical operation. Improper choice of parameters. Your choice of parameters depends upon various factors, such as interoperability, the varying platforms used by the clients, maintainability, the type of encoding format used, and so on. Improper choice of parameters can lead to a number of issues, including increased serialization costs and potential versioning problems for the Web service (for example where a custom type is updated). Where possible, you should use primitive types. If interoperability is an issue, consider using the XmlElement and XmlDocument types and choose types specific to your application, such as an Employee or Person class. Serialization. Serializing large amounts of data and passing it to and from Web services can cause performance-related issues, including network congestion and excessive memory and processor overhead.

Other issues that affect the amount of data passed across the wire include improper data transfer strategies for large amounts of data. Selecting an appropriate data transfer strategy — such as using a SOAP extension that performs compression and decompression or offloading data transfer to other services — is critical to the performance of your Web services solution. Improper choice of encoding format. You can use either literal or SOAP encoding. SOAP encoding involves more SOAP-processing overhead as compared to literal encoding. Lack of caching or inefficient caching. In many situations, application or perimeter caching can improve Web services performance. Caching-related issues that can significantly affect Web services performance include failure to use caching for Web methods, caching too much data, caching inappropriate data, and using inappropriate expiration settings. Inefficient state management. Inefficient state management design in Web services can lead to scalability bottlenecks because the server becomes overloaded with state information that it must maintain on a per-user basis. Common pitfalls for Web services state management include using stateful Web methods, using cookie container–based state management, and choosing an inappropriate state store. The most scalable Web services maintain no state. Misuse of threads. It is easy to misuse threads. For example, you might create threads on a per-request basis or you might write code that misuses the thread pool. Also, unnecessarily implementing a Web method asynchronously can cause more worker threads to be used and blocked, which affects the performance of the Web server.

On the client side, consumers of Web services have the option of calling Web services asynchronously or synchronously. Your code should call a Web service asynchronously only when you want to avoid blocking the client while a Web service call is in progress. If you are not careful, you can use a greater number of worker and I/O threads, which negatively affects performance. It is also slower to call a service asynchronously; therefore, you should avoid doing so unless your client application needs to do something else while the service is invoked. Inefficient Web method processing. A common example of inefficient processing is not using a schema to validate input upfront. This issue can be significant because the Web method may de-serialize the incoming message and then throw exceptions later on while processing the input data. Design Considerations

To help ensure that you create efficient Web services, there are a number of issues that you must consider and a number of decisions that you must make at design time. The following are major considerations: Design chunky interfaces to reduce round trips. Prefer message-based programming over RPC style. Use literal message encoding for parameter formatting. Prefer primitive types for Web services parameters. Avoid maintaining server state between calls. Consider input validation for costly Web methods. Consider your approach to caching. Consider approaches for bulk data transfer and attachments. Avoid calling local Web services. Design Chunky Interfaces to Reduce Round Trips

Design chunky interfaces by exposing Web methods that allow your clients to perform single logical operations by calling a single Web method. Avoid exposing properties. Instead, provide methods that accept multiple parameters to reduce roundtrips.

Do not create a Web service for each of your business objects. A Web service should wrap a set of business objects. Use Web services to abstract these objects and increase the chunkiness of your calls.Prefer Message-Based Programming Over RPC Style

You can design Web services by using either of two programming models: messaging style and RPC style. The RPC style is based on the use of objects and methods. Web methods take object parameters to do the processing, and then return the results. This style generally relies on making multiple Web method calls to complete a single logical operation, as shown in the following code snippet.

//client calling a Web service

Serv.SendItemsToBePurchased(Array[] items);

Serv.ShippingAddress(string Address);

Serv.CheckOut();

The messaging style does not focus on objects as parameters. It is based on a data contract (schema) between the Web service and its clients. The Web service expects the message to be XML that conforms to the published data contract.

//Client

string msg = "";

MyMethod(msg);

//Server

[WebMethod]

void MyMethod(string msg){ . . . }

This approach allows you to package and send all parameters in a single message payload and complete the operation with a single call, thus reducing chatty communication. The Web service may or may not return results immediately; therefore, the clients do not need to wait for results.Use Literal Message Encoding for Parameter Formatting

The encoded formatting of the parameters in messages creates larger messages than literal message encoding (literal message encoding is the default). In general, you should use literal format unless you are forced to switch to SOAP encoding for interoperability with a Web services platform that does not support the literal format.Prefer Primitive Types for Web Services Parameters

There are two broad categories of parameter types that you can pass to Web services: Strongly typed. These include .NET types such as double and int, and custom objects such as Employee, Person, and so on. The advantage of using strongly typed parameters is that .NET automatically generates the schema for these types and validates the incoming values for you. Clients use the schema to construct appropriately formatted XML messages before sending them. Loosely typed. These parameters use the string type. Note that you should not pass XML documents as string parameters because the entire string then needs to be XML encoded. For example, < and > needs to be converted to < and > and so on. Instead, you should use either an XmlElement parameter or implement IXmlSerializable. The latter is the most efficient and works well for large data sizes, regardless of which encoding style you use, you should prefer simple primitive types like int, double, and string for Web services parameters. Use of primitive types leads to reduced serialization and automatic and efficient validation by the .NET Framework. Avoid Maintaining Server State Between Calls

Maintaining per-caller state in memory on the server limits scalability because the state consumes server resources. As an alternative, you can pass state back and forth between the client and Web service. Although this approach enables you to scale your service, it does add performance overhead — including the time taken to serialize, transmit, parse, and de-serialize the state with each call.Consider Input Validation for Costly Web Methods

If you have a Web method that performs costly and time-consuming processing, consider validating the Web method input before processing it. It can be more efficient to accept the validation overhead to eliminate unnecessary downstream processing. However, unless you are likely to receive invalid input frequently, you should probably avoid schema validation due to the significant overhead that it introduces. You need to assess your specific situation to determine whether or not schema validation is appropriate.

You can validate input data either by using SOAP extensions or by using separate internal helper methods that your Web methods call. The advantage of using SOAP extensions is that they permit you to separate your validation code from your business logic. If there is any schema change in the future, the extension can change independently of the Web method.

Another option is to use the XmlValidatingReader class to perform schema-based validation, as shown in the following code snippet.

[WebMethod]

public void ValidateCreditCard(string xmlCardInfo){

try

{

// Create and load a validating reader

XmlValidatingReader reader = new XmlValidatingReader(xmlCardInfo,

XmlNodeType.Element, null);

// Attach the XSD schema to the reader

reader.Schemas.Add(

"urn:CardInfo-schema",@"http://localhost/Card/Cardschema.xsd");

// Set the validation type for XSD schema.

// XDR schemas and DTDs are also supported

reader.ValidationType = ValidationType.Schema;

// Create and register an event handler to handle validation errors

reader.ValidationEventHandler += new ValidationEventHandler(

ValidationErrors );

// Process the input data

while (reader.Read())

{

. . .

}

// Validation completed successfully

}

catch

{ . . .}

}

// Validation error event handler

private static void ValidationErrors(object sender, ValidationEventArgs args)

{

// Error details available from args.Message

. . .

}

Consider Your Approach to Caching

You can greatly enhance Web services performance by caching data. With ASP.NET Web services, you can use many of the same caching features that are available to ASP.NET applications. These include ASP.NET output caching, HTTP response caching, and ASP.NET application caching.

In common with any caching solution, your caching design for a Web service must consider issues such as how frequently the cached data needs to be updated, whether or not the data is user-specific or application-wide, what mechanism to use to indicate that the cache needs updating, and so on. For more information about caching with Web services, see the "Caching" section later in this chapter.Consider Approaches for Bulk Data Transfer and Attachments

You can use the following approaches to optimize the performance of bulk data transfer: Chunking. With this approach, you use fixed-size byte arrays to send the data one chunk at a time. Offloading the transfer. With this approach, you return a URL from your Web service which points to the file to be downloaded. Compression. You can use a SOAP extension to compress the SOAP messages before transmitting them. This helps when you are constrained primarily by network bandwidth or latency.

To handle attachments, your options include: WS-Attachments Base 64 encoding SOAP Message Transmission Optimization Mechanism (MTOM)

More Information

For more information about these approaches, see the "Bulk Data Transfer" and "Attachments" sections later in this chapter.Avoid Calling Local Web Services

Web services located on the same computer as a client ASP.NET application share the same thread pool with the ASP.NET application. Therefore, the client application and the Web service share the same threads and other related resources, such as CPU for request processing. Calling a local Web service also means that your request travels through the entire processing pipeline and incurs overhead, including serialization, thread switching, request queuing, and de-serialization.

In addition, the maxconnection attribute of Machine.config has no affect on the connection limit for making calls to local Web services. Therefore, local Web services always tend to give preference to the requests that come from the local computer over requests that come from other machines. This degrades the throughput of the Web service for remote clients.

There are two main approaches to solving this problem: Factor out the Web services business logic into a separate assembly, and call the assembly from the client application as well as the Web service. Load the Web services assembly directly and call its methods. This approach is not as intuitive as the first.

More Information For IIS 6.0 – specific deployment mitigation, refer to "ASP.NET Tuning" in Chapter 17, "Tuning .NET Application Performance" For more information about how to structure your application properly, refer to "Application Architecture for .NET: Designing Applications and Services" on MSDN at http://msdn.microsoft.com/library/en-us/dnbda/html/distapp.asp. Implementation Considerations

When you move from application design to development, consider the implementation details of your Web services. Important Web services performance measures include response times, speed of throughput, and resource management: You can reduce request times and reduce server load by caching frequently used data and SOAP responses. You can improve throughput by making effective use of threads and connections, by optimizing Web method serialization, and by designing more efficient service interfaces. Tune thread pooling to reduce contention and increase CPU utilization. To improve connection performance, configure the maximum limit of concurrent outbound calls to a level appropriate for the CPU performance. You can improve resource management by ensuring that shared resources, such as connections, are opened as late as possible and closed as soon as possible, and also by not maintaining server state between calls.

By following best practice implementation guidelines, you can increase the performance of Web services. The following sections highlight performance considerations for Web services features and scenarios.Connections

When you call Web services, transmission control protocol (TCP) connections are pooled by default. If a connection is available from the pool, that connection is used. If no connection is available, a new connection is created, up to a configurable limit. There is always a default unnamed connection pool. However, you can use connection groups to isolate specific connection pools used by a given set of HTTP requests. To use a separate pool, specify a ConnectionGroupName when you make requests. If you don't specify a connection group, the default connection pool is used. To use connections efficiently, you need to set an appropriate number of connections, determine whether connections will be reused, and factor in security implications.

The following recommendations improve connection performance: Configure the maxconnection attribute. Prioritize and allocate connections across discrete Web services. Use a single identity for outbound calls. Consider UnsafeAuthenticatedConnectionSharing with Windows Integrated Authentication. Use PreAuthenticate with Basic authentication. Configure The maxconnection Attribute

The maxconnection attribute in Machine.config limits the number of concurrent outbound calls.Note This setting does not apply to local requests (requests that originate from ASP.NET applications on the same server as the Web service). The setting applies to outbound connections from the current computer, for example, to ASP.NET applications and Web services calling other remote Web services.

The default setting for maxconnection is two per connection group. For desktop applications that call Web services, two connections may be sufficient. For ASP.NET applications that call Web services, two is generally not enough. Change the maxconnection attribute from the default of 2 to (12 times the number of CPUs) as a starting point.

Note that 12 connections per CPU is an arbitrary number, but empirical evidence has shown that it is optimal for a variety of scenarios when you also limit ASP.NET to 12 concurrent requests (see the "Threading" section later in this chapter). However, you should validate the appropriate number of connections for your situation.

Increasing the maxconnection attribute results in increased thread pool and processor utilization. With the increase in the maxconnection value, a higher number of I/O threads will be available to make outbound concurrent calls to the Web service. As a result, you process incoming HTTP requests more quickly.Before Making the Change

You should consider increasing the connections only if you have available CPU. You should always check processor utilization before increasing the attribute because increasing the attribute results in more work for the processor, as described above. For this reason, increasing this attribute makes sense only when your processor utilization is below the threshold limits (usually less than 75 percent utilization).

For more information, see the "Threading" section later in this chapter.Evaluating the Change

Changing the attribute may involve multiple iterations for tuning and involves various trade-offs with respect to thread pool utilization. Therefore, the changes in the maxconnection attribute may require changes to other thread pool – related configuration attributes, such as maxWorkerThreads and maxIoThreads.

When you load test your application after making the configuration changes, you should monitor CPU utilization and watch the ASP.NET Applications\Requests/Sec and ASP.NET Applications\Requests in Application Queue performance counters. Requests in Application Queue should decrease while Requests/Sec and CPU utilization should increase.Prioritize and Allocate Connections Across Discrete Web Services

Enumerate and prioritize the Web services you call. Allocate more connections to your critical Web services. You specify each Web service by using the address attribute as follows.

For example, if your application typically makes more requests to WebServiceA than WebServiceB, you can dedicate more connections, as shown in the example above.Use a Single Identity for Outbound Calls

Use a single trusted identity for making Web services calls where you can. This helps limit the number of separate connection pools. Although you may need to create separate pools of connections for different discrete Web services, avoid creating pools per user. If you need to create pools per user, then specify a ConnectionGroupName when you call the Web service, but be aware that this hurts performance and leads to a large number of pools.

The connection pool your call uses is not determined by the identity of the caller. The ConnectionGroupName determines which connection pool is used. If separate identities use the same ConnectionGroupName, they use the same pool of connections, as shown in the following code snippet.

// Create a secure group name.

….

serv = new WebService1();

// Set the PreAuthenticate property to send the authenticate request in

first go

serv.PreAuthenticate=true;

// Set the client side credentials

ICredentials conCredentials =

new NetworkCredential("UserId","Password","NPSTest" );

serv.Credentials = conCredentials;

// Do not allow the server to auto redirect as this may compromise security

serv.AllowAutoRedirect=false;

// Use the same connectionGroup Name for all the calls

serv.ConnectionGroupName = "SameForAllUsers";

You may need to create separate pools of connections for different discrete Web services or if you flow the identity of the original caller.

If ASP.NET calls Web services that allow anonymous callers, connections from the default connection pool are used. This is the default behavior unless you specify a ConnectionGroupName, as shown in above example.Consider UnsafeAuthenticatedConnectionSharing with Windows Integrated Authentication

If your ASP.NET application calls a Web service that uses Microsoft Windows® integrated authentication, consider enabling UnsafeAuthenticatedConnectionSharing. By default, when you connect using Windows Integrated authentication, connections are opened and closed per request. This means that connections are not pooled by default. By enabling UnsafeAuthenticatedConnectionSharing, you keep connections open so they can be reused.

Consider the following guidelines: If you are in a trusted environment and you connect using a single trusted identity, consider improving performance by setting UnsafeAuthenticatedConnectionSharing to true.

//set the UnsafeAuthenticatedConnectionSharing to true

myWebService.UnsafeAuthenticatedConnectionSharing = true;

NetworkCredential myCred = new

NetworkCredential("UserA","PasswordA","DomainA");

CredentialCache myCache = new CredentialCache();

myCache.Add(new Uri("http://Someserver/WS/service1.asmx"), "NTLM",

myCred);

myWebService.Credentials = myCache;

myWebService.ConnectionGroupName = "SameName";

string result = myWebService.HelloWorld();

//as the ConnectionGroupName property is same for different client requests //only the first connection from above gets authenticated

// the request below reuses the connection from above

myCred = new NetworkCredential("UserB","PasswordB","DomainB");

CredentialCache myCache = new CredentialCache();

myCache.Add(new Uri("http://Someserver/WS/service1.asmx"), "NTLM",

myCred);

myWebService.Credentials = myCache;

myWebService.ConnectionGroupName = "SameName";

result = myWebService.HelloWorld();

If you call a Web service by using the ASP.NET application original caller's identity, then you should avoid enabling UnsafeAuthenticatedConnectionSharing because connections would be shared across calls. Alternatively, you can enable UnsafeAuthenticatedConnectionSharing, and then assign users to individual connection groups by using a ConnectionGroupName. Either option is inefficient and results in a high number of pools. If you need to connect to separate discrete Web services, assign calls to separate pools using ConnectionGroupName. If you need to connect to a server that uses AuthPersistence (it authenticates a whole connection and not a single request), then you should set UnsafeAuthenticatedConnectionSharing to true, and specify some random connection group name. You will need to determine which application requests will go to that connection group because the server will no longer challenge for authentication on that connection.

More Information For more information about AuthPersistence, see Microsoft Knowledge Base article 318863, "HOW TO: Modify the AuthPersistence Metabase Entry Controls When Clients Are Authenticated," at http://support.microsoft.com/default.aspx?scid=kb;en-us;318863. For more information on UnsafeAuthenticatedConnectionSharing, see the .NET Framework documentation. Use PreAuthenticate with Basic Authentication

If you use Basic authentication, the proxy's PreAuthenticate property can be set to true or false. Set it to true to supply specific authentication credentials to cause a WWWauthenticate HTTP header to be passed with the Web request. This prevents the Web server from denying access to the request and performing authentication on the subsequent retry request.Note Pre-authentication only applies after the Web service successfully authenticates the first time. Pre-authentication has no impact on the first Web request.

private void ConfigureProxy( WebClientProtocol proxy,

string domain, string username,

string password )

{

// To improve performance, force pre-authentication

proxy.PreAuthenticate = true;

// Set the credentials

CredentialCache cache = new CredentialCache();

cache.Add( new Uri(proxy.Url),

"Negotiate",

new NetworkCredential(username, password, domain) );

proxy.Credentials = cache;

proxy.ConnectionGroupName = username;

}Threading

Web Services use ASP.NET thread pooling to process requests. To ensure that your Web Services use the thread pool most effectively, consider the following guidelines: Tune the thread pool using the Formula for Reducing Contention. Consider minIoThreads and minWorkerThreads for intermittent burst load. Tune the Thread Pool by Using the Formula for Reducing Contention

The Formula for Reducing Contention can give you a good starting point for tuning the ASP.NET thread pool. Consider using the Microsoft product group recommended settings (shown in Table 10.2) if you have available CPU, your application performs I/O bound operations (such as calling a Web method or accessing the file system), and you have queued requests as indicated by the ASP.NET Applications/Requests in Application Queue performance counter.

Table 10.2: Recommended Threading Settings for Reducing Contention

Configuration settingDefault (.NET 1.1)Recommended valuemaxconnection212 * #CPUsmaxIoThreads20100maxWorkerThreads20100minFreeThreads888 * #CPUsminLocalRequestFreeThreads476 * #CPUs

To address this issue, you need to configure the following items in Machine.config. The changes described in the following list should be applied across the settings and not in isolation. For a detailed description of each of these settings, see "Thread Pool Attributes" in Chapter 17, "Tuning .NET Application Performance." Set maxconnection to 12 * # of CPUs. This setting controls the maximum number of outgoing HTTP connections allowed by the client, which in this case is ASP.NET. The recommendation is to set this to 12 times the number of CPUs. Set maxIoThreads to 100. This setting controls the maximum number of I/0 threads in the common language runtime (CLR) thread pool. This number is then automatically multiplied by the number of available CPUs. The recommendation is to set this to 100. Set maxWorkerThreads to 100. This setting controls the maximum number of worker threads in the CLR thread pool. This number is then automatically multiplied by the number of available CPUs. The recommendation is to set this to 100. Set minFreeThreads to 88 * # of CPUs. The worker process uses this setting to queue up all the incoming requests if the number of available threads in the thread pool falls below the value for this setting. This setting effectively limits the number of concurrently executing requests to maxWorkerThreads – minFreeThreads. The recommendation is to set this to 88 times the number of CPUs. This limits the number of concurrent requests to 12 (assuming maxWorkerThreads is 100). Set minLocalRequestFreeThreads to 76 * # of CPUs. This worker process uses this setting to queue up requests from localhost (where a Web application calls a Web service on the same server) if the number of available threads in the thread pool falls below this number. This setting is similar to minFreeThreads, but it only applies to requests that use localhost. The recommendation is to set this to 76 times the number of CPUs. Note The above recommendations are starting points rather than strict rules. You should perform appropriate testing to determine the correct settings for your environment.

If the formula has worked, you should see improved throughput and less idle CPU time: CPU utilization should go up. Throughput should increase (ASP.NET Applications\Requests/Sec should go up), Requests in the application queue (ASP.NET Applications\Requests in Application Queue) should go down.

If this does not improve your performance, you may have a CPU-bound situation. If this is the case, by adding more threads you increase thread context switching. For more information, see "ASP.NET Tuning" in Chapter 17, "Tuning .NET Application Performance."

More Information

For more information, see Microsoft Knowledge Base article 821268, "PRB: Contention, Poor Performance, and Deadlocks When You Make Web Service Requests from ASP.NET Applications," at http://support.microsoft.com/default.aspx?scid=kb;en-us;821268.Consider minIoThreads and minWorkerThreads for Intermittent Burst Load

If you have burst load scenarios that are intermittent and short (0 to 10 minutes), then the thread pool may not have enough time to reach the optimal level of threads. The use of minIoThreads and minWorkerThreads allows you to configure a minimum number of worker and I/O threads for load conditions.

At the time of this writing, you need a supported fix to configure the settings. For more information, see the following Microsoft Knowledge Base articles: 810259, "FIX: SetMinThreads and GetMinThreads API Added to Common Language Runtime ThreadPool Class," at http://support.microsoft.com/default.aspx?scid=kb;en-us;810259. 827419, "PRB: Sudden Requirement for a Larger Number of Threads from the ThreadPool Class May Result in Slow Computer Response Time," at http://support.microsoft.com/default.aspx?scid=kb;en-us;827419. More Information

For more information about threading and Web services, see: "ASP.NET Tuning" in Chapter 17, "Tuning .NET Application Performance" Microsoft Knowledge Base article 821268, "PRB: Contention, Poor Performance, and Deadlocks When You Make Web Service Requests from ASP.NET Applications," at http://support.microsoft.com/default.aspx?scid=kb;en-us;821268. One-Way (Fire-and-Forget) Communication

Consider using the OneWay attribute if you do not require a response. Using the OneWay property of SoapDocumentMethod and SoapRpcMethod in the System.Web.Services.Protocols namespace frees the client immediately instead of forcing it to wait for a response.

For a method to support fire-and-forget invocation, you must decorate it with the OneWay attribute, as shown in the following code snippet.

[SoapDocumentMethod(OneWay=true)]

[WebMethod(Description="Returns control immediately")]

public void SomeMethod()

{…}

This is useful if the client needs to send a message, but does not expect anything as return values or output parameters. Methods marked as OneWay cannot have output parameters or return values.Asynchronous Web Methods

You can call a Web service asynchronously regardless of whether or not the Web service has been implemented synchronously or asynchronously. Similarly, you can implement a synchronous or asynchronous Web service, but allow either style of caller. Client-side and server-side asynchronous processing is generally performed to free up the current worker thread to perform additional work in parallel.

The asynchronous implementation of a Web method frees up the worker thread to handle other parallel tasks that can be performed by the Web method. This ensures optimal utilization of the thread pool, resulting in throughput gains.

For normal synchronous operations, the Web services asmx handler uses reflection on the assembly to find out which methods have the WebMethod attribute associated with them. The handler simply calls the appropriate method based on the value of the SOAP-Action HTTP header.

However, the Web services asmx handler treats asynchronous Web methods differently. It looks for methods that adhere to the following rules: Methods adhere to the asynchronous design pattern: There are BeginXXX and EndXXX methods for the actual XXX method that you need to expose. The BeginXXX method returns an IAsyncResult interface, takes whatever arguments the Web method needs, and also takes two additional parameters of type AsyncCallback and System.Object, respectively. The EndXXX method takes an IAsyncResult as a parameter and returns the return type of your Web method. Both methods are decorated with the WebMethod attribute.

The Web services asmx handler then exposes the method, as shown in the following code snippet.

[WebMethod]

IAsyncResult BeginMyProc(…)

[WebMethod]

EndMyProc(…)

//the WSDL will show the method as

MyProc(…)

The Web services asmx handler processes incoming requests for asynchronous methods as follows: Call the BeginXXX method. Pass the reference to an internal callback function as a parameter to the BeginXXX method, along with the other in parameters. This frees up the worker thread processing the request, allowing it to handle other incoming requests. The asmx handler holds on to the HttpContext of the request until processing of the request is complete and a response has been sent to the client. Once the callback is called, call the EndXXX function to complete the processing of the method call and return the response as a SOAP response. Release the HttpContext for the request.

Consider the following guidelines for asynchronous Web methods: Use asynchronous Web methods for I/O operations. Do not use asynchronous Web methods when you depend on worker threads. Use Asynchronous Web Methods for I/O Operations

Consider using asynchronous Web methods if you perform I/O-bound operations such as: Accessing streams File I/O operations Calling another Web service

The .NET Framework provides the necessary infrastructure to handle these operations asynchronously, and you can return an IAsyncResult interface from these types of operations. The .NET Framework exposes asynchronous methods for I/O-bound operations using the asynchronous design pattern. The libraries that use this pattern have BeginXXX and EndXXX methods.

The following code snippet shows the implementation of an asynchronous Web method calling another Web service.

// The client W/S

public class AsynchWSToWS

{

WebServ asyncWs = null;

public AsynchWSToWS(){

asyncWs = new WebServ();

}

[System.Web.Services.WebMethod]

public IAsyncResult BeginSlowProcedure(int milliseconds,AsyncCallback cb,

object s){

// make call to other web service and return the IAsyncResult

return asyncWs.BeginLengthyCall(milliseconds,cb,s);

}

[System.Web.Services.WebMethod ]

public string EndSlowProcedure(IAsyncResult call) {

return asyncWs.EndLengthyCall(call);

}

}

// The server W/S

public class WebServ

{

[WebMethod]

public string LengthyCall(int milliseconds){

Thread.Sleep(milliseconds);

return "Hello World";

}

}

Asynchronous implementation helps when you want to free up the worker thread instead of waiting on the results to return from a potentially long-running task. For this reason, you should avoid asynchronous implementation whenever your work is CPU bound because you do not have idle CPU to service more threads. In this case, an asynchronous implementation results in increased utilization and thread switching on an already busy processor. This is likely to hurt performance and overall throughput of the processor.Note You should not use asynchronous Web methods when accessing a database. ADO.NET does not provide asynchronous implementation for handling database calls. Wrapping the operation in a delegate is not an option either because you still block a worker thread.You should only consider using an asynchronous Web method if you are wrapping an asynchronous operation that hands back an IAsyncResult reference.Do Not Use Asynchronous Web Methods When You Depend on Worker Threads

You should not implement Web methods when your asynchronous implementation depends upon callbacks or delegates because they use worker threads internally. Although the delegate frees the worker thread processing the request, it uses another worker thread from the process thread pool to execute the method. This is a thread that can be used for processing other incoming requests to the Web service. The result is that you consume a worker thread for the delegate-based operation and you increase context switching.

Alternatively, you can use synchronous Web methods and decrease the minFreeThreads setting so that the worker threads can take requests and execute them directly.

In this scenario, you could block the original worker thread by implementing the Web method to run synchronously. An example of the delegate-based implementation is shown in the following code snippet.

// delegate

public delegate string LengthyProcedureAsyncStub(int milliseconds);

//actual method which is exposed as a web service

[WebMethod]

public string LengthyCall(int milliseconds) {

System.Threading.Thread.Sleep(milliseconds);

return "Hello World";

}

[WebMethod]

public IAsyncResult BeginLengthyCall(int milliseconds,AsyncCallback cb,

object s) {

LengthyProcedureAsyncStub stub = new LengthyProcedureAsyncStub(LengthyCall);

//using delegate for asynchronous implementation

return stub.BeginInvoke(milliseconds, cb, null); }

[System.Web.Services.WebMethod]

public string EndLengthyCall(IAsyncResult call) {

return ms.asyncStub.EndInvoke(call);

}Asynchronous Invocation

Web services clients can call a Web service either synchronously or asynchronously, independently of the way the Web service is implemented.

For server applications, using asynchronous calls to a remote Web service is a good approach if the Web service client can either free the worker thread to handle other incoming requests or perform additional parallel work before blocking for the results. Generally, Windows Forms client applications call Web services asynchronously to avoid blocking the user interface.Note The HTTP protocol allows at most two simultaneous outbound calls from one client to one Web service.

The WSDL-generated proxy contains support for both types of invocation. The proxy supports the asynchronous call by exposing BeginXXX and EndXXX methods.

The following guidelines help you decide whether or not calling a Web service asynchronously is appropriate: Consider calling Web services asynchronously when you have additional parallel work. Use asynchronous invocation to call multiple unrelated Web services. Call Web services asynchronously for UI responsiveness. Consider Calling Web Services Asynchronously When You Have Additional Parallel Work

Asynchronous invocation is the most useful when the client has additional work that it can perform while the Web method executes. Asynchronous calls to Web services result in performance and throughput gains because you free the executing worker thread to do parallel work before it is blocked by t

责任编辑:admin
相关文章